游戏服务器启动多少个线程合适

 二维码 119
发表时间:2018-10-20 00:16

线程是服务器的一种希有资源,它的创建,销毁,切换都需要很多服务器的其它资源。而在游戏服务器中,只要没有在多线程之间有共享数据的操作,都是可以并发的,即可以是多线程操作的。比如不同用户各自的操作处理,或同一个用户的数据更新到数据库的操作等等。那为了提高并发性,是不是线程越多越好呢?多少才合适呢?先不说游戏服务器的特殊性,就按普通的服务器业务来说,最合适的线程数是多少呢?说到线程,那一定是和cpu核数相关的。在其它的文章里面,我们可以看到这样的结论:


一般说来,大家认为线程池的大小经验值应该这样设置:(其中N为CPU的个数)

如果是CPU密集型应用,则线程池大小设置为N+1

如果是IO密集型应用,则线程池大小设置为2N+1

但是,IO优化中,这样的估算公式可能更适合:

最佳线程数目 = ((线程等待时间+线程CPU时间)/线程CPU时间 )* CPU数目

因为很显然,线程等待时间所占比例越高,需要越多线程。线程CPU时间所占比例越高,需要越少线程。

下面举个例子:

比如平均每个线程CPU运行时间为0.5s,而线程等待时间(非CPU运行时间,比如IO)为1.5s,CPU核心数为8,那么根据上面这个公式估算得到:((0.5+1.5)/0.5)*8=32。这个公式进一步转化为:

最佳线程数目 = (线程等待时间与线程CPU时间之比 + 1)* CPU数目


综上所看,线程数并不是越多越好,而是要适量。比如如果游戏服务器是使用netty开发的,那么boss线程一般1~2个就足够,而work线程可以根据服务器配置和上面的公式算出最合适的线程数。我们知道,在netty的业务操作中,也就是Channel的Handlerr操作中,不应该有IO操作,因为IO操作时间长,而所有的channel是共用work线程的,如果有IO操作,就会卡往其它的请求处理。所以一般来说,游戏服务器中的数据应该提前加载到内存中,这样即可消除IO操作。

那么问题来了,游戏服务器中不可能没有IO操作,比如登陆时数据库的查询,部分重要数据的即时更新到数据库,或向其它服务发送http请求等等。这该怎么处理呢?其实我们发现,这些操作都是可以并行的,他们之间没有依赖关系也没有共享数据,即没有什么顺序要求(当前同一个用户的对数据库的操作应该是有序的,同一个用户的操作应该放到同一个单线程池中处理,当然多个用户可以共用这个单线程池,使用netty的线程模型即可,EventExecutor)。所以我们可以把这些操作放到一个线程池中。线程池的数量和每个线程池中的线程数我们可以很好的把控。这个可以封装到服务器的框架里面。



技术交流,欢迎留言,也可添加QQ交流群:66728073,197321069