WebSocket分布式思考

    以前用workman搭建websocket集群服务时,也曾考虑过他的中心服务器是单机的,虽然业务可以交给business服务器,但是对于regesiter服务始终还是存在单点故障的危险。机缘巧合,看了一篇websocket的分布式部署的文章,以及向公司的同事请教了下关于现在公司的自研im的架构,特整理一下。

一、ws服务

1、架构图

基本流程为:用ws协议连接本服务,得到一个clientId,由客户端上报这个clinetId给服务端,服务端拿到这个clientId之后,可以给这个客户端发送信息,绑定这个客户端都分组,给分组发送消息。

2、时序图

核心点:

    1、redis映射了每个客户端所对应的ws服务器的ip地址和端口。

   2、当服务器需要发送消息时,需要判断这个client_id是不是属于本服务器:用reids的映射去验证。当不属于本服务器的client时,则通过rpc告知相应的ws服务器,让它去处理这个消息。

   3、群发消息时,通过队列来处理。公司目前用的kafka,保证了有序性。

  

二、消息模型

IM离不开消息模型,在以前的工作中使用的是传统的推模式。

传统模式大体如下:对于在线的用户,消息会直接实时同步到在线的接收方,如:手机端和pc端。而对于离线的用户或者消息有两种方式:一种是专门的离线库储存,未读和离线的消息;另一种是保存一个标记点,记录离线或者是未读的数量。无论哪一种,这种方式都是在同步后再储存消息的模式,存在着丢消息、消息不同步,也不支持消息漫游等功能。如果强行一致,那数据库的压力则会非常大。

另外一种模型是Timeline模型。

TimeLine模型

image

Timeline可以简单理解为是一个消息队列,但这个消息队列有如下特性:

  • 每个消息拥有一个顺序ID(SeqId),在队列后面的消息的SeqId一定比前面的消息的SeqId大,也就是保证SeqId一定是增长的,但是不要求严格递增。
  • 新的消息永远在尾部添加,保证新的消息的SeqId永远比已经存在队列中的消息都大。
  • 可根据SeqId随机定位到具体的某条消息进行读取,也可以任意读取某个给定范围内的所有消息。

有了这些特性后,消息的同步可以拿Timeline来很简单的实现。图中的例子中,消息发送方是A,消息接收方是B,同时B存在多个接收端,分别是B1、B2和B3。A向B发送消息,消息需要同步到B的多个端,待同步的消息通过一个Timeline来进行交换。A向B发送的所有消息,都会保存在这个Timeline中,B的每个接收端都是独立的从这个Timeline中拉取消息。每个接收端同步完毕后,都会在本地记录下最新同步到的消息的SeqId,即最新的一个位点,作为下次消息同步的起始位点。服务端不会保存各个端的同步状态,各个端均可以在任意时间从任意点开始拉取消息。

消息漫游也是基于Timeline,和消息同步唯一的区别是,消息漫游要求服务端能够对Timeline内的所有数据进行持久化。

参考:https://github.com/woodylan/go-websocket

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值