谈谈游戏服务器中RPC模块的设计

💡 原文中文,约4300字,阅读约需11分钟。
📝

内容提要

作者回顾了十多年的RPC模块设计与使用经历,指出早期设计的不足。通过参与不同游戏开发,逐步改进RPC接口,解决了超时和请求响应区分等问题,最终提出基于workerid的新设计思路,强调了分布式系统中链接管理的抽象化。

🎯

关键要点

  • 作者回顾了十多年的RPC模块设计与使用经历,指出早期设计的不足。
  • 早期RPC设计简陋,序列化方式依赖手工编码,回调函数设计局限。
  • 超时处理机制简单,使用session字段来管理请求与响应。
  • 参与SLG游戏开发时,决定将核心玩法逻辑独立到单独进程中运行。
  • 设计新的RPC接口,修改超时功能以便处理超时后的逻辑。
  • 解决双向通信中请求与响应的区分问题,选择独立连接的方案。
  • 独立连接导致消息顺序问题,项目后期不得不绕过限制。
  • 在Go语言环境中开发RPC模块,采用消息传递方式解决跨服通信问题。
  • 通过协议ID区分请求与响应包,维护成本逐渐增加。
  • 最终通过未使用的bit位区分响应包和请求包,简化了处理逻辑。
  • 新的RPC模块设计几乎解决了以往经历中的所有痛点。
  • 反思RPC模块是否需要关注链接,探索更抽象的设计思路。
  • 为每个进程分配唯一标识workerid,重新设计RPC接口。
  • 通过抽象链接管理,将其从业务逻辑中剥离,关注workerid与业务的关系。

延伸问答

RPC模块的早期设计存在哪些不足?

早期RPC设计简陋,序列化方式依赖手工编码,回调函数设计局限,超时处理机制简单。

作者在SLG游戏开发中如何改进RPC模块?

作者将核心玩法逻辑独立到单独进程中运行,并设计新的RPC接口以简化进程间通信。

新的RPC模块设计是如何解决请求与响应区分问题的?

新的设计通过为每个进程建立独立连接来区分请求与响应,避免了消息顺序问题。

在Go语言环境中,RPC模块的设计有什么特点?

在Go语言环境中,RPC模块采用消息传递方式,设计了超时逻辑,并通过协议ID区分请求与响应包。

作者如何处理RPC模块中的超时逻辑?

作者修改超时功能,使得超时后仍调用回调函数,但参数置为nullptr,以便处理超时逻辑。

RPC模块设计中workerid的作用是什么?

workerid为每个进程分配唯一标识,决定了进程处理的特定数据范围,是数据路由与处理的关键。

➡️

继续阅读