世界boss卡服务器问题
2018-10-29 本文已影响0人
landon30
线上测试版本世界boss卡服务器临时解决方案
- 现象
- 当开启世界boss时,所有的业务包括世界boss的请求处理都出现了卡甚至超时重连(可钻石复活、可自动战斗)
- 此时的cpu热点都是在challengeBoss上
- 评经验判断是'广播风暴'
- 每一个打boss的玩家要广播伤害给其他所有玩家
- 100人同时打,100 * 100的广播量
- 排查
- 监控发现世界boss期间出口流量极高,达到40M,说明期间频繁广播
- 内网使用robot压力测试,challengeBoss具体逻辑时间耗时打点(战斗、广播、事件、打点),发现广播逻辑非常耗时,即阻塞了业务线程(主要是mina的线程模型,write的大多数逻辑都是在当前线程执行);而世界boss当初为保证原子血量,这个方法还是同步的,即同时只有一个线程可以执行,所以广播耗时将业务线程阻塞,从而玩家的请求开始排队,直到超时
- 解决
- 临时解决方案:世界boss服务增加了一个异步线程池,用来广播,这样避免阻塞逻辑线程,让玩家感觉不卡;内网测试和外网均顺利测试通过
- 其他解决方案-降低广播频率
- 总结
- challengeBoss需要优化,降低锁粒度
- 世界boss引起卡顿的主要原因是这个业务频繁的广播,而如果类似世界聊天这种频率则可以不考虑异步
- 需要检查其他类似频繁的广播业务,后面需要统一线程池
- TODO 直接替换mina,用Netty,netty4的线程模型做了优化,write直接切换到io线程
- TODO 要做优化,考虑带宽的问题
- Q & A
- 世界BOSS建议不要所有伤害都做广播。建议伤害变化固定秒再广播血量及伤害
- 不然客户端渲染也渲染不过来。满屏幕飘字
- 可再伤害时判断上次广播时间间隔是否大于n毫秒。如果大于广播。并更新上次广播时间
- 如果客户端需要飘血。则记录间隔时间最大渲染伤害条数。如果如每秒100条。那就从间隔的条数中随即或者有个算法找出100条。其他伤害不发给客户端
- 可参考某线上事故
- 降低广播范围 分组
- boss总血量定时更 (减少同屏显示玩家)
- 本身玩家伤害同步
- boss死亡时即使同步就行
- 没必要 同屏120个玩家 30左右就可以了;要不然客户端也扛不住
- TODO udp发消息,丢了无所谓
- landon# 总结广播的解决思路
- 降低广播频率
- 降低广播范围
- 异步,避免阻塞业务线程
- 扩展
- mmo#场景aoi解决方案