转自http://www.zhihu.com/question/23323557
另一篇好文章http://blog.csdn.net/pi9nc/article/details/17336695
请教一下关于网游服务器网络层IO多线程效率问题?
只是想问下效率问题,有以下几种方案,还有请问下怎么测试效率:
1.只用一条线程收发数据包。
2.一条线程收,一条线程发送。
3.一条线程收,多条线程发送。
还想知道的是现在网游服务器一般会用哪种模式?
我做网游服务器几年了,下面主要是经验之谈(主要是端游服务器这块)。一般来说国内开发游戏服务器常用 TCP 协议,所以下面都是基于此来谈的。
如果是选择 IOCP(proactor),网络 IO 可以在多个线程进行(IOCP 可以设置等待 IO 完成事件的线程数),这些处理实际网络 IO 的线程我叫它们网络线程,游戏的逻辑线程和网络线程可以通过共享内存来交互,也就是说,逻辑层需要发送消息时先将消息送入和网络线程共享的内存,网络线程则从共享内存中读取数据发送,反之亦然。
如果是选择 EPOLL(reactor),可以使用上述的类似做法,但是和 IOCP 不同,其只能存在一个网络线程来负责连接建立和网络 IO,著名的开源项目 libevent 在其基于 buffer 的那套接口上就使用了这样的做法(也就是其 v2 引入的那套新接口)。另外一种做法是使用一个线程来负责连接的建立,然后使用多个线程来负责实际的 IO 操作,这种做法在 memcached 的网络部分可以看到。回到游戏服务器上来说,一般而言,这些做法都能够高效完成任务。在一些存在 gate(专门负责处理客户端连接的服务器或者组件)的设计中,在 gate 上常常用一个线程接受连接,多个线程处理 IO 的做法,而那些被屏蔽在 gate 之后的服务器之间则直接可以用 select 之类的模型了(通常来说服务器之间的连接数很少)。
除此还有一些做法,但是在我实际工作中所见不多,这里也就不多说了。网络层的效率除了和选择的 IO 模型,选用的具体结构等因素相关之外,还需要注意实现的细节,不同的细节处理可能让性能差距拉的很大。
网游中因为gate层会涉及大量的广播发送,效率的最高的方式是第三种。在传奇类的2D游戏中经常会出现400玩家同屏的情况,如果采用单线程发送,会导致大量的堆包,导致严重的卡顿情况。
至于怎么测试,自己做压力就可以了。实现最简单的gameserver + gateserver,然后通过模拟客户端发送广播包,关注网络层的队列的大小和发送TPS就可以了。