前言

先前设计了一种基于Redis的分布式广播服,实际项目运行一段时间后,有几个问题需要面对

  1. 整体依赖Redis整个广播服的压力受限于Redis的吞吐量。
  2. 因为项目主短连接的, 广播服需要承担一些长连接的逻辑,依赖Redis数据更新并不方便。
  3. 因为未进行聊天室拆分,人数N多时广播风暴不可避免
  4. 广播时基于Redis的发布订阅,玩家数据未标识玩家进程UID,进程多时数据交互效率不高

本文主要讲针对上面几个问题重新设计的一个基于RPC的分布式广播服(纯理论,实际项目刚着手)。

设计思路

需要几种类型服务器

  1. connecter 集群,保持和客户端的长连接,用于信息广播和一些交互的逻辑
  2. chatRoomMgr 单点,聊天室拆分、合理的分散玩家到各个聊天室
  3. master 单点,管理各个服务器进程的状态,记录和广播各个注册服务器的状态
  4. gameserver 集群,http服务器,和客户端连接(已存在,显示说明为了解释方便)

RPC

RPC基于webSocket,端口采用独立端口不和Clint连接的端口复用,用于服务端接口调用及维护服务器状态。

master

  1. master服务器启动
  2. 非master进程启动时RPC向master注册自己服务器信息,以及取得其它注册服务器的信息。
  3. 非master进程,RPC连接其它注册服务器。
  4. 每个连接master的服务器,每30秒左右定时汇报自己服务器基本信息(可以夹带私货比如服务器人数,房间人数))。
  5. 非master进程状态变更,master服务器向所有注册到自己服务器广播启动、关闭等消息。
  6. master提供接口用于RPC向此采集数据。

gameserver

  1. 启动,RPC连接各个进程
  2. 客户端http连接gameserver
  3. gameserver通过RPC向connecter写入玩家的基本信息
  4. gameserver返回一个connecter地址

connecter

  1. 启动,RPC连接各个进程
  2. 客户端webSocket连接connecter
  3. 通用连接验证,connecter通过RPC向chatRoomMgr申请一个聊天室ID,并写入连接信息
  4. connecter返回客户端聊天室ID
  5. 向master同步数据提供连接人数

chatRoomMgr

  1. 启动,RPC连接各个进程
  2. 启动聊天室功能,等待RPC请求创建聊天室,聊天室从1开始,每200人新增一个频道
  3. 聊天内容不入库,客户端可以缓存

基本流程

  • 聊天
  • 客户端向聊天室发送消息
  • connecter接收消息
  • connecter向chatRoomMgr请求聊天消息
  • chatRoomMgr通过RPC向聊天室内各个玩家所在connector广播聊天消息

  • 密集聊天(比较幼稚的思路)

  • 每个聊天广播做个50条大小的数组,所有聊天消息先入数组

  • 上次广播未推送完毕,等待广播

  • 上次广播所有已推送完毕1秒左右,一次全部取出未广播的消息进行推送

  • 系统广播

  • 类似聊天室,但得消息缓存做一个优先原则

  • 消息池总条数不变,若消息池已满优先级高的消息会挤优先级低的空间,相同优先级先到先得

  • 直接由gameServer向各个connector广播系统消息

小结

一个常规的高仿Pomelo的分布式系统,全靠自己撸的话,开发设计难度不低,造轮子。chatRoomMgr单点的设计感觉不是很保险,应该从结构上想办法调整为可以集群。项目结构整体调整完毕再重发一版本说明吧。