dispatcher 设计

attach_166cb75a42945105 (1).png

二期 msg dispather ,im server 。

目前我们公司 go im server 基于 https://github.com/googollee/go-socket.io 做开发的 。
同时 go im server 是 将 im server , msg dispatcher 融合在了一起 。职责单一原则 ,我认为拆成 msg dispatcher , im server 会更加合理。 msg dispatcher 可以支持多队列,屏蔽上层队列不同,也更容易去做背压设计 。

当前架构最大的问题

  1. 吞吐量问题 ,目前tqmq 是单队列传输消息 。将来可以通过多队列提升消息的吞吐量。巨量的数据,如果是kafka ,完全可以通过单队列,多数据分片来解决 ,如果是 tqmq ,只能通过多tqmq队列扩展其吞吐量性能。
  2. 消息顺序问题。目前同时发送两个消息,go im server 有一定概率,顺序是颠倒的。
  3. 当流量到达一定程度情况下 ,难免会出现不同地区用户,消息实时性,可达率,可能存在较大差别 ,这个当前架构体系是无法改变。不同地区到ecs 路由时间本来就存在较大差别。im 消息稳定性也是如此。期待公司未来吧
  1. 过去有离线消息表 ,用户不在线或者im消息失败,会发到业务,业务在入离线消息表,然后发送推送。离线消息表本身被已读索引优化掉了。其实没有必要把消息推送到业务平台,在通过业务平台调用推送。可以直接推送 即可。

  2. java 其实可以通过groovy 脚本引擎,提供动态编程的能力 ,无需重启,即可提供更新代码的能力,提供更加可靠的稳定性。比如不同版本消息协议解析或者转换成统一格式 ,或统一格式的变化,dispatcher 是可以不重启的。(第3期做比较好)

下面是第二期设计的消息下发的架构图
[图片上传失败...(image-4c54c7-1628040115137)]

解决消息完全有序

当前go im server , 如果是自己msg 就不转发, 如果不是就转发,连续的msg 被分到了不同的机器 ,机器处理时间有不一致 。这里极有可能出现消息乱序问题。

通过kafka 可以保证,分片数据一定被唯一一个消费者消费 ,不会存在tqmq的多消费者问题。也就不存在乱序可能性。

消息验证

我希望能够将消息下发验证流程都都到 java server ,而不是说 到了im server 还要效验消息的合法性 。目前 go 通过ticket 作为登录验证过程,如果ticket 验证通过后 ,登录成功 ,消息可以下发。否则 不能下发 。 但是这个过程 已经 经过 消息队列 。到达im server ,那之前的流程 不是白走了?
如果 我们把msg 验证 放到 push server ,流程更加合理 。

背压设计背景

比如 某个im server 已经 满负荷运行了 , 这时候 其他im server 依然不断配发属于你的msg 给你 , 可以想象结局会是如何 。
分离的话 ,这块逻辑会很好处理 。消息入im server队列 ,队列满后,告知dispatcher ,别给我发了 ,消息入拥塞队列。并告警阻塞 。 更加合理

这一块比上面说的,其实要复杂 。因为场景 n 生成者与n消费者问题,对于消费者1而言 ,我可能需要m 个产品 ,而 m个产品 对于n个生产者而言,但是真实业务的场景,显然是不均衡的。某些消费者必然会比其他消费者消费更多的消息 。

服务背压和tcp 滑动窗口 本质上是相同的 ,针对上面的问题,dispatcher 与im server 间,类似于tcp连接滑动窗口。

dispatcher 会将msg 分发到指定 im server 队列中, 等待im server 授权,授权后,将消息发送给im server 。
当im server 队列满后, 需要阻塞消息的消费 ,并告警哪条im server队列已满。通知下游im server 开启服务降级 ,新的用户会登陆其他im server 。同时 3次发送重试入离线消息,变成一次未确认,入离线队列 。

重点是要保障 消费能力 大于生成能力

未来可能会有多协议队列

msg dispatcher 会从不同类别队列拉取msg ,然后根据用户登录meta data (appcode , uuid ) ,找到登录im server 。 将消息分发到指定im server 发送队列上。批量推送给 im server 待发队列, im server 待发队列满了之后 。im server 会告知 msg dispatcher 不要给我发了 ,im server 发送队列满了后,多的消息暂时保存在rocksdb中 ,告警中,rocksdb 保存该条连接消息超过2w 消息 ,告警高,直接走离线下发流程。这样msg dispatcher 永远不会内存溢出 挂掉。第二我们优化了消息下发流程。之前消息都是通过soa 一个一个下发消息。消息批量下推方式。效率更高。
im server 有一待发队列 ,在待发满之前 。 可以通过rsocket 告知dispatcher 一次可以推送的最大消息数量 。达到背压效果 。im server 永远不会内存溢出 挂掉。im server demo 下推消息方式其实是不合理的。 必须基于netty 进行开发。(第3期做会比较好)

im proxy 属于第3期内容

类似于智能dns 选址 。im proxy 观察后端im server负载,负载较低情况下,通过hash 方式,将后端ip直接分发给客户端,允许客户端和对应im server 创建连接。负载中情况下 (有im server 存在msg 推送不完的情况) ,新建连接到负载小的 im server 上 , 负载高 。必须要扩展imserver ,将连接创建到新的imserver 。 或者 禁止 用户登录 。im proxy 尽量解决 im server 热点问题 。 (第三期开发)

rsocket rpc

im server 列表更新后 ,etcd 推送给所有dispatcher ,dispatcher 和新的imserver 初始化队列,建立连接。 对于下掉im server ,检测 im server 连接,连接正常不做任何操作 。
rsocket https://rsocket.io/
RSocket 是传输无关的,支持 TCP、WebSocket 和 Aeron UDP 协议,并支持无语义损失的混合传输协议——回压和流量控制仍然有效。
基于tcp 长链 ,支持回压 ,重连,双向流。具有较高性能,benchmark强于 http2 grpc 是必然的 。 天生响应式编程都是他的优点。

dispatcher metadata

im dispatcher metadata
key : tqmsg:dispatcher:metadata:%s id
value:

 [ 
    address : ip,
    port : 8080,
    tps: ,
    offline_tps,
    online_tps,
    rt:
    offline_rt,
    online_rt,
   risk_level,
   unvalid_msg_num,
 ]

dispatcher connection metadata

im dispatcher connection metadata
key : tqmsg:dispatcher:connection:metadata:%s id_id
value:

[
    im server id ,
    im server ip ,
    im server port ,
    status ,
    sendQueue,
    recieveQueue,
    rocksDb ,
    tps,
    rt,
]
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341