1.前言

掉线是令每个网络游戏开发人员头痛的问题,太频繁的掉线会影响玩家的体验从而影响到整个游戏的口碑。御龙在天是琳琅天上工作室自研的一款国战型的MMO网络游戏,在2012年公测初期,御龙服务器全体开发人员也被掉线这一问题困扰,通过大家长期坚持不懈的定位,掉线问题逐渐下降,给了玩家一个好的体验,获得了玩家的肯定与喜爱。

2.定位工具

御龙在天是基于互娱的tsf4g框架开发出来的,我们就是使用tsf4g里的tconnd作为链接层。Tconnd如果检测到链接层的异常,它就会给gamesvr发回一个TFRAMEHEAD_CMD_STOP消息,我们就是在gamesvr中接收和处理这个消息,并记录玩家掉线的日志。这些日志对于判断玩家掉线的原因非常有用。

在服务器上抓包,就是使用tcpdump命令。但是现在服务器端都接入了tgw,导致要抓特定玩家的链接的包变得困难了。

另外,有时候需要在玩家的电脑上进行抓包分析,刚开始时我们是通过QQ远程操作玩家的机器,安装WireShark并进行登录抓包,但是这样操作效率比较低,所以后面我们基于winpcap开发了一个御龙专属的抓包工具,玩家只需要直接运行这个工具,就可以抓到和御龙客户端相关的所有链接的包,并保存成文件。玩家只需要把生成的文件发回给我们,我们就能分析到玩家的网络状况。

3.经典掉线问题分析

由于国内的网络比较复杂,所以掉线的原因五花八门,像一些某地区的网络波动导致的掉线我们就不进行描述了,下面主要是挑选了我们遇到的2个比较经典的掉线问题进行分析,希望能对其他项目有些启发作用。

3.1 跳zone引起RST

御龙在天的定位是一个大型的国战类游戏,一个服是由9个国家组成,每个国家有N张地图,单服需要支撑7万人同时在线。由于它宏大的世界观,所以我们使用了机器集群的方式,图1就是御龙的单服架构图的简单表示。(如果想详细了解御龙的后台架构,可以在KM上搜索alancai的《御龙在天服务器性能优化小结》以及rosickyxiao的《御龙后台架构演进之路》)

图1

如果玩家要从一个国家到另外一个国家,那在服务器端就是需要从Zone_A切换到Zone_B。切zone流程是这样的:

(1)Zone_A通过world_login转发一个切zone请求的SS消息到Zone_B;

(2)Zone_B到对应的Tconnd_B上请求预分配位置,Tconnd_B如果预分配成功,就把相关的信息返回给Zone_B;

(3)Zone_B通过world_login把这些信息返回给Zone_A;

(4)Zone_A把当前玩家的数据回写DB并且组建一个通知包,把预分配信息下发给客户端,并同时通知Tconnd_A断开和这个玩家的链接(即在这个通知消息的TFrameHead中带上TFRAMEHEAD_CMD_STOP标记);

(5)客户端收到这些预分配信息后,就会使用这些信息去重连Tconnd_B,从而实现了跳zone,到达另外一个国家。

在御龙公测初期,外网一些玩家报出国偶尔会掉线。经过分析,他们都是被断开了当前zone的链接,但并没有连到新的zone上去。通过在玩家的机器上抓包分析,发现玩家是收到了一个RST包,并没有去重连新的zone。通过与tsf4g的同学一起定位和模拟试验,发现如果是服务器主动关闭链接,而这时候这个链接的发送缓冲区里还有消息没发送,应该是会把消息发送完之后才完全关闭的。但是如果服务器主动关闭后,这时候如果客户端还有消息发送上来的话(因为客户端不知道服务器已关闭,并且服务器关闭时客户端可能有些消息正在路上),那么这个TCP链接就会清掉发送缓冲区里还没发送的消息,并且直接给客户端发送一个RST,导致客户端没接收到最后那个跳zone通知包,而导致掉线。

对于这个问题,tsf4g的同学给我们的建议是让客户端来主动断开链接。但是由于御龙服务器的一些特性,我们最后并没有采用他们的建议,而是使用了下面的2种改进措施:

(1)在跳zone开始的时候(即上面的第(1)步),服务器先给客户端发送一个准备跳zone通知包,客户端收到这个通知包后,就把玩家锁定不给操作,并且不再发送消息给服务器。如果客户端收到服务器的跳zone错误通知包,或者超时了还没收到服务器的跳zone通知包,那就给玩家恢复正常,玩家可以继续在本zone进行游戏;

(2)给玩家发送跳zone通知包时(即上面的第(4)步),不要同时断开这个玩家的链接。为了节省内存,我们依然是把玩家的数据回写并且从zone的共享内存上释放这个玩家的对象。但是把这个玩家对应的TFrameHead信息保存下来(TFrameHead相对比较小),延迟一两秒后才加上TFRAMEHEAD_CMD_STOP标记并发送给tconnd,让tconnd断开相关链接。

