如下是最近某个项目的一次经历,最终并无按照这样的方案来优化,但对思路确实是一个提升,因此记录在此。mysql
-------------------------------------------------------------------------------------------------------------------sql
项目D为单机服务器,听说在线达到1500后,会很卡,因而想仔细分析了其中的缘由。数据库
总体来讲:C++服务器+mysql数据库,多线程。可是是单服。服务器
请教了前同事,在他的一步步询问下,理清了服务器的当前架构。网络
同事指导,对于服务器性能分析,要从内存分配和多线程两个方面入手。session
修改内存分配策略不但能下降内存,还能减小碎片,最终势必会提升游戏性能(分配阻塞致使性能低)。多线程
使用多线程,将复杂的逻辑异步到不一样的线程去计算,减小了主逻辑的等待,也必然提升了流畅性。架构
线程方面:异步
1 一个socket负责监听全部客户端的session。使用了完成端口的概念,起了3个线程,负责收消息,收到后,将消息放入一个全局的队列revQueue中,这个队列包含全部玩家的全部消息。socket
2 全局的session管理类,管理全部客户端的session。每一个玩家发送消息时,写入本身的发消息队列ownSendQueue中。
3 一个单独的数据库操做队列dbQueue,负责全部对数据库的读取。
4 启动游戏时,开了一个线程,专门负责内部逻辑的刷新。包括各类timer,数据库队列dbQueue的分发,全局收消息队列revQueue的分发(每次轮询到时,会将队列中的全部消息都分发出去),每一个session的发消息队列ownSendQueue,其它游戏内的各类update(血量体力等各类恢复)。
内存分配:
1 会频繁使用到标准库的map,vector,string对象。
2 对自定义的类,有内存池的管理策略。当前策略:
再来看下服务器当前的配置,在线人比较多的一个区服务器,包括三组服务器:
32G内存+10个CPU,每组在线约300人。cpu使用7%左右,内存使用17%左右。
这一系列的分析出来,问题相对而言就明显了。
内存没有达到有效的使用。
逻辑全在一个线程,应该就是整个瓶颈所在了。
针对问题提出的优化策略:
1.内存分配方法
对于已有的内存池策略:
完全的接管内存分配
初步测试,接入tcmalloc后,内存占用由原来的107448降为67108,提升大约40%,可验证对在线的影响。
2.并行计算
以上是在不改变当前单服的状态下,可作出的优化。毕竟单服总有上限,若是以上的优化都不能达到想要的效果,就要拆分服务器了。
增长LoginServer
Gate和Master之间增长LoginServer,或者Gate自己增长LoginServer的功能。
负责:登录验证、创角、角色列表、删角、 封禁IP过滤等处理,其它逻辑交给Master。
增长LogServer,监听Master传送的消息,专门负责和logDB的交互。
上述修改完成后,若是在线依然没法知足,可根据统计数据,逐步拆分出GameGate,GMGate,ChatServer,TaskServer,DBServer。
-------------------------------------------------------------------------------------------------------------------
再次重复下,以上只是某个项目的一次经历,最终并无按照这样的方案来优化,但对思路确实是一个提升,因此记录在此。