• Netty游戏服务器消息分发技巧(channelRead处处理)


    背景:

            不像node.js是单线程的,我们使用netty都是多线程架构,但是写业务逻辑,其实我们是希望单线程的。

            因此我们需要根据模块进行相应的消息分发处理,那就是从channelRead处下手做好分发。

            hash映射这种,除了临界情况,其实尽量不应该在业务层出现,除非是到玩家线程的一些(如:房间结算),否则不需要手动映射。

    阅读pomelo项目的启发,其实游戏都是有一个模块号的,可以根据模块号做好具体的分发,业务代码写的时候,就可以保证完全按照单线程的逻辑写即可。在zfoo中,其实就是根据玩家请求过来的packet,就可以得到module的name,知道这个请求属于哪个模块。那这个玩家的请求到底投递到哪个线程呢?

    1)以斗地主为例子:

            1.登录前的模块 "auth":

                    这个是:在登录账号前,还没有uid时。也就是:拿着account进行登录,此时是直接取

                            account这个账号作为执行线程。

                            TaskBus.addTask(account, ()=>{  这写操作db的逻辑 } ),这样子保证玩家不管怎么登录,都是串行处理,避免一下子同一个账号搞进来2个连接。

            总结:先采用默认的sid做路由进入到handler内,执行业务逻辑时,根据accountId做路由。

            2.玩家相关的模块 "player":

                    这个模块处理的都是登录过后只处理个人数据的业务,如:每日登录、引导。

                    此时都在路由层处理好,

                    总结:根据uid进行映射到指定的线程。

            3.匹配相关的模块 "match":

                     匹配一般只有一个线程,这样子处理就可以完全无锁化,也无需使用加锁。

                    但是,匹配成功后要创建房间,此时要先生成房间号,生成房间号可以用内存原子变量,一旦生成房间号后,就可以根据房间号进行操作,往房间管理里面添加room等可以到房间线程执行。

                    总结:单独独立出来一个匹配线程进行逻辑处理。之后的临界情况:确定下来roomId后就到roomId指定的线程执行。

            4.房间相关的模块 "room":

                    此时都是房间内的逻辑,从玩家Session上要绑定好房间roomId,此时所有的请求都路由到房间线程即可。 也可以将房间线程单独开辟一个房间线程池,这样子就完全没有db操作,会更快一点。 结算之后,再把结果放到玩家线程中进行db相关的处理:

            TaskBus.addTask(uid, ()=>{  这写操作db的逻辑 } ),这样子保证。

            总结:房间内逻辑用roomId做路由,结算等涉及多人信息的,采用uid做路由,在里面修改个人数据库。

    2)好处:

            无需大部分情况下,无需进行手动hash映射(登录前、房间内结算每个人信息相对特殊)

    3)要写好单进程多线程类的游戏逻辑

            大部分都是分区分服类的游戏,因为方便游戏运营。

            一个12c32g内存的游戏服务器,那已经可以支撑很多人了,其实jvm堆内存也要求不可超过32G,JAVA堆大小不要超过32GB!!!_占小狼的技术博客_51CTO博客

    ----------------------------------------思考--------------------------------

    经过上面的分析可以看出来,很多业务中都会存在一些临界情况:

            如:登录前不知玩家uid,登录后确定下来玩家uid,但是分配uid和初始化uid对应的玩家数据此时是在登录前的这个线程中。那么后续的存储操作可以提交的uid的线程中。

          还有:处理创建房间的handler,此时还没roomId,那么分配roomId和存储这个new出来的Room这个操作也是在默认在创建房间的线程中。那其实后续的操作可以提交到房间线程中。

  • 相关阅读:
    【深度学习21天学习挑战赛】2、复杂样本分类识别——卷积神经网络(CNN)服装图像分类
    解决Mysql和redis缓存不一致问题
    PPTP、L2TP、IPSec、IPS 有什么区别?
    套接字介绍
    Gamefi与DeFi之间有什么关系?
    Fiddler三种方式改包
    C语言刷题(一)
    软件产品(确认)有效性测试的作用和流程
    大一作业HTML网页作业 HTML校园篮球网页作业(12个页面)
    【献给过去的自己】栈实现计算器(C语言)
  • 原文地址:https://blog.csdn.net/themagickeyjianan/article/details/126034507