Vertx Event Bus与Hazelcast扩缩容:大消息下TPS骤降排查
Vert.x 4.4.5 微服务大消息场景下TPS骤降&延迟排查求助
背景与问题
我们基于Vert.x 4.4.5构建微服务,部署在RHEL 9系统的Dell R730 18核虚拟机上(共11个微服务):
- 消息大小约1kb时,可达到3k TPS
- 消息提升至生产环境平均100kb后,TPS骤降至600,且Event Bus消费者接收消息存在数秒延迟
为解决Event Bus不适合大消息的问题,我们调整了方案:
服务A(ApiGateWay)将100kb消息写入Shared Data,完成后调用
eventBus.request(.., .., ..)发送apiKey通知服务B(BusinessService),由服务B通过apiKey异步从Shared Data获取数据
但优化后延迟问题依然存在。
已尝试的配置调整
- 服务A与B的
WorkerInstances、WorkerPoolSize均设置为100 - 消费者消息缓冲区设置为10000:
eventBus.consumer(.., ..).setMaxBufferedMessages(10000) - 启动服务时添加Hazelcast参数:
-Dhazelcast.socket.receive.buffer.size=10240 -Dhazelcast.socket.send.buffer.size=10240
压测详情
- 工具:Jmeter
- 线程数:7000
- 循环次数:100
- Ramp up时间:0.7s
- 固定延迟:1000ms
排查建议
1. 先验证压测模型合理性
7000线程在0.7s内启动,相当于每秒启动10000个线程,远超18核虚拟机的处理能力,会引发大量上下文切换直接拖垮系统。建议先调整Ramp up时间至合理范围(比如70s,每秒启动100线程),重新压测排除压测本身的干扰。
2. 排查Shared Data性能瓶颈
- 确认Shared Data的实现:如果用Hazelcast分布式Map,检查集群备份数、分区数配置是否合理,同时确认apiKey生成是否均匀,避免热点Key引发的读写阻塞
- 添加Metrics监控:统计Shared Data写入/读取100kb数据的耗时,确认是否是存储层成为性能瓶颈
3. 调整Event Bus的调用模式
eventBus.request()是同步等待响应的模式,当服务B处理缓慢时,服务A的请求线程会被阻塞占用。建议改为eventBus.send()异步通知,避免服务A线程池被占满导致后续请求排队。
4. 检查Worker线程池实际利用率
通过JConsole、VisualVM等工具监控Worker线程池的活跃线程数、队列积压长度:
- 如果队列持续积压,说明线程池配置仍不足,或者单任务处理耗时过长,需要进一步拆解任务逻辑
- 若线程池空闲率高,可能是任务调度逻辑存在阻塞点
5. 系统与网络层面优化
- 调整RHEL 9的TCP参数:当前设置的Hazelcast socket buffer为10k,远小于系统默认值,反而限制传输效率,建议调整为
131072(128k)或更高 - 监控虚拟机资源:查看CPU使用率、内存占用、网络带宽、磁盘IO,确认是否有资源耗尽的情况(比如CPU跑满、网络带宽达到上限)
6. Vert.x内部配置排查
- 开启Event Bus压缩:大消息场景下,开启
eventBus.setCompressionLevel(CompressionLevel.MEDIUM)可减少传输数据量 - 查看Vert.x DEBUG日志:追踪Event Bus消息的发送、接收节点,确认是否有消息堆积在传输队列中
内容的提问来源于stack exchange,提问作者Areeb Gillani
相关产品推荐
相关产品推荐

