基於 FastAPI + Redis + Worker 架構的高併發案號處理系統,解決資料庫連線數限制問題。
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 前端 API │──────▶│ Redis 隊列 │──────▶│ Worker │
│ (多實例) │ │ + 緩存 │ │ (多實例) │
└─────────────┘ └─────────────┘ └─────────────┘
│ │
│ │
▼ ▼
┌──────────────────────────────────────────────────────┐
│ Oracle Database │
│ (連線池,批次寫入) │
└──────────────────────────────────────────────────────┘
▲
│
┌────┴────┐
│ LLM │
│ API │
└─────────┘
-
提交案號請求 (
POST /api/v1/cases)- 檢查案號是否已存在(避免重複處理)
- 將狀態設為「處理中」並緩存到 Redis
- 推送任務到 Redis 隊列
- 記錄基本信息到資料庫
-
查詢處理結果 (
GET /api/v1/cases/{case_id})- 優先從 Redis 緩存查詢
- 若緩存未命中,從資料庫讀取
- 自動更新緩存(已完成的案號)
-
健康檢查 (
GET /api/v1/health)- 檢查 Redis、資料庫連線狀態
- 返回隊列長度等指標
- 從 Redis 隊列批量拉取任務
- 調用 LLM API 處理案號
- 批次寫入結果到資料庫(減少 DB 連線數)
- 自動重試機制(失敗任務可重試 3 次)
- 死信隊列(DLQ)處理無法恢復的任務
- 配置管理 (
config.py) - 統一管理環境變數 - Redis 客戶端 (
redis_client.py) - 隊列與緩存操作 - 資料庫客戶端 (
db_client.py) - 連線池與批次寫入
- API 框架: FastAPI
- 消息隊列: Redis (List)
- 資料庫: Oracle DB (連線池)
- LLM: 支援 OpenAI / Azure OpenAI
- 容器化: Docker + Docker Compose
# 複製環境變數配置文件
cp .env.example .env
# 編輯 .env 文件,填入實際的配置
nano .envpip install -r requirements.txt# 啟動 Redis(如果沒有本地 Redis)
docker run -d -p 6379:6379 redis:7-alpine
# 啟動 API 服務器(終端 1)
python api/main.py
# 啟動 Worker 服務(終端 2)
python worker/main.py
# 可以啟動多個 Worker 實例(終端 3, 4, ...)
python worker/main.py驗證狀態: ✅ 已驗證通過
驗證狀態: ✅ 已驗證通過(詳見 DOCKER_DEPLOYMENT_VALIDATION.md)
簡化版部署(單實例):
# 構建鏡像
docker build -f Dockerfile.api -t case-api:latest .
docker build -f Dockerfile.worker -t case-worker:latest .
# 啟動所有服務
docker-compose -f docker-compose-simple.yml up -d
# 查看日誌
docker-compose -f docker-compose-simple.yml logs -f
# 停止服務
docker-compose -f docker-compose-simple.yml down完整版部署(多實例 + 負載均衡):
# 構建並啟動所有服務(包含 Nginx)
docker-compose up -d
# 查看日誌
docker-compose logs -f
# 擴展 Worker 數量
docker-compose up -d --scale worker=5# 提交案號處理請求
curl -X POST "http://localhost:8000/api/v1/cases" \
-H "Content-Type: application/json" \
-d '{
"case_id": "CASE-2026-001",
"request_data": {
"query": "請幫我分析這個案件的風險等級",
"metadata": {"priority": "high"}
}
}'
# 查詢處理結果
curl "http://localhost:8000/api/v1/cases/CASE-2026-001"
# 健康檢查
curl "http://localhost:8000/api/v1/health"CREATE TABLE case_processing (
case_id VARCHAR2(100) PRIMARY KEY,
status VARCHAR2(50) NOT NULL,
request_data CLOB,
llm_response CLOB,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
host_name VARCHAR2(100)
);REDIS_HOST: Redis 主機位址REDIS_PORT: Redis 端口(預設 6379)REDIS_DB: Redis 資料庫編號REDIS_PASSWORD: Redis 密碼(可選)
ORACLE_USER: 資料庫用戶名ORACLE_PASSWORD: 資料庫密碼ORACLE_DSN: 資料庫連線字串(格式:host:port/service)ORACLE_POOL_MIN: 最小連線數ORACLE_POOL_MAX: 最大連線數
WORKER_BATCH_SIZE: 每次批量處理的任務數(預設 10)WORKER_POLL_INTERVAL: 隊列輪詢間隔(秒,預設 1)WORKER_MAX_RETRY: 最大重試次數(預設 3)
- API 服務: 可部署多個實例,通過負載均衡器分發請求
- Worker 服務: 可部署多個實例,自動從共享隊列中拉取任務
- Redis: 可使用 Redis Cluster 或 Sentinel 提高可用性
- 使用 Prometheus + Grafana 監控隊列長度、處理速度
- 記錄 DLQ 中的失敗任務,定期分析原因
- 監控資料庫連線池使用率
A: API 會先檢查 Redis 緩存,如果案號已存在,直接返回當前狀態,不會重複推送到隊列。
A: 增加 Worker 實例數量,而非增加連線池大小。Worker 使用批次寫入,每個 Worker 只佔用少量連線。
A: Worker 會自動重試(最多 3 次),超過重試次數後會將任務移至 DLQ,並標記案號狀態為「失敗」。
A: Redis 緩存有 TTL(預設 1 天),資料庫數據需要定期清理:
DELETE FROM case_processing WHERE updated_at < SYSDATE - 30;MIT License