【从零开始学Skynet】实战篇《球球大作战》(十五):项目问题和改进

1、问题:在客户端发起登录协议后,在登录协议返回之前客户端下线。由于此时agentmgr记录的是登录中状态,下线请求不会被执行,除非再次登录踢下线,否则agent会一直存在。这种情况不常出现。

     解决:方法是让gatewayagent之间偶尔发送心跳协议,若检测到客户端连接已断开,则请求下线。

 2、问题:agentmgr是个单点,有可能成为系统瓶颈。

       解决:可以开启多个agentmgr,以玩家id为索引分开处理。

3、问题:由于move协议的广播量很大,会造成跨节点通信的负载压力。

      解决:匹配时应尽量匹配到同节点的场景服务,只有在某些特殊玩法中才匹配到跨节点的场景服务。

4、问题:gateway在Lua层处理字符串协议,但Lua并不适合处理大量可变字符串,因为它会增加GC(内存垃圾回收机制)的负担,所以Lua层输入缓冲区效率较低。

     解决:可以使用其他的数据传输协议,例如ProtobufJson以及Skynet自带的netpack模块用于高效处理该功能。

5、问题:场景服务广播量很大,

      解决:可以用AOI(Area of Interest)算法做优化。考虑到玩家屏幕大小有限,只能看到有限的球和食物,因此只需把玩家附近小球和食物广播给他即可(后面会介绍)。

6、问题:食物碰撞计算量很大,

      解决:可以用四叉树算法做优化,比起双重遍历,可以减少几倍计算量。另一种做法是服务端不主动做碰撞检测,由客户端计算。若客户端发现玩家碰撞到食物,告诉服务端。服务端只需做校验,这样就把计算量转移到了客户端(后面会介绍不同做法的优劣之处)。

7、 问题:在登出过程中,agent会接收kickexit消息,分别用于保存数据和退出服务。一种意外情形是,在kickexit之间,agent接收并处理了其他服务发来的消息,这些消息导致的属性更改将不会被存档(例如:如果在kickexit之间,玩家充值了,因为已经保存了数据,所以更新的金额不会被再次保存)。

      解决:可以给agent添加状态,设置若处于kick状态下则不处理任何消息。

8、问题:对于大量玩家,数据要怎么处理?

      解决:可以对数据库做分库分表操作,甚至可使用Redis做一层缓存。

9、 问题:如何让服务端稳定运行?

       解决:稳定运行的前提是所有Skynet节点都能稳定运行, 且各个节点能维持稳定的网络通信,因此所有节点应当部署在同一局域网。

你可能感兴趣的:(从零开始学Skynet,skynet,lua,服务器开发)