Files
ljwx-stock/K8S_DEPLOYMENT_SUMMARY.md
bruno f5fc79e70f feat: Implement Phase 2 - Offline Batch Recommendation System (v1.2.0)
完成离线批处理架构第二阶段,实现每日自动生成股票推荐,API响应时间从10-20分钟降至<100ms

## 核心功能

### 1. 批处理任务 (RecommendationBatchJob)
- 7阶段处理流程:报价 → 历史数据 → 特征工程 → 评分排序 → 解释生成 → 数据库存储 → Redis发布
- 30+只A股股票池(覆盖银行、科技、消费、医疗等行业)
- 技术指标:MA5/10/20、RSI、MACD、ATR、成交量比率
- 简化评分算法(基础分50 + 趋势/动量/成交量加分,最高100分)

### 2. 自动调度 (APScheduler)
- 每日凌晨3:30自动执行(上海时区)
- 支持手动触发(测试/应急场景)
- 完整的任务生命周期管理(启动/停止/监控)
- 事件监听(执行成功/失败告警)

### 3. 管理API (10+ endpoints)
- POST /admin/batch/recommendations/trigger - 手动触发任务
- GET /admin/batch/recommendations/status - 任务状态和下次执行时间
- GET /admin/batch/recommendations/snapshots - 快照列表
- GET /admin/batch/recommendations/snapshots/{version} - 快照详情
- POST /admin/batch/recommendations/snapshots/{version}/publish - 发布草稿
- GET /admin/batch/jobs/history - 执行历史和统计
- DELETE /admin/batch/jobs/{job_id} - 取消运行中任务
- GET /admin/batch/health - 系统健康检查

### 4. 测试基础设施
- 集成测试:04_test_batch_job.py(端到端验证)
- API测试脚本:05_test_admin_api.sh(自动化测试)
- 手动触发脚本:trigger_batch_job.py(CLI工具,支持dry-run)
- stock_limit参数(快速测试,5-10只股票 vs 30+只)

## 新增文件

### 后端实现
- backend/app/jobs/recommendation_batch_job.py (~700行) - 核心批处理逻辑
- backend/app/services/batch_scheduler.py (~200行) - APScheduler集成
- backend/app/routes/batch_admin.py (~500行) - 管理API
- backend/app/dao/recommendation_snapshot_dao.py - 快照数据访问
- backend/app/dao/batch_job_log_dao.py - 任务日志数据访问
- backend/app/modules/recommendation_redis_manager.py - Redis缓存管理器

### 测试和脚本
- backend/scripts/trigger_batch_job.py - 手动触发工具
- backend/scripts/batch_test/04_test_batch_job.py - 集成测试
- backend/scripts/batch_test/05_test_admin_api.sh - API测试脚本
- backend/tests/batch/test_dao.py - DAO单元测试
- backend/tests/batch/test_redis_manager.py - Redis管理器测试

### 文档
- PHASE2_IMPLEMENTATION_COMPLETE.md (19KB) - Phase 2完整技术文档
- OFFLINE_BATCH_ARCHITECTURE_PLAN.md - 架构设计方案
- README.md更新:离线批处理系统使用指南

## 修改文件

- backend/main.py - 集成scheduler到FastAPI生命周期
- backend/app/jobs/__init__.py - 导出批处理任务类

## 性能提升

- **API响应时间**: 10-20分钟 → <100ms (99.2%↓)
- **用户体验**: 实时响应 vs 长时间等待
- **系统负载**: 离线计算 + 在线读取(降低实时计算压力)
- **数据一致性**: 全量计算 + 版本管理 + 原子发布

## 技术栈新增

- APScheduler 3.10.4 - 异步任务调度
- 模板方法模式 - BaseBatchJob框架
- 分布式锁 - Redis防并发
- 双缓冲发布 - 原子更新防脏读

## 后续计划

- Phase 3: AI增强推荐(Claude解释生成)
- Phase 4: 监控告警(Prometheus + Grafana)
- Phase 5: 性能优化(并行处理 + 增量更新)

Generated with Claude Code
Co-Authored-By: Claude Sonnet 4.5 <[email protected]>
2025-12-25 22:08:39 +08:00

7.8 KiB
Raw Permalink Blame History

Kubernetes 部署总结

