谈谈游戏服务器中RPC模块的设计
内容提要
作者回顾了十多年的RPC模块设计与使用经历,指出早期设计的不足。通过参与不同游戏开发,逐步改进RPC接口,解决了超时和请求响应区分等问题,最终提出基于workerid的新设计思路,强调了分布式系统中链接管理的抽象化。
关键要点
-
作者回顾了十多年的RPC模块设计与使用经历,指出早期设计的不足。
-
早期RPC设计简陋,序列化方式依赖手工编码,回调函数设计局限。
-
超时处理机制简单,使用session字段来管理请求与响应。
-
参与SLG游戏开发时,决定将核心玩法逻辑独立到单独进程中运行。
-
设计新的RPC接口,修改超时功能以便处理超时后的逻辑。
-
解决双向通信中请求与响应的区分问题,选择独立连接的方案。
-
独立连接导致消息顺序问题,项目后期不得不绕过限制。
-
在Go语言环境中开发RPC模块,采用消息传递方式解决跨服通信问题。
-
通过协议ID区分请求与响应包,维护成本逐渐增加。
-
最终通过未使用的bit位区分响应包和请求包,简化了处理逻辑。
-
新的RPC模块设计几乎解决了以往经历中的所有痛点。
-
反思RPC模块是否需要关注链接,探索更抽象的设计思路。
-
为每个进程分配唯一标识workerid,重新设计RPC接口。
-
通过抽象链接管理,将其从业务逻辑中剥离,关注workerid与业务的关系。
延伸解读
RPC模块设计的演变
作者回顾了十多年的RPC模块设计历程,强调了早期设计的局限性,如手工编码的序列化和简单的超时处理。这些不足促使作者在后续开发中不断探索和改进,最终形成了更高效的RPC接口设计,反映了技术进步对游戏开发的重要影响。
独立连接的挑战
在新的RPC设计中,作者选择了独立连接的方案以区分请求与响应,但这也带来了消息顺序的问题。在高并发场景下,消息顺序的破坏可能导致客户端与服务器之间的状态不一致,开发者需对此保持警惕,确保设计能够适应复杂的通信需求。
workerid的关键作用
作者提出为每个进程分配唯一的workerid,以重新设计RPC接口。这一设计思路不仅简化了链接管理,还将业务逻辑与底层连接状态剥离,使得分布式系统的资源调度与业务需求更加紧密结合。开发者在设计RPC模块时应考虑workerid的使用,以提升系统的灵活性和可维护性。
延伸问答
RPC模块的早期设计存在哪些不足?
早期RPC设计简陋,序列化方式依赖手工编码,回调函数设计局限,超时处理机制简单。
作者在SLG游戏开发中如何改进RPC模块?
作者将核心玩法逻辑独立到单独进程中运行,并设计新的RPC接口以简化进程间通信。
新的RPC模块设计是如何解决请求与响应区分问题的?
新的设计通过为每个进程建立独立连接来区分请求与响应,避免了消息顺序问题。
在Go语言环境中,RPC模块的设计有什么特点?
在Go语言环境中,RPC模块采用消息传递方式,设计了超时逻辑,并通过协议ID区分请求与响应包。
作者如何处理RPC模块中的超时逻辑?
作者修改超时功能,使得超时后仍调用回调函数,但参数置为nullptr,以便处理超时逻辑。
RPC模块设计中workerid的作用是什么?
workerid为每个进程分配唯一标识,决定了进程处理的特定数据范围,是数据路由与处理的关键。