压力测试 案例 jconsole 消息推送服务器压力下导致系统卡死的分析调试过程

本文详细记录了一次基于Netty的消息推送服务器在压力测试下的性能问题及调试过程。在压力测试中,服务器在高并发下出现卡死现象,通过分析发现主要瓶颈在于数据库操作,尤其是未加索引的删除操作。通过对数据库进行索引优化和调整表引擎,成功降低了线程消耗,提高了服务器处理能力。最后总结了后续可能的优化方向,包括数据库深度优化、连接池使用和消息接收队列等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

开发消息推送服务器, 基于netty
主要引擎分4大组件: toolPooler, taskDispatcher, httpHandler, registerCenter

toolPooler, 任务池, 负责任务接收和保存
taskDispatcher, 任务派送器, 负责任务发送处理
httpHandler, http连接器, 负责处理netty上的所有websocket和ajax连接, 提供心跳支持
registerCenter 注册中心, 负责连接的注册信息(userId, devicerId), 以及心跳时间决定

3个人, 1个架构师, 1个4年,1个3年

前期架构师设计花了3天, 中期2个人各花10天, 后期集成调试3天

服务器开发完成, 在后期集成调试时, 做压力测试,
1.长连接测试: 不带消息处理, 只连接和心跳,
a.以一台2W块钱的服务器虚拟出来的wind8, 能支持1600个websocket同时在线并心跳后, 就很难再连接上了, 分析其原因, 打开其他页面, netty响应速度极慢(5s-30s)
b.以一台2W块钱的服务器虚拟出来的centos6, 能支持3000个websocket同时在线并心跳, 其实这个只是保持数量, 因为没有更多的客户端了...
2.消息推送测试: 同时在线100人, 每秒都给这100人发消息
a.win8的1600的能力被嫌弃, 只在centos6测试, 跑了30分钟, 程序就卡死了, 打开自己写的后台监控页面同样极慢(5s-30s-抓狂),
b.把程序回到开发机上, 下降压为每秒推30个消息, 打开jconsole监控, 如下图

[img]http://dl2.iteye.com/upload/attachment/0114/1416/1646e2c4-3552-3fe3-a342-6f3eab593140.jpg[/img]

[img]http://dl2.iteye.com/upload/attachment/0114/1418/aeebf767-2294-33c6-9b94-248342874797.jpg[/img]

现象: 线程直线上升, 到600个线程后, 线程数量一直上升没有回收(就像房价, 不像股市), 程序就出现访问简单页面卡死现象,
由此推出这个程序在centos6虚拟机的瓶颈是600个线程

分析: 消息推送, 在taskPooler里, 实现逻辑为:
收到消息 -> 存数据库 -> 发事件 -> 激活taskDispatcher的观察事件 ->
taskDispatcher处理: 判断推送的用户是否在线(通过registerCenter判断), 在线则调用httpHander把消息推出去, 否则无视

从图上分析, 线程数量直线上涨, 没有回落, 观察左右下角的panel, 有大量线程被阻塞, 主要入口在
receiveMsg (taskPooler.java:48)
即接收外面要推送消息, 最后追踪到自己的代码是
delete (taskPoolerImpl.java:135)

调试: 在delete前后加入时间日志


[img]http://dl2.iteye.com/upload/attachment/0114/1436/6d4ea367-47d4-3630-9990-0d248591d54a.png[/img]


分析: 看出来删除记录花了8秒, 而每秒又会产生100个任务入库, 入库后推送又需要删除,
所以每个线程卡死在8秒, 造成堆压, 现有数据库的数据量为60W, mysql数据库
然后定位删除代码, 发现是通过
where deviceId=? and sent_to=?
去数据库, 发现是innoDB表引擎, 没有做任何索引
接着就是改索引, 改表引擎, 如下图

[img]http://dl2.iteye.com/upload/attachment/0114/1432/eb5959f1-c6e7-3ede-8296-57e6414022cb.png[/img]

[img]http://dl2.iteye.com/upload/attachment/0114/1424/c6b614a8-5414-3f0c-ad08-03ecdc49db9b.png[/img]

[img]http://dl2.iteye.com/upload/attachment/0114/1426/d98d45e5-0df9-30ca-8d66-a0796e7ae405.png[/img]

然后再更新到服务器去了, 跑99个一直稳定在28-22个线程并发数量, 如图

[img]http://dl2.iteye.com/upload/attachment/0114/1515/e491f985-fc63-33ae-8353-693b7686c78f.png[/img]

[img]http://dl2.iteye.com/upload/attachment/0114/1517/4cf5afe3-cc92-3f73-bafc-f68bdd6a769d.png[/img]

----------再作死, 加大压力----------

再加大压力, 跑198个, 线程又出现同样情况, 飚升到600后卡死, 但增加速度慢了很多
再走同样的排除法, 发现还是delete卡住,

以30人天开发的服务器, 能达到每秒99个消息推送的能力, 已经可以了, 到此为止,
赶紧跟其他子系统集成


后续(如果有的话):
1.深度优化数据库
2.现在已经在用连接池了, 后续不使用连接池, 直接长期保持delete专用连接
3.在接收消息时添加队列进去缓冲和拒绝


总结, JVM要做成房价那样就是失败了, 要做成股市那样就是成功了
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值