部署日期: 2024-12-24 命名空间: ljwx-stock 状态: ✅ 部署成功(Backend正在初始化)


📊 部署概览

成功部署的资源

资源类型 名称 状态 说明
Namespace ljwx-stock ✅ Active 已创建命名空间
StatefulSet postgres ✅ Running (1/1) PostgreSQL 16
StatefulSet redis ✅ Running (1/1) Redis 7
Deployment claude-stock-backend ⏳ Initializing (1/2) Backend + Frontend Pod
Service claude-stock-backend ✅ LoadBalancer External IP: 192.168.139.200
Service claude-stock-frontend ✅ LoadBalancer External IP: 192.168.139.201
PVC postgres-pvc ✅ Bound 10Gi 持久存储
PVC redis-pvc ✅ Bound 5Gi 持久存储
ConfigMap claude-stock-config ✅ Created 应用配置
Secret postgres-secret ✅ Created 数据库密码
Secret redis-secret ✅ Created Redis密码

🌐 访问地址

External Services (LoadBalancer)

# Backend API
http://192.168.139.200:80

# Frontend Dashboard
http://192.168.139.201:8090

测试访问

# 测试 Backend Health Endpoint
curl http://192.168.139.200/health

# 测试 Frontend
curl http://192.168.139.201:8090

📁 数据持久化

PostgreSQL 数据卷

  • PVC名称: postgres-pvc
  • 容量: 10Gi
  • 挂载路径: /var/lib/postgresql/data
  • StorageClass: (默认)

Redis 数据卷

  • PVC名称: redis-pvc
  • 容量: 5Gi
  • 挂载路径: /data
  • StorageClass: (默认)

🔧 当前状态详情

Pod 状态

NAME                                    READY   STATUS    RESTARTS   AGE
claude-stock-backend-549f8c6ff4-7w9p9   1/2     Running   6          14m
postgres-0                              1/1     Running   1          3h43m
redis-0                                 1/1     Running   1          3h43m

说明:

  • ✅ Frontend容器: 已就绪并运行 (Vite dev server on port 5173)
  • ⏳ Backend容器: 正在初始化,首次启动需安装Python依赖包
    • 已重启6次(因liveness probe超时)
    • 预计需要5-10分钟完成依赖安装

Services 端口映射

Service Type Cluster IP External IP Port Mapping
claude-stock-backend LoadBalancer 192.168.194.251 192.168.139.200 80:31272/TCP
claude-stock-frontend LoadBalancer 192.168.194.148 192.168.139.201 8090:31535/TCP
postgres ClusterIP (Headless) None - 5432/TCP
redis ClusterIP (Headless) - - 6379/TCP

📝 配置详情

环境变量 (Backend)

DATABASE_URL: postgresql://stockai:[email protected]:5432/stockai
REDIS_URL: redis://:[email protected]:6379/0
ENVIRONMENT: production

Volume Mounts (使用 HostPath)

Backend Code: /Users/brunogao/work/codes/ljwx/ljwx-stock/backend
Frontend Code: /Users/brunogao/work/codes/ljwx/ljwx-stock/frontend

优势: 代码修改实时生效,无需重新构建镜像 限制: 仅适用于单节点K8s集群(如Docker Desktop Kubernetes)


⚙️ 资源配额

Backend Container

Requests:
  CPU: 250m
  Memory: 512Mi
Limits:
  CPU: 1000m (1 core)
  Memory: 1Gi

Frontend Container

Requests:
  CPU: 100m
  Memory: 256Mi
Limits:
  CPU: 500m
  Memory: 512Mi

HPA (Horizontal Pod Autoscaler)

Min Replicas: 1
Max Replicas: 3
Target CPU: 70%
Target Memory: 80%

🔍 监控和日志

查看 Pod 状态

kubectl get pods -n ljwx-stock
kubectl describe pod <pod-name> -n ljwx-stock

查看日志

# Backend logs
kubectl logs -f -n ljwx-stock -l app=claude-stock-backend -c backend

# Frontend logs
kubectl logs -f -n ljwx-stock -l app=claude-stock-backend -c frontend

# PostgreSQL logs
kubectl logs -f -n ljwx-stock postgres-0

# Redis logs
kubectl logs -f -n ljwx-stock redis-0