做了上面2步优化之后,通过统计全服的掉线日志,发现由于跳zone而引起掉线的问题已经变得很少了。依然存在的那小部分跳zone掉线,就是玩家的网络条件比较差,是属于不可避免的问题了。

3.2发送缓冲区满

另外一个有意思的掉线问题,是我们服务器内部人员在新服体验游戏的时候发现的。跟踪掉线日志,发现是tconnd检测到链接的发送缓冲区满而主动断开的,同时在tconnd的日志里搜到这样的记录:

(tconnd_sendto_lisinst)] Inst[1922] of uin[173801489] send package to client [183.58.222.148:55696] failed!datelen[1282],iRet[1224],errorstring[Success]

从上面的日志可以发现,tconnd要向客户端发送长度为1282的消息,但调用send只发出了1224个字节。但是tconnd是不做消息缓存的,所以它就粗暴的断开链接并且给zone返回一个错误消息。

发送缓冲区满,我们立马就想到2个原因:(1)发送缓冲区太小;(2)玩家网络太差,丢包或延时严重,导致已发送出去的包得不到及时的确认。第(1)点马上就被我们否定了,因为我们在tconnd.xml里配置的发送缓冲区是1M,见图2(a)。如果传入的值(1049000)没有大于允许的最大值(图2(b)中的4194304),setsockopt函数会把缓冲区设置为传入的值的2倍,即1049000*2=2M。2M的发送缓冲区是足够的。至于第(2)点,我们是在公司登录游戏的,网络不会差,同时也ping过,发现延时很小。

(a)

(b)

图2

接着,我们关注到了机器的内存使用情况,发现zone所在的机器(老C1)的内存使用到了7点多G,几乎用完了。由于每个链接的发送缓冲区空间不是在创建链接的时候一下子分配出来的,而是在使用过程中逐渐增大的。当时就怀疑会不会是由于内存紧张,导致某些链接扩大发送缓冲区失败,导致只能在当前剩余的发送缓冲区上发送部分字节?或者是由于内存不够,而底层的系统调用也需要内存,需要等待SWAP OUT获得新内存使得处理速度变慢,导致缓冲区满?针对这2个疑问,当时google查了一些资料以及咨询了tlinux相关的同事,但是都没得到确定的答案。于是我们就决定把几台8G的老C1机器替换成16G的新C1机器,再观察对比下效果。

图3就是最后对比出来的结果,其中标红的zone2、zone6、zone12、zone16就是替换成16G的新C1。第3列的数值,是一整天里由于发送缓冲区满而掉线的数量。可以看到,换成16G的新C1后,这个掉线数量的确是减少了很多,一个zone一整天才几十个掉线,这个数量是比较令人满意的。

图3

正当我们沉浸于以为找到原因的快乐的时候,一个系统参数走进了我们的视线。图4(a)是老C1机器的参数,图4(b)是新C1机器的参数。在net.ipv4.tcp_wmem里有3个数值,分别表示TCP发送缓冲区的最小值、默认值以及最大值。但是有另外一个参数net.core.wmem_max在新老C1机器里是不同的。这个参数是什么意思呢?

(a)

(b)

图4

通过写了个小代码进行测试,最后发现在setsockopt设置SO_SNDBUF时,net.core.wmem_max是替换了tcp_wmem里的第3个数作为最大值限制的。那这个问题的根本原因终于浮出水面了,是系统参数给限制住导致没能成功的把发送缓冲区设置为2M。虽然在tconnd.xml里配置了SendBuff为1M,但在setsockopt的时候,是不可能把发送缓冲区大小设置为2M的,因为net.core.wmem_max限制了传入setsockopt的参数不能超出131071。所以最后设置的发送缓冲区大小只是131071*2=262142=256KB。只有256KB的发送缓冲区,肯定是不能满足一个MMOG的要求的。于是我们另外找了几台老C1机器,把这个系统配置改成2048000,再对比下,见图5。其中蓝色的zone1、zone7、zone11、zone17就是把net.core.wmem_max设置为2048000,可以看到修改参数后,这4个zone由于发送缓冲区满引起的掉线马上减少了很多,和16G的几个zone达到一样的水平,从而确定了是系统参数的问题。

图5

4.结束语

经过御龙服务器全体人员坚持不懈的努力,现在御龙在天的掉线已经比较少了,玩家可以在游戏内得到好的体验。这是御龙服务器全体人员共同努力的结果,我只是负责整理,如果有疑问可以咨询我或者御龙服务器其他人员,谢谢!

