记录《QMWS》服务器性能优化过程

作者: NickYang 分类: 技术文章,程序开发 发布时间: 2015-11-13 16:26
性能优化(图片来自网络)

性能优化(图片来自网络)

本文是为了记录下《QMWS》项目服务器在对外测试期间,性能表现和技术审核时的性能表现差距很大,从而做出的一些优化过程,期间还是比较头疼,接近两个连续通宵来修改。第一个通宵一直在查找问题和猜问题,找问题是如何出现的,第二天主要是解决对应的性能问题。

性能问题主要集中在:

内存使用过快

内存泄露

某些时间内协议过多

逻辑功能处理不当

其他网络消耗什么的暂时也没有考虑,下面详细说说这几个问题是如何引起的以及如何一步步解决的。

1.内存使用过快问题

我们项目使用的是C++后端,用了团队主程之前写的,后来我参与开发的一个开源的服务器数据管理框架NFrame,下面是github地址。

GitHub 仓库挂件 WordPress 插件

ketoo / NoahGameFrame

A fast, scalable, distributed game server framework for C++, include actor library, network library,can be used as a real time multiplayer game engine ( MMO RPG/MOBA ), which support C#/Lua script/ Unity3d, Cocos2dx and plan to support Unreal. BBS: http://bbs.noahframe.com

http://noahframe.com/

这个框架就不多做介绍了,有兴趣可以从github pull下来研究研究,或者加群讨论。

这个框架的主要问题就是小的变量和内存申请太多了,导致产生了很多碎片,在linux系统上回收不够及时导致的,而且我们错误的估计了shared_ptr的能力了,智能指针确实能减少很多内存管理,但是生命周期却不好把握,所以我们临时用了大google的TCMalloc,每5分钟主动回收一次内存,确实解决了我们的问题。

2.内存泄漏

内存泄漏这块主要的问题还是代码上的漏洞,逻辑不够严谨,释放对象的时候因为一些判断导致对象没有被释放。还有就是一些数据管理上的问题,不是特别严重。

3.某些操作下逻辑处理过多

因为NFrame采用的是事件回调的方式来处理数据变动,我们会在自己感兴趣的属性(Property)和表(Record)数据上注册回调函数,从而做一些逻辑。这个时候就得特别注意逻辑需求了,因为某些时候属性会有多次变化,导致多次计算其他属性,我们遇到的问题就是当属性变化时计算多个武将的战斗力,如果某个操作导致了多个属性变化,就会导致成倍的战斗力计算,加重了逻辑负担。修改方式是去掉部分回调,在逻辑操作中特定的时候处理回调做的事情,从而降低调用次数。

4.逻辑功能处理不当

这个就是一些常见的问题了,经过重构整理以及性能测试就可以很好的看出来问题,就不多说了。

 

推荐的一些工具:

VLD C++内存泄漏检查工具

VTune C++性能内存检查工具,完美和VS IDE结合,非常好用

Valgrind linux下内存检查工具,缺点是没有IDE环境,报告不太容易看,不过分析还是蛮准确的

Border check(DevPartner) 自动化测试/覆盖性测试工具,大borland(估计很多人都没听过了)出品,业界一流产品

 

好的结果是问题基本已经排查到了,所以后续的版本测试基本没有特别大的性能问题,不过还是得争取高的压测结果。

PS:线上环境和本地测试还是有很大差距,前些天看到一个测试方法,觉得很有意思,与大家分享下。是通过线上开一台功能服务器A,然后再开一台同样的功能服务器B,A和B做的事情完全相同,A是对外服务,B是内部测试服务器,A多做一件事情,将收到的消息顺便转发到B,B再按照收到的协议做处理,这样通过观察B的数据和性能就能模拟线上环境,从而更容易发现问题处理问题,这个东西github上也有对应的项目,叫TCP Copy,有兴趣的朋友可以看看。

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

4条评论
  • freeeyes

    2015 年 11 月 18 日 08:57

    内存碎片主要是在运行期的new 和delete,以及使用STL容器类而产生的碎片堆积。可以根据不同的类型去做优化处理,比如,内存池,关于内存泄露,可以用这个表述出来。至于内存溢出,要防止开发过程中使用非内存边界检查的API,可以规定开发使用的API必须是有边界封装的函数。不建议过多的使用服务器间的调用,诚然,这是中间件提倡的方法,但是这样的模式弱电室对及时类消息的相应速度完全取决于你的内部IO,关键的数据放在共享内存中,这样就算服务器core了也不需要重新从IO获取,剥离数据同步存储为独立进程,这样不管游戏服务是否有正常,数据都会得到同步。游戏服务只提供数据的读写和类型转换(逻辑)即可。
    一直关注你们的服务器,写的挺好的。和我开源的一组服务器有很多一样的想法,赞一个。
    有机会可以一起学习讨论一下技术。

    潜水 Chrome浏览器 Windows 7
    1. eliteYang

      2015 年 11 月 18 日 09:40

      你说的不错,我们主要是new和delete用的很少,大部分在用智能指针,在windows下还好,linux下确实是小数据申请频率太高了,所以才会出现这个问题。大家多讨论,先去看看你的开源服务器。

      站长 Chrome浏览器 Windows 7 x64 Edition
  • 李阳博客

    2015 年 11 月 15 日 09:45

    服务器优化这个东西,我也只有优化过Nignx,对于其他的还在摸索中

    冒泡 Chrome浏览器 Windows 10 x64 Edition
    1. eliteYang

      2015 年 11 月 15 日 22:55

      我们是游戏服务器,自己写出来的问题,只能自己摸索,没有别人的经验可参考。

      站长 Chrome浏览器 Windows 7 x64 Edition

发表评论

电子邮件地址不会被公开。 必填项已用*标注