实时监控

# Watch pod status
kubectl get pods -n ljwx-stock -w

# Watch all resources
kubectl get all -n ljwx-stock -w

🐛 已知问题和解决方案

问题1: Backend容器反复重启

现象: Pod RESTARTS次数持续增加

原因:

  • 首次启动安装依赖包耗时较长(5-10分钟)
  • Liveness probe initialDelaySeconds=60秒不足
  • 容器在依赖安装完成前被探针杀死

临时解决方案:

# 方案1: 延长探针初始延迟
kubectl patch deployment claude-stock-backend -n ljwx-stock -p '{"spec":{"template":{"spec":{"containers":[{"name":"backend","livenessProbe":{"initialDelaySeconds":300}}]}}}}'

# 方案2: 临时禁用探针(不推荐生产环境)
kubectl patch deployment claude-stock-backend -n ljwx-stock -p '{"spec":{"template":{"spec":{"containers":[{"name":"backend","livenessProbe":null}]}}}}'

永久解决方案: 构建包含所有依赖的Docker镜像

问题2: HostPath在多节点集群不可用

现象: 如果K8s集群有多个worker节点,Pod调度到其他节点时无法访问代码

解决方案:

  1. 使用 PVC + NFS/Ceph 共享存储
  2. 构建完整Docker镜像并push到registry
  3. 添加节点亲和性确保Pod调度到特定节点

🚀 后续优化建议

短期优化

  1. 构建Docker镜像 - 避免每次启动都安装依赖

    # Backend
    docker build -t ljwx-stock/backend:v1.0 backend/
    docker push ljwx-stock/backend:v1.0
    
    # Frontend
    docker build -t ljwx-stock/frontend:v1.0 frontend/
    docker push ljwx-stock/frontend:v1.0
    
  2. 调整探针参数

    livenessProbe:
      initialDelaySeconds: 300  # 增加到5分钟
      periodSeconds: 30
    readinessProbe:
      initialDelaySeconds: 120  # 增加到2分钟
      periodSeconds: 10
    
  3. 添加Init Container - 预先检查数据库连接

    initContainers:
    - name: wait-for-postgres
      image: busybox:1.35
      command: ['sh', '-c', 'until nc -z postgres.ljwx-stock.svc 5432; do sleep 2; done']
    

中期优化

  1. Ingress配置 - 统一入口,SSL termination
  2. Prometheus监控 - 集成Prometheus抓取metrics
  3. 日志聚合 - ELK/Loki stack
  4. Secrets管理 - 使用External Secrets Operator

长期优化

  1. GitOps - 使用ArgoCD/FluxCD自动部署
  2. 多环境 - dev/staging/prod命名空间隔离
  3. 蓝绿部署 - 零停机更新
  4. 备份恢复 - Velero备份整个namespace

📋 验收检查清单

  • Namespace创建成功
  • PostgreSQL StatefulSet运行正常
  • Redis StatefulSet运行正常
  • Backend Deployment创建成功
  • Backend容器完全启动(等待依赖安装完成)
  • Frontend容器运行正常
  • LoadBalancer分配External IP
  • Health endpoint响应正常
  • 数据库连接测试通过
  • Redis连接测试通过

🔗 相关文档

  • K8s配置文件: /k8s/temp/
  • 原始配置: /k8s/
  • README: /README.md (包含数据抓取和维护指南)
  • 数据管理: 参考README中的"数据增量更新与维护"章节

📞 故障排查命令

# 检查所有资源
kubectl get all -n ljwx-stock

# 检查配置
kubectl get configmap,secret -n ljwx-stock

# 检查PVC
kubectl get pvc -n ljwx-stock

# 检查Events
kubectl get events -n ljwx-stock --sort-by='.lastTimestamp'

# 进入Pod调试
kubectl exec -it <pod-name> -n ljwx-stock -c backend -- /bin/bash

# 端口转发(本地调试)
kubectl port-forward -n ljwx-stock service/claude-stock-backend 8000:80
kubectl port-forward -n ljwx-stock service/claude-stock-frontend 8090:8090

部署完成时间: 2024-12-24 15:00:00 K8s集群: Docker Desktop Kubernetes (localhost:26443) 命名空间: ljwx-stock