御龙在天掉线问题定位过程相关推荐

  1. 腾讯游戏4名技术专家详解:《御龙在天移动版》服务器性能优化

    本文作者:蔡铭福.刘林.杨岳军.向熠 一.游戏介绍 <御龙在天移动版>是一款3D MMORPG手游,以三国为背景,移植<御龙在天端游>经典玩法,主打手机上的实时万人国战,同时通 ...

  2. 御龙在天怎么找回服务器,御龙在天手游人物找回 误删的角色如何找回

    我们在玩游戏的时候,有些时间我们的游戏人物会被我们误删掉,在我们给家里的小孩玩的时候,一步小心我们的人物就没有了,或者我们的账号在被盗,会被别人删掉我们的角色. 还有我们在升星的过程中升不上去,就会生 ...

  3. MIPS架构下LW指令的重定位过程

    通常我们不会去关心指令重定位(relocation)的细节,编译器的ld过程已经帮助我们做好了.由于最近在移植CRIU,涉及到指令的重定位计算,不得不细细研究代码重定位的细节知识.之前的文章介绍了MI ...

  4. 御龙在天找回以前的服务器,奋起直追!掉队系统找回经验

    在<御龙在天>手游中,等级才是最非常重要的,等级越高也就能装备更高级别的装备,并且开启的功能玩法也越多,从而使得战斗力遥遥领先.在游戏前期升级还是很快的,这时候等级差距也不明显,然而到了后 ...

  5. 御龙在天手游怎么不显示服务器了,御龙在天手游进不去怎么办 闪退原因及解决办法...

    御龙在天手游进不去怎么办?闪退原因及解决办法.御龙在天手游今天迎来了安卓平台的不删档不限号测试(游戏出现打不开的问题,下面就让小编为大家介绍一下出现这类问题的原因及解决办法吧! 1.服务器问题 游戏早 ...

  6. AIX 关键系统文件被清空问题定位过程全记录

    问题描述 某日接到客户反馈,某系统备机重启后 telnet 无法登录,提示信息如下: telnet (testlpar1)telnetd: /bin/login: Cannot run a file ...

  7. python语法元素测试_基于python全局设置id 自动化测试元素定位过程解析

    背景: 在自动化化测试过程中,不方便准确获取页面的元素,或者在重构过程中方法修改造成元素层级改变,因此通过设置id准备定位. 一.python准备工作: 功能:用自动化的方式进行批量处理. 比如,你想 ...

  8. 业务模块卸载失败定位过程

    模块卸载失败定位过程 查看服务状态 查看卸载进程状态 查看进程栈信息 查看卡住的工作队列 查看异常工作队列进程栈 强制产生core文件并使用crash工具打开 研究lock信息 设备重启服务会先卸载业 ...

  9. 御龙在天以前服务器信息,细数御龙在天的名人以及其崛起的服务器

    N0.1 皇族天赐(御龙抬头):天赐的财力可以说是有目共睹的,可以说是一掷千金,在统一御龙抬头.收购花大仙之后光荣退服,乃御龙最强公会之一创始人 NO.2 CHINA宝哥(一统江山):宝哥可以说是很早 ...

最新文章

  1. VS2013\VS2017 使用git 总是需要输入账号密码
  2. GPT-3说:马斯克是世界最强的人,但没有他人类会更好
  3. OpenCV 4.0 Dis光流算法 运动检测
  4. 详解mysql数据库的启动与终止_详解MySQL数据库的启动与终止(一)
  5. TCP面向连接中的“连接”和“可靠”与“不可靠”
  6. Unicode 属性类
  7. 解决sklearn.metrics指标报错ValueError: Target is multiclass but average=‘binary‘. Please choose anothe...
  8. 【Flink】Flink的窗口触发器 PurgingTrigger
  9. PHP中的pack和unpack函数
  10. MySQL 5.7 忘记密码
  11. postman 测试http post的json请求
  12. 【驱动安装及keil使用】win10 stm32 stlink驱动安装,检测不到芯片,下载不了程序
  13. 抖音养号脚本源码分享
  14. 黎曼 zeta 函数与黎曼猜想
  15. 基本SQL命令表命令
  16. mini2440 -- TFTP方式下载u-boot
  17. 7-10 黑洞数(20 分)
  18. 计算机考研什么时候开始备考,2022考研什么时候开始准备最好 为什么
  19. java开发微信公众号图片上传功能,不吃透都对不起自己
  20. iOS开发 关于tableView加载图片时出现卡顿时的解决办法

热门文章

  1. vi/vim下字符串搜索
  2. 博客开篇 -- 每个程序员都是一位肆意江湖的游侠少年
  3. Android中Paint画图(线、虚线、矩形、多边形、圆形、曲线、半圆、三角形、旋转文字)
  4. Photoshop CS2 视频教程-PS污点修复画笔工具(转)
  5. 都9012年了,你还在手动部署代码吗
  6. JavaScript6、7、8、9、10、11新特性
  7. Echart折线图横坐标时间获取
  8. 煽情的儿子554=随笔
  9. python中decimal用法详解
  10. ZZNUOJ_C语言1018:奇数偶数(完整代码)