【服务器篇】把一款手游服务器从PCU1000调教成PCU18000宝贵经验
去年接手一款大世界跳舞类游戏,性能问题一直困扰团队。游戏运营目标是PCU20000概述通过执行以下命令,可以...
最近公司发行一款高PCU的跳舞类游戏。性能问题一直困扰着这个项目。技术目标是PCU18000,运营目标PCU12000。对于一款手游而言,技术要求算是比较高了。那怎么解决这个问题呢?
一、概述
随着移动网络游戏的发展,玩家之间交互性和实时性要求越来越高,那么先看看我们的需求和目标。
1、运营指标:
- PCU 12000
- 可靠性
- 实时性
- 健壮性
- 可扩展性
- 可恢复性
- 安全性
- PCU:1000
- PCU:18000
游戏服务器架构
这款游戏设计之初就是奔着万人PCU而去的。这是一款分布式架构的游戏服务器,把所有能解耦合的模块都进行了解耦合,以满足计算资源。架构说明:
- gate server 网关服务,可扩展
- router server 系统内部消息路由服务,不可扩展(缺少灾备,待后期扩展)
- monitor server游戏内部监控服务,不可扩展
- filter server关键字过滤服务,不可扩展
- info Server角色基础信息服务,不可扩展
- log server 日志服务,不可扩展
- GM server 游戏管理服务,不可扩展
- Account Server 账号服务,用于登录鉴权,不可扩展
- mail Server游戏内邮件服务,不可扩展
- game server玩家个人游戏行为服务,不可扩展
- group server 游戏内社团服务,不可扩展
- pay server支付服务器,不可扩展
- pay proxy server 支付代理服务器,可扩展
- Scene Server 房间服务器,不可扩展
- stage server 关卡服务器,战斗服务器,可扩展
- DB proxy DB服务器,不可扩展
- Game DB 玩家数据DB
- Log DB 游戏日志DB
1、服务器环境
①服务器部署在阿里云上,使用18台KVM的虚拟机,配置均为8核心16G wwindows server 2008。其中gate服务器为4核心16G内存,100M带宽。
②技术语言:C#
③通讯协议:基于google protobuffer序列化的自定义二进制
④DB:mysql(阿里云RDS)
2、“望闻问切”
①望
超过PCU>1000逐渐卡段现象:
- 登录缓慢,甚至超时;
- 创建房间缓慢,甚至超时;
- 游戏动作同步超时,严重影响游戏体验;
使用压测工具模拟机器人压测,分别模拟1000,1500,2000PCU的case。并自己安装真实客户端体验游戏,记录下来体验不良点。
- 登录偶然超时
- 切线缓慢(游戏内部是分线设计)
- 创建房间,以及游戏卡段,提示“通讯中”
- 聊天卡顿
③问
这一阶段就是和CP的技术负责人商讨系统瓶颈,问题解决思路达成共识。
④切
- 增加gate接口耗时日志
- 增加router主要接口耗时日志
- 增加gameserver主要接口耗时日志
- 增加scene Server主要接口耗时日志
- 增加DB Proxy耗时日志
- 增加stage server耗时日志
- 增加accout server耗时日志
- 使用zabbix对系统各个模块的CPU,内存,IO进行监控和统计
- 增加DB监控(DB使用阿里云RDS)
首先对gate和router以及其他服务器进行系统级别的优化,由于windows是基于注册表机制,参考微软官方文档进行了调优。
TCP/IP方面优化:
- TcpMaxConnectResponseRetransmissions:防止 SYN flooding ,2
- TcpNumConnections:TCP最大连接数,65534
- TcpTimedWaitDelay:TCP复用资源超时时间,30
- MaxUserPort:用户进程可分配最大端口号(5,000–65,534)65534
- TcpWindowSize:TCP窗口大小,65535微软官方参考链接:
https://technet.microsoft.com/en-us/library/cc938216.aspx
https://technet.microsoft.com/en-us/library/cc938217.aspx
https://technet.microsoft.com/en-us/library/cc938196.aspx
https://technet.microsoft.com/en-us/library/cc938219.aspx
3、取证调优
问题一:登录卡顿
①取证
DB Proxy耗时日志发现一个角色注册后会有大量update SQL操作,造成创建角色缓慢,且SQL耗时大于500MS以上。
②分析问题
经过和CP技术负责人讨论,发现由于系统模块较多,一个角色创建会涉及背包,经验,等级等相关属性更改,模块之间只负责自己属性更改,所以造成角色注册后多个update操作,造成注册缓慢。
③提出问题
DB Proxy直接对数据库操作,DB Proxy算法存在问题。
④提出解决方案
对DB Proxy进行改造,
- 增加热数据缓存机制;
- 玩家数据更新使用内存标记,玩家数据增加时间戳,按照玩家延迟落地到数据库,尽量让更新操作平均分布到时间轴上;
- 敏感数据,立即落地;
- 增加“玩家影子”机制(默认时间保留60分钟),再次上线后无语重新从数据库load;
- 把热数据存储到NoSql,redis做主从,可避免此问题(待后续优化)
对登录接口进行性能压测
优化前:
样本数
平均值
最小值
最大值
偏差
吞吐
50000
193
1
617
31
251
优化后:
样本数
平均值
最小值
最大值
偏差
吞吐
50000
206
1
353
45
446
问题二:房间内2%概率跳舞卡死
①取证
Stage Server存在异常日志
②分析问题
异常日志在随机歌曲后,抛出异常。
③提出问题
策划配置数据表格式存在问题
④提出解决方案
策划FIX数据表格式问题
⑤验证方案
使用压测平台模拟机器人进行跳舞,不再出现卡死,掉线
问题三:角色2%概率注册重复
①取证
DB proxy抛出主键冲突
②分析问题
Account Server RoleId 分配算法可能存在漏洞
③提出问题
优化Account Server RoleId 分配算法
④提出解决方案
在高并发时对分配ID加锁处理,避免分配重复
⑤验证方案
使用压测平台模拟机器人注册,不在出现角色重复问题
问题四:游戏大厅频繁TCP广播
①取证
经过逻辑日志以及router流量分析,发现router存在指数级别消息转发增长;
②分析问题
分析可能存在广播代码的逻辑
③提出问题
高PCU时,玩家进入游戏大厅后,会对所有玩家广播,自己状态改变
④提出解决方案
显然这是没有任何必要的消息通知,如果1000在线,那么转发量就是1000×1000的消息量,直接去掉此处转发逻辑
⑤验证方案
使用压测平台模拟机器人进出游戏大厅,发现router IO降低,gate消息队列减少,增加通讯效率
问题五:跳舞房间刷新排序问题
①取证
PCU超过1000后,刷新房间列表,超级卡顿,进入跳舞房间也卡顿,且Game Server CPU飚满到100%
②分析问题
刷新房间算法问题?确认使用冒泡排序,且每次请求,都做一次排序
③提出问题
冒泡排序是效率最低排序算法,切排序时机不对,
④提出解决方案
更改成快排,且有数据变化时再排序(按照1000人算,排序次数从1000000降低到3000,且变化才会排序),
⑤验证方案
刷新房间不在卡顿,PCU可以从1000到10000,且不卡顿,可以流畅游戏
问题六:机器人下线后,存在很多无效空房间,造成玩家卡死在房间内
①取证
增加Scene Server分配房间日志,逐步打印
②分析问题
跳舞房间流程:申请创建房间->系统创建房间->进入房间
发现在系统创建房间后,此时玩家正好下线,逻辑未对玩家状态进行检查,进而导致空房间存在
③提出问题
房间分配逻辑存在BUG
④提出解决方案
增加系统创建房间后对玩家状态检查机制,玩家可能随时掉线
⑤验证方案
多次使用压测工具模拟10000同时在线,压测10分钟,同时掉线,不存在空房间问题
问题七:关键字屏蔽卡顿优化
①取证
开启Filter Server后,系统卡顿,尤其聊天
②分析问题
Filter Server采用主循环单线程模型,未重复利用CPU,过滤算法采用关键字循环监测,效率低下
③提出问题
Filter Server线程模型待优化,过滤算法待优化
④提出解决方案
- 修改Filter Server线程模型多进程多线程模型,充分利用多核
- 关键字逻辑分成,永久关键字(角色名,舞团名字),临时关键字(聊天,房间名)
- 过滤算法变成关键字,首字+扫列表方式存储,大大提高效率
- 临时过滤服务为有损服务,可实时关闭
压测工具模拟PCU18000,5%聊天压测模型,关键字过滤效率OK,满足需求
问题八:gate卡队列问题
①取证
日志打印gate发送和接受队列,发现发送队列阻塞到1000-2000之间,IO峰值到80M
②分析问题
Gate Server把正常逻辑消息和聊天消息放在同一个队列,且消息没有优先级之分,如若存在大量世界聊天广播,势必造成发送队列卡顿。例如:18000在线,5%聊天频率。那么会出现:900×18000=16,200,000消息转发量,当前2个gate,每个gate会有8,100,000消息转发量。
③提出问题
gate转发存在瓶颈,以及聊天消息过大会覆盖正常逻辑消息
④提出解决方案
- 消息增加优先级,聊天消息优先级最低,排在队尾
- 增加gate到4个
压测工具模拟PCU18000,5%聊天压测模型,gate发送队列不存在大量阻塞情况
问题九:心跳检测机制问题
①取证
模拟机器人不发送心跳消息,出现掉线问题
②分析问题
怀疑心跳机制存在问题,gate服务器只是认为心跳消息为有效消息,设计不合理
③提出问题
心跳检测机制存在不合理
④提出解决方案
心跳机制优化成任何为心跳消息,不特定具体某一个消息,客户端可减少心跳消息发送,空闲时再发送心跳消息
⑤验证方案
压测工具模拟PCU18000,不发送心跳消息,不在出现掉线问题
四、优化后
使用压测工具模拟PCU18000跳舞游戏,5%聊天case,不再出现卡顿问题,且router和gate未到达计算资源和IO系统瓶颈,满足上线PCU12000需求。
五、总结
系统最初架构设计是可以满足万人PCU需求。但是由于后期开发人员研发过程没有足够考虑,导致后期上线前各种还债。不过这次优化体现了算法、合理设计、缓存、架构重要性,在以后系统设计和开发之初就好考虑进去,避免上线前期的各种还债。
最后感谢:这次优化历程艰辛,感谢 @点点乐 付大爷,@点点乐-良元 @龙翼 @晁宇 @子青 @丽媛 一起努力才能解决此问题,最后预祝我们游戏《心动劲舞团》大麦~ 大麦~,欢迎大家近期从九游&苹果下载并体验我们的游戏~下周一见~
喜欢的话,就关注一个呗~
关注 游戏技术那些事儿
微信扫一扫关注公众号