记一次服务端定时器问题的解决

最近遇到了一次服务端定时器性能瓶颈的问题,把解决过程在此记录一下,作为备忘。

首先是前一段线上项目连续导人,平均在线千人左右,随之服务器慢接口(>100ms)越来越多,一天能达到五位数。观察内存占用情况,不高,没有频繁old gc的情况。观察cpu占用率,达70%-90%。这个数据是比较高的,比一般同等人数在线的游戏高出不少。这说明出现这种情况不太正常,并不是单纯在线高需要分服务器的问题,可能代码中某部分存在性能瓶颈。

顺着这个思路,在慢接口中的关键节点加日志调试,发现运行时间长的是一段添加新定时器的代码。这段代码是按时间顺序,将定时器添加到保存列表的一个合适位置,执行过程中会加全局锁。怀疑是定时器数量太多时,这段代码执行慢。用Jstack查看线程状态,也侧面印证了这一点,多个线程都在等待这段代码使用的全局锁。仔细研读这段代码,发现它使用LinkedList来保存所有定时器,所以插入和移除的时间复杂度都是O(N)。考虑改成PriorityQueue,这样插入和删除都降为O(logN)。

新代码上线后,慢接口大幅度减少,cpu占用也降到20%左右。说明优化起到明显效果。

总结几点:

  1. Jstack真的很有用。除了可以看死锁,还可以看线程运行状态、锁竞争情况,多次Jstack下都在Runnable状态的代码往往是执行较耗时的。
  2. 做好日志监控。慢接口数量、平均响应时间、平均接口数据包大小、内存占用、cpu占用,这些一有异常,能够及时被通知到。主动接受监控报警,而不是被动接受玩家反馈。
  3. 一定要做好压测。为今后一段时间设立目标,按预估负载,尽量模拟线上真实情况。对于怀疑可能产生瓶颈的代码重点压测。做到早发现,早解决。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值