基于RPC的分布式广播服设计思路
Contents
前言
先前设计了一种基于Redis的分布式广播服,实际项目运行一段时间后,有几个问题需要面对
- 整体依赖Redis整个广播服的压力受限于Redis的吞吐量。
- 因为项目主短连接的, 广播服需要承担一些长连接的逻辑,依赖Redis数据更新并不方便。
- 因为未进行聊天室拆分,人数N多时广播风暴不可避免
- 广播时基于Redis的发布订阅,玩家数据未标识玩家进程UID,进程多时数据交互效率不高
本文主要讲针对上面几个问题重新设计的一个基于RPC的分布式广播服(纯理论,实际项目刚着手)。
设计思路
需要几种类型服务器
- connecter 集群,保持和客户端的长连接,用于信息广播和一些交互的逻辑
- chatRoomMgr 单点,聊天室拆分、合理的分散玩家到各个聊天室
- master 单点,管理各个服务器进程的状态,记录和广播各个注册服务器的状态
- gameserver 集群,http服务器,和客户端连接(已存在,显示说明为了解释方便)
RPC
RPC基于webSocket,端口采用独立端口不和Clint连接的端口复用,用于服务端接口调用及维护服务器状态。
master
- master服务器启动
- 非master进程启动时RPC向master注册自己服务器信息,以及取得其它注册服务器的信息。
- 非master进程,RPC连接其它注册服务器。
- 每个连接master的服务器,每30秒左右定时汇报自己服务器基本信息(可以夹带私货比如服务器人数,房间人数))。
- 非master进程状态变更,master服务器向所有注册到自己服务器广播启动、关闭等消息。
- master提供接口用于RPC向此采集数据。
gameserver
- 启动,RPC连接各个进程
- 客户端http连接gameserver
- gameserver通过RPC向connecter写入玩家的基本信息
- gameserver返回一个connecter地址
connecter
- 启动,RPC连接各个进程
- 客户端webSocket连接connecter
- 通用连接验证,connecter通过RPC向chatRoomMgr申请一个聊天室ID,并写入连接信息
- connecter返回客户端聊天室ID
- 向master同步数据提供连接人数
chatRoomMgr
- 启动,RPC连接各个进程
- 启动聊天室功能,等待RPC请求创建聊天室,聊天室从1开始,每200人新增一个频道
- 聊天内容不入库,客户端可以缓存
基本流程
- 聊天
- 客户端向聊天室发送消息
- connecter接收消息
- connecter向chatRoomMgr请求聊天消息
chatRoomMgr通过RPC向聊天室内各个玩家所在connector广播聊天消息
密集聊天(比较幼稚的思路)
每个聊天广播做个50条大小的数组,所有聊天消息先入数组
上次广播未推送完毕,等待广播
上次广播所有已推送完毕1秒左右,一次全部取出未广播的消息进行推送
系统广播
类似聊天室,但得消息缓存做一个优先原则
消息池总条数不变,若消息池已满优先级高的消息会挤优先级低的空间,相同优先级先到先得
直接由gameServer向各个connector广播系统消息
小结
一个常规的高仿Pomelo的分布式系统,全靠自己撸的话,开发设计难度不低,造轮子。chatRoomMgr单点的设计感觉不是很保险,应该从结构上想办法调整为可以集群。项目结构整体调整完毕再重发一版本说明吧。
Author wangkm
LastMod 2018/08/06