探讨游戏服务器压力的三座大山——数据库、网络以及系统资源(2)

贴上原文地址:http://blog.csdn.net/gz80/article/details/7410695


然后探讨一下网络端的压力。

服务器是玩家数据的交通枢纽,客户端所有数据包都在这里汇集,并由这里分发出去。特别对于网游服务器来说,其最主要的压力就是来自于网络流量,情况严重时会导致服务器相应缓慢,甚至卡死。

网络流量就是像风一般的男子,残酷地摧毁了服务器的优雅。当繁华落尽,尘嚣散去时,只留下你如烟花般寂寞……(呕吐中)


(1)钟山风雨起苍黄,百万雄师过大江——应对大量网络连接资源竞争。
我们曾经遇到一个问题,当开新服导量的时候,大约过了两个小时,登录就很不稳定。有时会卡死,但刷新一下有时就好了,但失败的几率依然高企。
后来我们发现建立的TCP连接数超高约8千多个。我心里的第一个想法就是遭到了TCP SYNC Flood洪水的DDoS攻击。但是查看链接源地址,没有规则的分布,而且又觉得新平台上的新服应该不会这么引人瞩目被枪打出头鸟吧。
直到后来通过询问平台导量方式后才得知他们是弹出窗口式的,而我们游戏客户端机制就是在弹出页面时就已经建立好了TCP连接。
这样就导致很多用户只是弹出窗口,但什么都不操作,不关闭窗口一直挂着,而服务端也一直维持着这个连接,这样就形成连接数爆炸的问题了。
后来我们做了心跳检测机制,在弹出页面不发送心跳包,让它超时断开释放连接。这样同时也能防止某些简单类型的DDoS攻击。

(2)让领导先走——数据包分优先级处理
在我们进行压力测试时,发现在密集的地图中数据流量非常大。通过数据包统计分析,原来在RPG类型游戏中,玩家移动的数据量占很大比例。
比如某玩家视野内有N个其余玩家,那他的移动信息要广播N份,如果每个玩家都在移动,那么移动信息就要广播N*N份,形成恐怖的广播风暴。
针对这种情况,我们对数据包进行优先级划分,分为移动信息队列和命令信息队列:
视野内其他玩家的移动信息优先级低,即使被丢弃也不会对玩家的游戏功能使用上造成错误。
命令数据包优先级高,因为如果数据包被丢了,会导致前后端的状态信息不一致,以至于某些功能使用出错。

在平常状态下优先发送命令包,然后才发送视野内其余玩家移动信息包。
当网络数据产生拥塞时,先尽力发送命令数据包,再循环增量地尝试丢弃移动信息包。当命令数据包发送缓存队列也被塞满时,说明该用户的网络状况非常差,很多命令数据收不到,再玩下去也没意义了,只能强行将他断线——大家好才是真的好。

(3)落红岂是无情物,化作春泥更护花——利用数据包环形队列以减少垃圾内存
在使用C++程序时,一个压力环节是来自频繁的系统调用。像new和delete这样的操作,都要向系统申请和释放内存空间,同时会产生内存碎片,严重时会触发系统内存整理。
这种情况在对socket数据包处理时特别严重,因为预先无法估计数据包的大小,所以一般都只能临时根据当前数据包长度向系统动态申请。
为了解决这个问题,我们就设计了一个socket buffer的环形队列,然后定两个浮标——读浮标和写浮标,先写再读,一追一赶。
这个环形队列在账号对象创建时就向系统申请内存,长度给一个默认值,不够用的时候再扩展。这就是类内存池的一个做法。

(4)人有悲欢离合,月有阴晴圆缺——数据包的分分合合
在Mongos系统中对socket数据包发送有一个合包处理,就是把多个数据包合并在一个buffer中再一次过调用send发送出去;在收包时也有对数据包进行分离解析。这种做法是为了减少系统调用,以及额外的网络开销。
众所周知,在校车接送孩子的时候用一辆大车一次性运输所有人,比用一辆小车分多次来回运输的效率高。
当前网络设备的最大传输单元——MTU是1400字节,而我们游戏内容数据包一般不过上百字节。所以尽量把数据包合并发送以减少系统负担。
当然,合包发送时也要注意延迟问题,我们在程序中设定约50ms一循环来发送buffer中累积的数据,也就是玩家数据堆积最多不超过50ms,一般玩家感觉不到这种延迟。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值