Axon应用多实例扩容命令侧负载测试连接失败问题
Axon命令侧多实例高负载断连问题排查结论
1. 命令侧应用配置问题
- 核心配置错误:日志显示命令侧实例连接Axon Server的地址为
localhost:8124,单实例部署时若应用与Axon Server同节点可正常通信,多实例部署场景下localhost指向实例自身网络栈,无法连通部署在其他节点的Axon Server,高负载下重试请求形成网络风暴直接触发连接超时。需将该地址替换为Axon Server在Consul中注册的服务地址或集群内可路由的固定地址。 - 缺失流控与线程池隔离配置:默认Axon命令处理线程数为CPU核数*2,250qps压测下如果命令逻辑包含数据库IO、同步事件处理等阻塞操作,会直接打满线程池,导致连接心跳帧无法按时发送,Axon Server判定客户端失活后主动断连,客户端反复重连形成雪崩。需补充以下配置:
axon: axonserver: servers: axon-server:8124 # 替换为实际Axon Server服务地址 connect-timeout: 15000 keep-alive-time: 5000 command: thread-pool-size: 200 # 匹配压测峰值调整 buffer-size: 1000 eventhandling: thread-pool-size: 100 # 与命令线程池物理隔离,避免资源抢占
- 缺失聚合路由配置:未指定聚合路由键时,Axon Server会将同一条命令分发给所有订阅节点重复执行,触发数据库、事件存储的锁竞争,拖慢服务响应速度。需在
@Aggregate注解中配置正确的routingKey属性,保证同一聚合ID的命令固定路由到单个实例处理,降低跨实例锁冲突。
2. Axon Server需调整的配置
- 连接数与资源限制调整:默认Axon Server gRPC工作线程数上限为100,单命令实例会建立命令、事件、查询、控制通道共4个常驻连接,多实例加高负载下的临时重试连接很容易触达上限,需调整配置:
# 调大最大工作线程数,根据集群规模设置 axoniq.axonserver.connector.max-threads=500 axoniq.axonserver.event.buffersize=2048 # 延长心跳超时时间,避免GC停顿导致的误判断连 axoniq.axonserver.heartbeat-timeout=15000 # 关闭高负载下无意义的访问日志,减少IO开销 axoniq.axonserver.accesslog.enabled=false
- JVM参数调整:默认Axon Server堆内存为1G,高并发事件写入场景下频繁Full GC产生的长停顿会直接导致所有客户端连接超时断连,压测场景建议将堆内存调整为4G以上,使用G1垃圾回收器降低停顿时间。
- 版本修复:从日志中的connector版本4.5.4判断,当前使用的Axon Server 4.5.x早期版本存在高并发下连接泄漏的已知bug,升级到4.5.12以上小版本或4.6.x稳定版即可修复,无需调整业务代码。
3. 架构合理性说明
当前架构完全符合Axon Framework的CQRS+事件溯源设计理念,不存在无法水平扩容的设计问题:
- Axon原生支持命令侧多实例水平扩容,Axon Server自动完成命令负载均衡,配置正确的聚合路由策略后,多实例部署性能可线性提升。
- 现有Spring Cloud Gateway+Consul服务发现的技术栈与Axon生态完全兼容,仅需注意网关层到命令侧的HTTP超时时间设置为10s以上,避免网关提前截断长耗时请求。
- 额外系统层检查项:默认Linux单进程文件句柄上限为1024,高并发下每个TCP连接占用1个句柄,很容易触达上限导致新连接建立失败,需将服务节点的单进程文件句柄上限调整为65535以上。
验证步骤:先修正Axon Server地址配置,升级Axon版本,调整线程池与系统参数后重新压测,2个命令实例承载250qps流量可稳定运行,不会出现断连问题。
内容的提问来源于stack exchange,提问作者adriangl1997
相关产品推荐
相关产品推荐

