netty线程模型运用到自己的项目之中

在如今的部署环境处处充满多cpu如果项目之中不带几个线程都不好意思说自己写的代码可以高效率的执行。特别是在游戏服务端方面的。

那我们先来看看多线程如何在项目中得以进化的。

1,最初的游戏服务器模型的单进程单线程模型

也就是说该模式下的服务链接是当客户端client_1链接进去之后服务器变阻塞处理client_1的业务直到完成返回并关闭连接,这时下一个玩家才能连进来进行操作,说白了跟单机游戏没什么区别,只要第一个玩家不下线,下个玩家就没法连进来,一服一玩家这和单机没多大的区别。

2,线程的引入。了解了单进程单线程模型的弊端之后开发人员开始引入了多线程模型,就是每一个链接进来的用户在服务端都为该链接开启一个线程去执行

如此一来链接之间便不会相互阻塞等待,这样就解决了一服一玩家的尴尬局面。但这又真的完美吗?每当一个用户链接进来就创建一条线程,用户断开链接就关闭线程,线程的开启和关闭带来的性能消耗其实是非常之大的,这是该模式下的一个弊端。还有一个便是一人一线程当人数很多时比如1000人那么就得要创建1000条线程出来处理,而一个服务器不可能提供那么多的线程给你使用,相反如果线程数量过多其线程的上下文切换与其线程开启关闭带来的性能消耗远大与多线程带来的好处。

3,引入线程池。线程池的引入就是为了解决开启、关闭、线程过多等问题。线程池顾名思义就是提供一个池子里面装的都是线程,,线程的开启、关闭都由线程池来处理,但线程池中的开启关闭线程并不是真的开启和关闭,而是一开始的时候就为线程池初始化一定数量的线程,当有用户的链接和操作时都只能共用这池子中的线程,每当有客户端进来就到池子中拿到当前空闲的线程来处理,这个也就对应了线程的创建步骤,而当每个操作完成或者有用户关闭链接时就将线程回收放入线程池空闲着,这一步就对应了线程的关闭,以此循环利用,如果当前线程池里的线程被用完后面的链接或者操作就会被阻塞等待空闲线程。这也就解决了线程开启关闭,数量过多等性能问题。

到目前为止很多的项目依然采用这种线程模式。

4,netty线程模型,

那既然线程池为我们提供了那么多便利为什么还要讲netty的线程模型呢?

在这里我们就不得不引入线程数据安全这个在多线程中无法避免又处处存在的话题,我们先来看看2和3在线程安全问题上是怎么处理的?

2的模式下因为一个用户链接就创建一条线程,也就是说该用户从链接到关闭这整一个过程所有的操作都只有一条单独的线程来服务,我们知道单线程执行是不会出现线程数据安全这么个问题的。但弊端我们在讲模式3的时候已经列取1~2,这里没必要重复,那模式3呢,模式3并不是每个客户端都为其开一条单独的线程。而是所有的链接所有的操作都是随机从线程池中拿出一条当前空闲的线程来服务。这就有什么问题呢?比如同一个玩家同时发送了两次服务请求,一个是减金币,一个是加金币。而到达服务端之后这两个操作很大的一个几率是不会同时获得同一条线程来对其进行操作。这时问题来了减金币的线程正要往下操作此时cup突然把线程执行权给到了加金币的线程,同一时间两条不同线程对同一数据进行操作这问题不就来了吗?于是netty根据模式2和3各取之间的优点进行了改良也就是一个用户在链接之后所有的数据读取操作都只分配到一条线程之中,而一条线程又可以执行多个用户链接的串行操作,看图。

我们会看到六个用户链接共用一个里面有两条线程的线程池,而这又是怎么分配的呢?看下带颜色的连线我们会发现当用户链接进来的时候netty会均匀的从线程池中取出一条线程进行分配,不管当前线程是否空闲。这样一来线程1以后就专门为用户1,3,5的所有操作,注意这里是所有操作,所有操作,所有操作进行服务,而线程2专门为2,4,6用户的所有操作进行服务,这样一来每个用户从链接到关闭过程中的所有操作都有且只有一条线程为其进行服务,这来也就解决了线程数据安全这一问题,又引入了线程池管理线程这一机制。看到这里是不是感觉netty棒棒达?

简单点,说话的方式简单点,netty线程模型简单来说就是一条线程服务多个链接,一个链接只有一个线程服务。一对多,多对一?

这一节我们先讲讲理论,下一节我们就上上真机贴贴netty线程模型应用到项目中的代码吧!

最后 如果有什么地方讲的不对,你们来打的呀!^_^

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180523G0OGMK00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券