MCP Server 多实例与负载均衡问题
一、是什么问题?
1. 传统业务系统是怎么解决高并发的?
在传统后端系统中,一个业务服务通常不会只部署一个实例,而是部署多个实例。
例如公司的订单服务:
Business Gateway
│
┌────────────┼────────────┐
↓ ↓ ↓
Order-01 Order-02 Order-03
│ │ │
└────────────┼────────────┘
↓
MySQL
用户请求:
GET /api/order/12345
先经过 Business Gateway,由 Gateway 把请求分发到不同的 Order Service 实例。
这样可以实现:
- 多实例横向扩容
- 请求负载均衡
- 单实例故障摘除
- 提升系统并发能力
2. MCP 场景产生了什么问题?
现在我们把订单查询能力通过 MCP 暴露给 Agent。
用户在飞书中说:
“帮我查询一下订单 12345 的状态。”
Agent 决定调用:
query_order(order_id=12345)
请求不再直接调用传统 HTTP API,而是:
Agent
↓
MCP Server
↓
Order API
这时候就出现一个问题:
MCP Server 自己是不是也需要像传统业务服务一样部署多个实例?如果部署多个实例,Agent 的 MCP 请求能不能自动负载均衡?
答案是:
可以。MCP Server 完全可以多实例部署。
但 MCP 场景相比普通 HTTP API,需要额外考虑:
MCP 可能存在 Session、连接、Streaming 以及实例本地状态。
这就是 MCP 多实例部署时真正需要解决的问题。
二、为什么 MCP 会出现这个问题?
核心原因是:
传统业务 API 通常强调无状态请求,而 MCP 除了 Tool 调用之外,还可能涉及 Session、持续连接和执行上下文。
下面还是用“查询订单”这个例子。
1. 普通业务 API 很容易做多实例
比如:
用户
↓
Business Gateway
↓
┌──────────┬──────────┬──────────┐
↓ ↓ ↓
Order-01 Order-02 Order-03
假设:
请求 A → Order-01
请求 B → Order-02
请求 C → Order-03
只要订单数据存在 MySQL 中,三个实例都能处理。
因为:
Order-01 ─┐
Order-02 ─┼──→ MySQL
Order-03 ─┘
业务状态没有放在某一个实例的内存里。
所以它天然适合负载均衡。
2. MCP 可能存在 Session
MCP Client 和 MCP Server 建立连接之后,可能存在一个 Session:
Agent
│
│ Session A
↓
MCP Server-01
假设 Session A 的相关状态只保存在:
MCP Server-01
└── Session A
那么下一次请求经过 Gateway,被分到了:
Agent
↓
MCP Gateway
↓
MCP Server-02
但是:
MCP Server-02
└── 没有 Session A
这时候就可能出现 Session 不一致的问题。
3. MCP 还可能存在 Streaming / 长连接
例如 Agent 调用一个耗时较长的 Tool:
Agent
↓
MCP Server
↓
Tool
↓
业务系统
执行过程中可能存在持续的数据传输。
它和普通的:
POST /api/order
这种“一次请求 → 一次响应”的模式不完全一样。
因此 MCP 多实例部署时,需要考虑:
- Session 应该保存在哪里?
- 长连接应该如何管理?
- 请求能不能随意切换实例?
- 实例故障之后 Session 怎么恢复?
- Tool 执行状态是否依赖某一个实例?
4. 用订单查询例子总结
原来的业务系统:
用户
↓
Business Gateway
↓
Order-01 / Order-02 / Order-03
问题比较简单:
请求打到哪个 Order Service 都可以。
而 MCP:
Agent
↓
MCP Gateway
↓
MCP-01 / MCP-02 / MCP-03
如果:
Session A
↓
MCP-01
下一次:
Session A
↓
MCP-02
但 Session A 只存在 MCP-01:
MCP-01
└── Session A
MCP-02
└── 没有 Session A
那么多实例负载均衡就不能简单地理解成:
“请求随机扔给任意一个 MCP Server 就行。”
这就是 MCP 多实例场景真正需要解决的问题。
三、怎么解决?
核心思路就三个:
MCP Server 多实例化 + 共享状态外置 + Gateway 负责负载均衡。
还是使用刚才的“查询订单”例子。
1. 第一层:MCP Server 多实例 + MCP Gateway
我们把 MCP Server 部署成多个实例:
Agent
│
↓
MCP Gateway
│
┌────────────┼────────────┐
↓ ↓ ↓
MCP-01 MCP-02 MCP-03
用户查询:
“帮我查询订单 12345”
Agent 调用:
query_order(12345)
MCP Gateway 根据负载把请求分给:
MCP-02
于是:
Agent
↓
MCP Gateway
↓
MCP-02
如果现在有 10,000 个 Agent 请求,就可以部署更多实例:
MCP-01
MCP-02
MCP-03
...
MCP-20
由 MCP Gateway 把请求分摊到这些实例。
这一层解决的是:
MCP 能力层自身的高并发和横向扩展问题。
2. 第二步:把 Session / 共享状态外置
为了避免:
MCP-01
└── Session A
MCP-02
└── 不认识 Session A
不要把关键 Session 状态只放在某一个 MCP Server 的本地内存里。
而是:
┌── MCP-01
│
MCP Gateway ─────┼── MCP-02
│
└── MCP-03
│
↓
Redis / DB
例如:
Redis
Session A
├── userId
├── tenantId
├── permission
└── execution context
那么:
第一次:
Agent
↓
MCP Gateway
↓
MCP-01
↓
Redis
下一次:
Agent
↓
MCP Gateway
↓
MCP-02
↓
Redis
MCP-02 依然可以拿到 Session A 的状态。
因此:
MCP Server 尽可能无状态,共享状态放到 Redis / DB 等外部存储。
3. 第三步:MCP Server 再调用原来的业务系统
注意:
MCP Server 不需要替代原来的业务服务。
还是刚才的订单查询。
MCP Server 收到:
query_order(12345)
然后转换成传统业务 API:
GET /api/order/12345
再进入原来的 Business Gateway:
Agent
↓
MCP Gateway
↓
MCP-02
↓
Business Gateway
↓
┌──────────┬──────────┬──────────┐
↓ ↓ ↓
Order-01 Order-02 Order-03
↓ ↓ ↓
MySQL
假设这一次 Business Gateway 把请求分给:
Order-03
那么完整链路就是:
Agent
│
│ query_order(12345)
↓
MCP Gateway
│
↓
MCP-02
│
│ GET /api/order/12345
↓
Business Gateway
│
↓
Order-03
│
↓
MySQL
这里就出现了两层独立的负载均衡:
第一层
MCP Gateway
↓
MCP Server × N
解决:
MCP 能力层的高并发。
第二层
Business Gateway
↓
Business Service × N
解决:
传统业务系统的高并发。
两层不是 MCP 特有的机制,而是因为:
MCP 能力层和传统业务服务本来就是两个独立的服务集群。
4. 最终推荐架构
对于企业级 MCP 平台,可以最终设计成:
User
│
↓
Agent
│
↓
┌──────────────┐
│ MCP Gateway │
│ LB/Auth/Rate │
└──────┬───────┘
│
┌─────────────┼─────────────┐
↓ ↓ ↓
MCP-01 MCP-02 MCP-03
│ │ │
└─────────────┼─────────────┘
│
Redis / DB
Session / State
│
↓
Tool Runtime
│
↓
Business Gateway
│
┌─────────────┼─────────────┐
↓ ↓ ↓
Order-01 Order-02 Order-03
│ │ │
└─────────────┼─────────────┘
↓
MySQL
最核心的设计原则
MCP Server
↓
尽量无状态
↓
Session / 共享状态外置
↓
Gateway 负责负载均衡
↓
MCP Server 横向扩容
↓
继续调用原有业务 Gateway
↓
业务服务继续多实例部署
因此最终可以用一句话回答这个问题:
MCP Server 可以像普通后端服务一样做多实例和负载均衡,MCP 本身不负责负载均衡。MCP 真正需要额外解决的是 Session、Streaming 和实例状态问题,所以生产环境通常让 MCP Server 尽量无状态,把共享状态外置到 Redis/DB,通过 MCP Gateway 做第一层负载均衡;MCP Server 再调用原有 Business Gateway,由业务服务集群承担第二层业务并发。