23 KiB
23 KiB
系統整合與部署規格
📋 文件資訊
- 文件名稱: 系統整合與部署規格
- 版本: v2.0
- 建立日期: 2025-01-25
- 最後更新: 2025-01-25
- 負責團隊: DramaLing DevOps團隊
- 適用系統: AI句子分析功能全棧系統
🏗️ 系統架構圖
整體架構
┌─────────────────┐ HTTP/JSON ┌──────────────────┐ Gemini API ┌─────────────────┐
│ │ Request │ │ Request │ │
│ Frontend │ ──────────────► │ Backend API │ ──────────────► │ Google Gemini │
│ (Next.js) │ │ (.NET Core) │ │ AI Service │
│ Port 3000 │ ◄────────────── │ Port 5008 │ ◄────────────── │ │
│ │ Response │ │ Response │ │
└─────────────────┘ └──────────────────┘ └─────────────────┘
│ │
│ │
▼ ▼
┌─────────────────┐ ┌──────────────────┐
│ Local Storage │ │ SQLite Database │
│ - user_level │ │ - Cache Data │
│ - auth_token │ │ - Usage Stats │
└─────────────────┘ └──────────────────┘
數據流向
sequenceDiagram
participant U as 用戶
participant F as 前端(3000)
participant B as 後端(5008)
participant G as Gemini API
participant D as 資料庫
U->>F: 1. 輸入英文句子
U->>F: 2. 點擊「分析句子」
F->>F: 3. 驗證輸入(≤300字符)
F->>F: 4. 讀取userLevel (localStorage)
F->>B: 5. POST /api/ai/analyze-sentence
B->>B: 6. 輸入驗證和處理
B->>G: 7. 調用Gemini API
G->>B: 8. 返回AI分析結果
B->>B: 9. 解析和格式化數據
B->>D: 10. 記錄使用統計 (可選)
B->>F: 11. 返回結構化分析結果
F->>F: 12. 計算個人化統計
F->>F: 13. 渲染詞彙標記和統計卡片
F->>U: 14. 顯示完整分析結果
🔄 前後端整合規格
API整合詳細設計
前端請求實現
// 位置: frontend/app/generate/page.tsx
const handleAnalyzeSentence = async () => {
try {
const response = await fetch('http://localhost:5008/api/ai/analyze-sentence', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${getAuthToken()}` // 可選
},
body: JSON.stringify({
inputText: textInput,
analysisMode: 'full',
options: {
includeGrammarCheck: true,
includeVocabularyAnalysis: true,
includeTranslation: true,
includeIdiomDetection: true,
includeExamples: true
}
})
});
if (!response.ok) {
throw new Error(`API請求失敗: ${response.status}`);
}
const result = await response.json();
handleAnalysisResult(result.data);
} catch (error) {
handleAnalysisError(error);
}
};
數據處理邏輯
// 前端個人化統計計算
const calculateVocabularyStats = (vocabularyAnalysis, idioms, userLevel) => {
const userIndex = CEFR_LEVELS.indexOf(userLevel);
let simple = 0, moderate = 0, difficult = 0;
Object.values(vocabularyAnalysis).forEach(word => {
const wordIndex = CEFR_LEVELS.indexOf(word.difficultyLevel);
if (userIndex > wordIndex) simple++;
else if (userIndex === wordIndex) moderate++;
else difficult++;
});
return {
simpleCount: simple,
moderateCount: moderate,
difficultCount: difficult,
idiomCount: idioms.length
};
};
錯誤處理整合
前端錯誤處理
const handleAnalysisError = (error) => {
console.error('Analysis error:', error);
// 顯示用戶友善的錯誤訊息
if (error.message.includes('timeout')) {
setErrorMessage('分析服務繁忙,請稍後再試');
} else if (error.message.includes('network')) {
setErrorMessage('網路連接問題,請檢查網路狀態');
} else {
setErrorMessage('分析過程中發生錯誤,請稍後再試');
}
// 提供降級體驗
setFallbackAnalysisView(textInput);
};
後端錯誤映射
// 位置: backend/Controllers/AIController.cs
private ApiErrorResponse CreateErrorResponse(string code, string message, object? details, string requestId)
{
var userFriendlyMessage = code switch
{
"INVALID_INPUT" => "輸入格式不正確,請檢查文本內容",
"AI_SERVICE_ERROR" => "AI分析服務暫時不可用,請稍後重試",
"RATE_LIMIT_EXCEEDED" => "請求過於頻繁,請稍候再試",
"TIMEOUT" => "分析超時,請嘗試較短的句子",
_ => "系統暫時不可用,請稍後重試"
};
return new ApiErrorResponse
{
Success = false,
Error = new ApiError
{
Code = code,
Message = userFriendlyMessage,
Details = details,
Suggestions = GetSuggestionsForError(code)
},
RequestId = requestId,
Timestamp = DateTime.UtcNow
};
}
🔧 開發環境配置
環境準備
必要軟體
開發工具:
- Node.js: >= 18.0.0
- .NET SDK: >= 8.0.0
- Git: >= 2.40.0
- VSCode: 最新版本
瀏覽器支援:
- Chrome: >= 90 (開發調試用)
- Safari: >= 14 (測試用)
- Firefox: >= 88 (測試用)
可選工具:
- Docker: >= 20.0 (容器化部署)
- Redis: >= 6.0 (本地快取測試)
- Postman: API測試
環境變數配置
# 後端環境變數
export GEMINI_API_KEY="your-gemini-api-key"
export ASPNETCORE_ENVIRONMENT="Development"
export DRAMALING_DB_CONNECTION="Data Source=dramaling_test.db"
# 前端環境變數 (可選)
export NEXT_PUBLIC_API_URL="http://localhost:5008"
export NEXT_PUBLIC_ENVIRONMENT="development"
啟動流程
開發環境啟動腳本
#!/bin/bash
# 位置: start-development.sh
echo "🚀 啟動 DramaLing 開發環境..."
# 1. 檢查必要軟體
check_prerequisites() {
command -v node >/dev/null 2>&1 || { echo "需要安裝 Node.js"; exit 1; }
command -v dotnet >/dev/null 2>&1 || { echo "需要安裝 .NET SDK"; exit 1; }
}
# 2. 啟動後端 API (Port 5008)
start_backend() {
echo "🔧 啟動後端 API..."
cd backend/DramaLing.Api
dotnet restore
dotnet run &
BACKEND_PID=$!
echo "後端 PID: $BACKEND_PID"
}
# 3. 啟動前端 (Port 3000)
start_frontend() {
echo "🎨 啟動前端..."
cd ../../frontend
npm install
npm run dev &
FRONTEND_PID=$!
echo "前端 PID: $FRONTEND_PID"
}
# 4. 健康檢查
health_check() {
echo "🏥 執行健康檢查..."
sleep 10
# 檢查後端
if curl -f http://localhost:5008/health >/dev/null 2>&1; then
echo "✅ 後端服務正常"
else
echo "❌ 後端服務異常"
fi
# 檢查前端
if curl -f http://localhost:3000 >/dev/null 2>&1; then
echo "✅ 前端服務正常"
else
echo "❌ 前端服務異常"
fi
}
# 執行啟動流程
check_prerequisites
start_backend
start_frontend
health_check
echo "🎉 開發環境啟動完成!"
echo "前端: http://localhost:3000"
echo "後端API: http://localhost:5008"
echo "API文檔: http://localhost:5008/swagger"
🧪 測試整合策略
整合測試架構
API整合測試
[TestFixture]
public class AIAnalysisIntegrationTests : IClassFixture<WebApplicationFactory<Program>>
{
private readonly WebApplicationFactory<Program> _factory;
private readonly HttpClient _client;
[SetUp]
public void Setup()
{
_client = _factory.CreateClient();
}
[Test]
public async Task AnalyzeSentence_EndToEnd_ReturnsValidResponse()
{
// Arrange
var request = new
{
inputText = "She just join the team, so let's cut her some slack.",
analysisMode = "full"
};
// Act
var response = await _client.PostAsJsonAsync("/api/ai/analyze-sentence", request);
// Assert
response.EnsureSuccessStatusCode();
var result = await response.Content.ReadFromJsonAsync<AnalysisResponse>();
Assert.That(result.Success, Is.True);
Assert.That(result.Data.VocabularyAnalysis.Count, Is.GreaterThan(0));
Assert.That(result.Data.SentenceMeaning, Is.Not.Empty);
Assert.That(result.Data.Idioms.Count, Is.GreaterThan(0));
}
}
前端E2E測試
// 使用 Playwright 或 Cypress
describe('AI Analysis E2E Flow', () => {
test('complete analysis workflow', async ({ page }) => {
// 1. 導航到分析頁面
await page.goto('http://localhost:3000/generate');
// 2. 輸入測試句子
await page.fill('[data-testid="text-input"]',
'She just join the team, so let\'s cut her some slack.');
// 3. 點擊分析按鈕
await page.click('[data-testid="analyze-button"]');
// 4. 等待分析完成
await page.waitForSelector('[data-testid="analysis-result"]', { timeout: 10000 });
// 5. 驗證結果
await expect(page.locator('[data-testid="grammar-correction"]')).toBeVisible();
await expect(page.locator('[data-testid="vocabulary-analysis"]')).toBeVisible();
await expect(page.locator('[data-testid="idioms-section"]')).toBeVisible();
await expect(page.locator('[data-testid="statistics-cards"]')).toBeVisible();
// 6. 測試詞彙點擊
await page.click('[data-testid="word-she"]');
await expect(page.locator('[data-testid="vocab-popup"]')).toBeVisible();
});
});
性能測試整合
負載測試配置
# 使用 k6 或 JMeter
負載測試場景:
- 正常負載: 100 用戶,持續 10 分鐘
- 壓力測試: 500 用戶,持續 5 分鐘
- 尖峰測試: 1000 用戶,持續 2 分鐘
性能指標:
- 回應時間P95: < 5秒
- 錯誤率: < 1%
- 吞吐量: > 100 RPS
- 資源使用: CPU < 80%, Memory < 70%
🚀 部署架構
環境配置
開發環境 (Development)
基礎設施:
- 本地開發機器
- SQLite 資料庫
- In-Memory 快取
- Gemini API (測試金鑰)
配置特點:
- 詳細日誌輸出
- 熱重載支援
- Swagger API 文檔
- CORS 寬鬆政策
測試環境 (Staging)
基礎設施:
- 雲端虛擬機 或 Docker 容器
- PostgreSQL 資料庫
- Redis 快取
- Gemini API (測試金鑰)
配置特點:
- 生產環境模擬
- 效能監控啟用
- 自動化測試整合
- 安全掃描
生產環境 (Production)
基礎設施:
- Kubernetes 叢集 或 雲端服務
- PostgreSQL 高可用性叢集
- Redis 叢集
- Gemini API (生產金鑰)
- CDN 和負載均衡
配置特點:
- 高可用性 (99.9%+)
- 自動擴容
- 全面監控和告警
- 災難恢復機制
容器化部署
Docker Compose 配置
# docker-compose.yml
version: '3.8'
services:
# 後端 API 服務
backend:
build:
context: ./backend/DramaLing.Api
dockerfile: Dockerfile
ports:
- "5008:5008"
environment:
- ASPNETCORE_ENVIRONMENT=Production
- GEMINI_API_KEY=${GEMINI_API_KEY}
- ConnectionStrings__DefaultConnection=${DB_CONNECTION}
depends_on:
- database
- redis
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:5008/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 40s
# 前端服務
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
ports:
- "3000:3000"
environment:
- NEXT_PUBLIC_API_URL=http://backend:5008
depends_on:
- backend
# 資料庫服務
database:
image: postgres:15-alpine
environment:
- POSTGRES_DB=dramaling
- POSTGRES_USER=${DB_USER}
- POSTGRES_PASSWORD=${DB_PASSWORD}
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"
# 快取服務
redis:
image: redis:7-alpine
ports:
- "6379:6379"
volumes:
- redis_data:/data
volumes:
postgres_data:
redis_data:
Kubernetes 部署配置
# k8s-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: dramaling-backend
spec:
replicas: 3
selector:
matchLabels:
app: dramaling-backend
template:
metadata:
labels:
app: dramaling-backend
spec:
containers:
- name: backend
image: dramaling/backend:latest
ports:
- containerPort: 5008
env:
- name: GEMINI_API_KEY
valueFrom:
secretKeyRef:
name: ai-secrets
key: gemini-api-key
- name: ConnectionStrings__DefaultConnection
valueFrom:
configMapKeyRef:
name: app-config
key: db-connection
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /health
port: 5008
initialDelaySeconds: 30
periodSeconds: 30
readinessProbe:
httpGet:
path: /health
port: 5008
initialDelaySeconds: 5
periodSeconds: 5
📊 監控與可觀測性
日誌整合
結構化日誌配置
// appsettings.Production.json
{
"Serilog": {
"Using": ["Serilog.Sinks.Console", "Serilog.Sinks.ApplicationInsights"],
"MinimumLevel": {
"Default": "Information",
"Override": {
"Microsoft": "Warning",
"System": "Warning",
"DramaLing": "Information"
}
},
"WriteTo": [
{
"Name": "Console",
"Args": {
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss} [{Level:u3}] {Message:lj} {Properties:j}{NewLine}{Exception}"
}
},
{
"Name": "ApplicationInsights",
"Args": {
"instrumentationKey": "{ApplicationInsights:InstrumentationKey}"
}
}
],
"Enrich": ["FromLogContext", "WithMachineName", "WithThreadId"]
}
}
前端錯誤追蹤
// 錯誤邊界和監控
class ErrorBoundary extends React.Component {
componentDidCatch(error, errorInfo) {
// 發送錯誤到監控服務
console.error('React Error Boundary:', error, errorInfo);
// 可選:整合 Sentry 或其他錯誤追蹤服務
if (typeof window !== 'undefined' && window.gtag) {
window.gtag('event', 'exception', {
description: error.toString(),
fatal: false
});
}
}
}
健康檢查系統
深度健康檢查
public class SystemHealthCheck : IHealthCheck
{
private readonly IGeminiService _geminiService;
private readonly DramaLingDbContext _dbContext;
public async Task<HealthCheckResult> CheckHealthAsync(
HealthCheckContext context, CancellationToken cancellationToken = default)
{
var checks = new Dictionary<string, HealthStatus>();
// 檢查資料庫連接
try
{
await _dbContext.Database.CanConnectAsync(cancellationToken);
checks["database"] = HealthStatus.Healthy;
}
catch (Exception ex)
{
checks["database"] = HealthStatus.Unhealthy;
}
// 檢查 AI 服務
try
{
var isHealthy = await _geminiService.HealthCheckAsync();
checks["gemini_api"] = isHealthy ? HealthStatus.Healthy : HealthStatus.Degraded;
}
catch (Exception ex)
{
checks["gemini_api"] = HealthStatus.Unhealthy;
}
// 檢查記憶體使用
var memoryUsage = GC.GetTotalMemory(false);
checks["memory"] = memoryUsage < 500_000_000 ? HealthStatus.Healthy : HealthStatus.Degraded;
var overallStatus = checks.Values.All(s => s == HealthStatus.Healthy)
? HealthStatus.Healthy
: checks.Values.Any(s => s == HealthStatus.Unhealthy)
? HealthStatus.Unhealthy
: HealthStatus.Degraded;
return new HealthCheckResult(overallStatus,
description: $"System health: {string.Join(", ", checks.Select(c => $"{c.Key}:{c.Value}"))}",
data: checks.ToDictionary(c => c.Key, c => (object)c.Value.ToString()));
}
}
🔒 安全整合
HTTPS 配置
開發環境:
- HTTP: localhost:3000, localhost:5008
- 自簽證書: dotnet dev-certs https --trust
生產環境:
- HTTPS: 強制重定向
- TLS 1.3: 最低版本要求
- HSTS: 嚴格傳輸安全
- 證書: Let's Encrypt 或企業CA
CORS 政策
// 開發環境 CORS 配置
services.AddCors(options =>
{
options.AddPolicy("Development", policy =>
{
policy.WithOrigins("http://localhost:3000", "http://localhost:3001")
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
options.AddPolicy("Production", policy =>
{
policy.WithOrigins("https://dramaling.com", "https://app.dramaling.com")
.AllowAnyHeader()
.AllowAnyMethod()
.AllowCredentials();
});
});
📈 監控整合
應用程式監控
關鍵指標儀表板
業務指標:
- 每日分析次數
- 用戶活躍度
- 功能使用分佈
- AI分析成功率
技術指標:
- API回應時間分佈
- 資料庫查詢性能
- 記憶體和CPU使用
- 錯誤率和異常統計
用戶體驗指標:
- 頁面載入時間
- 首次內容繪製 (FCP)
- 最大內容繪製 (LCP)
- 累積佈局偏移 (CLS)
告警配置
嚴重告警:
- API 錯誤率 > 5% (5分鐘內)
- 回應時間P95 > 10秒 (5分鐘內)
- 服務不可用 > 2分鐘
- 資料庫連接失敗
警告告警:
- CPU 使用率 > 80% (10分鐘內)
- 記憶體使用率 > 85% (10分鐘內)
- AI API 調用失敗率 > 10%
- 磁碟空間不足 < 10%
🔧 故障排除指南
常見問題和解決方案
連接問題
問題: CORS 錯誤
症狀: "Access to fetch blocked by CORS policy"
解決: 檢查後端 CORS 設定,確認前端域名在允許清單
問題: 連接被拒絕
症狀: "Connection refused" 或 "ECONNREFUSED"
解決: 確認後端服務正在運行,檢查埠號是否正確
問題: 超時錯誤
症狀: "Request timeout" 或響應超過 30 秒
解決: 檢查 AI API 金鑰,網路連接,增加超時設定
資料問題
問題: AI 回應格式錯誤
症狀: "Cannot read property 'vocabularyAnalysis' of undefined"
解決: 檢查 Gemini API 回應格式,更新錯誤處理邏輯
問題: 詞彙分析為空
症狀: 分析結果不包含詞彙資訊
解決: 檢查 AI Prompt 設計,確認輸入文本有效
問題: 統計數字不一致
症狀: 統計卡片數字與實際標記不符
解決: 檢查前端統計計算邏輯,確認分類算法正確
調試工具
開發調試指令
# 檢查服務狀態
curl -I http://localhost:5008/health
curl -I http://localhost:3000
# 測試 API 端點
curl -X POST http://localhost:5008/api/ai/analyze-sentence \
-H "Content-Type: application/json" \
-d '{"inputText":"Test sentence","analysisMode":"full"}'
# 檢查日誌
docker logs dramaling-backend
docker logs dramaling-frontend
# 檢查資源使用
docker stats
top -p $(pgrep dotnet)
生產監控指令
# 健康檢查
kubectl get pods -l app=dramaling
kubectl describe pod dramaling-backend-xxx
# 查看日誌
kubectl logs -f deployment/dramaling-backend
kubectl logs -f deployment/dramaling-frontend
# 性能監控
kubectl top pods
kubectl top nodes
📋 部署檢查清單
部署前檢查
- 所有測試通過 (單元、整合、E2E)
- 安全掃描無嚴重漏洞
- 性能基準測試達標
- 配置檔案正確設定
- 環境變數和金鑰配置完成
- 資料庫遷移腳本準備
- 監控和告警配置完成
- 回滾計劃準備
部署後驗證
- 健康檢查端點回應正常
- API 功能端到端測試通過
- 前端頁面載入和功能正常
- 監控指標顯示正常
- 日誌記錄正確產生
- 告警機制測試正常
- 負載測試驗證性能
- 安全掃描確認無新漏洞
🔄 CI/CD 流程
持續整合流程
觸發條件:
- 主分支推送 (main)
- Pull Request 建立
- 標籤建立 (v*.*.*)
建置步驟:
1. 程式碼檢出
2. 依賴安裝
3. 靜態分析 (ESLint, SonarQube)
4. 單元測試執行
5. 測試覆蓋率檢查
6. 安全掃描
7. 建置 Docker 映像
8. 整合測試執行
部署條件:
- 所有測試通過
- 程式碼覆蓋率 > 80%
- 安全掃描通過
- 人工審核批准 (生產部署)
持續部署流程
測試環境自動部署:
- 主分支每次推送自動部署
- 自動執行煙霧測試
- 通知團隊部署狀態
生產環境部署:
- 手動觸發或定期發布
- 藍綠部署或滾動更新
- 自動回滾機制
- 部署後監控和驗證
文件版本: v2.0 DevOps負責人: DramaLing DevOps團隊 最後更新: 2025-01-25 下次審查: 2025-02-25
關聯文件:
- 《AI句子分析功能產品需求規格》- 產品需求和用戶故事
- 《AI分析API技術實現規格》- API設計和技術實現
- 《AI驅動產品後端技術架構指南》- 架構設計指導原則