从单机到分布式的平滑迁移、Docker部署与配置管理
完整部署架构
══════════════
┌─────────────────────────────────────────────────────┐
│ Nginx (反向代理) │
│ SSE长连接支持 + 静态资源 + 负载均衡 │
└──────────────────────┬──────────────────────────────┘
│
┌──────────────┼──────────────┐
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ App实例 1 │ │ App实例 2 │ │ App实例 3 │
│ (Spring Boot)│ │ (Spring Boot)│ │ (Spring Boot)│
└──────┬───────┘ └──────┬───────┘ └──────┬───────┘
│ │ │
└────────────────┼────────────────┘
│
┌───────────┬───────────┼───────────┬───────────┐
│ │ │ │ │
▼ ▼ ▼ ▼ ▼
┌─────┐ ┌────────┐ ┌────────┐ ┌───────┐ ┌───────┐
│MySQL│ │Milvus │ │ Redis │ │RocketMQ│ │Nacos │
│ 8.0 │ │ 2.6.0 │ │Cluster │ │ 4.9.6 │ │ 2.3.2 │
│ │ │ │ │ (3节点) │ │ │ │ │
└─────┘ └────────┘ └────────┘ └───────┘ └───────┘
项目提供了一键启动脚本 docker/cluster-runtime/setup.sh:
docker-compose.cluster.yml 服务清单: 中间件层: ├── mysql MySQL 8.0 数据持久化 ├── milvus-standalone Milvus 2.6 向量数据库 ├── milvus-etcd etcd Milvus元数据 ├── milvus-minio MinIO Milvus对象存储 ├── redis-node-1/2/3 Redis 7 3节点Cluster ├── rocketmq-namesrv RocketMQ 消息队列 ├── rocketmq-broker RocketMQ 消息代理 ├── nacos Nacos 2.3 配置中心 └── gpt4free GPT4Free 免费AI模型 一键启动: $ bash docker/cluster-runtime/setup.sh → 自动拉取镜像 → 启动所有服务 → 初始化数据库 → 健康检查
项目的分布式能力通过SPI(Service Provider Interface)架构实现,每个子系统可独立选择LOCAL或REDIS模式:
分布式运行时SPI: hub-common 定义10个SPI接口: ┌──────────────────────────────────────────────────────┐ │ ActiveTaskStore ← 活跃任务追踪 │ │ CircuitBreakerStateStore ← 熔断器状态 │ │ InboundDedupeStore ← 入站消息去重 │ │ ChannelSessionStore ← 通道会话绑定 │ │ CanaryTokenStore ← 金丝雀令牌存储 │ │ InjectionRateLimiterStore ← 注入限流计数 │ │ UserRateLimiterRuntime ← 用户并发控制 │ │ LoginRateLimiterRuntime ← 登录限流 │ │ KeyPoolRuntimeStateStore ← 密钥池状态同步 │ │ TaskRuntimeStore ← 任务运行时状态 │ └──────────────────────────────────────────────────────┘ 每个SPI有LOCAL和REDIS两个实现: ┌──────────────────────────────────────────┐ │ distributed-config.yml: │ │ │ │ hub.distributed: │ │ mode: redis # 全局默认 │ │ active-task: local # 按子系统覆盖 │ │ circuit-breaker: redis │ │ canary-token: redis │ │ key-pool: redis │ │ │ │ → 可以混合使用! │ │ → 不重要的用LOCAL,重要的用REDIS │ └──────────────────────────────────────────┘
| 功能 | Redis数据结构 | 说明 |
|---|---|---|
| Key池状态同步 | Hash + String | 多实例共享Key状态(ACTIVE/COOLING/DISABLED) |
| 熔断器状态 | Lua脚本 + String | 原子状态转换,跨实例共享熔断状态 |
| 金丝雀令牌 | String (TTL 30天) | 多实例共享相同的canary token |
| 消息去重 | SETNX (TTL) | 防止多实例重复处理同一消息 |
| 通道会话 | Hash | 用户在哪个实例上的哪个Agent对话 |
| 注入限流 | Sorted Set | 按用户ID统计注入尝试次数 |
| 轮询索引 | INCR | Key轮询的原子计数器 |
RocketMQ Topic 分布: ┌──────────────────────────────────────────────────┐ │ Topic: TASK_RETRY │ │ 用途: 失败任务的异步重试 │ │ → TaskScheduler消费 → 重新提交到AgentExecutor │ ├──────────────────────────────────────────────────┤ │ Topic: KEY_POOL_REFRESH │ │ 用途: 密钥池配置变更通知 │ │ → 所有实例消费 → 热更新内存中的Key池 │ ├──────────────────────────────────────────────────┤ │ Topic: CHANNEL_INGEST │ │ 用途: 通道消息入站处理(如QQ频道) │ │ → 异步消费 → 调用Agent编排器 │ └──────────────────────────────────────────────────┘
平滑迁移策略:
阶段1: 单实例 (LOCAL模式)
┌───────────────────────────────────────┐
│ 所有SPI使用LOCAL实现 │
│ · 无需Redis/RocketMQ │
│ · 所有状态在内存中 │
│ · 适合开发和低流量场景 │
└───────────────────────────────────────┘
│ 修改配置文件即可
▼
阶段2: 分布式 (REDIS模式)
┌───────────────────────────────────────┐
│ 按需切换SPI到REDIS实现 │
│ · 可以逐个子系统迁移 │
│ · 先迁移最重要的(Key池、熔断器) │
│ · 后迁移次要的(登录限流、去重) │
│ · LOCAL实现作为Redis故障时的降级后备 │
└───────────────────────────────────────┘
关键设计:
· Redis不可用时自动降级到LOCAL
· 每个子系统独立选择模式
· 不需要修改任何业务代码
项目的配置文件按职责分离:
| 配置文件 | 职责 |
|---|---|
application.yml | 主配置(数据库、Redis、RocketMQ、Nacos) |
agent-config.yml | Agent ReAct/工具/并行配置 |
model-catalog.yml | 可用LLM模型列表 |
llm-config.yml | LLM供应商设置 |
security-config.yml | JWT和提示词防护 |
distributed-config.yml | 分布式运行时模式选择 |
orchestrator-config.yml | 编排器线程池/超时/熔断 |
search-rag-config.yml | RAG引擎/分块/缓存 |