Terry-Mao / goim

goim
https://goim.io/
MIT License
7.21k stars 1.78k forks source link

router挂掉后如何处理 #145

Closed carbin-gun closed 6 years ago

carbin-gun commented 8 years ago

看了下现在router如果挂掉.无法再完成推送的.因为对于挂掉的router内存中维护的信息会丢失.我也看了这个issue94提出的解决方案:

不知道B站现在线上是如何处理这个问题的.


我现在想的是能否将router层全部移到comet中能解决这个问题:

这样就解决了.物理连接和维护的session在多机不同步的问题.因为物理连接和user-connection mapping在一台机器.如果丢失那么同样会丢失掉物理连接.那么天然是保持同步的.

如此之后,需要解决一个问题.那就是logic收到push请求之后如何找到一个用户的连接.可以有一个dispatch模块.所有的物理连接之前需要先请求dispatch.它会有加密规则并指定用户新发起的连接连接到指定的comet(这样comet也可以水平扩展).dispatch底层还需要一个路由规则支持,保证一个用户的所有连接都打到一台comet上.

之后查询logic就查询这个路由规则就能找到相应用户在哪台comet server.


但是如上之后,维护的业务数据(router里的数据)就已经跟物理耦合在一起.如果要发布,则可能对物理连接产生影响. 所以希望知道B站在实际使用过程中在这个问题上的思考和解决办法.

tonybase commented 7 years ago

在comet上面存放在线信息,其实我倒是不太建议在这层做,调度起来会非常麻烦,某个comet节点挂可能会导致打到这节点的用户都无法使用,而不能间隔去连接其它可用节点,因为用户规则绑定了连接节点了。

tonybase commented 7 years ago

目前我们做法是,在comet上面保存完整的在线信息,以增量进行拉用户信息,如果router挂了,可以全量去拉一次数据回来,以目前的业务看这个做法是最好维护的;还有别的做法,比如router没有复杂逻辑可以直接使用redis来存,做主从;或者说router双写也是可以达到容灾,看看业务场景。

carbin-gun commented 7 years ago

@im-qq ,某个comet节点挂可能会导致打到这节点的用户都无法使用 如果comet都挂了,本身的维护的连接都已经没了,本来就已经不可用.这时候客户端会建立新连接,这时候应该有新的调度把用户调度到新的comet节点上.

carbin-gun commented 7 years ago

全量拉取的代码在现有的开源里是没有的吧.

Terry-Mao commented 7 years ago

目前我们公司在内测,会尽快开源整体goim 多iDC方案

tonybase commented 7 years ago

@carbin-gun 关于调度方案: 1、使用HTTPDNS进行测速以及权重计算,调度到最优节点。 2、DNS域名解析调度,如果检测到节点不可用进行自动调度。

kirk91 commented 7 years ago

@Terry-Mao 可以先大体上介绍下多idc的方案么

Terry-Mao commented 7 years ago

@im-qq 看找时间更新一下多idc的文档以及goim IDC的patch来合并吧

tonybase commented 7 years ago

好的,后面会整理一下再放出来。

buddh0 commented 7 years ago

期待这个patch

kirk91 commented 7 years ago

+1

hhjj6363 commented 7 years ago

@im-qq @Terry-Mao 请教一下引入三方消息队列主要是为了解决什么问题,持久化存储? 分层设计? 直接通过logic->comet推送消息出去影响会很大吗?

chuangyou commented 7 years ago

@hhjj6363 Kafka 异步、消峰、排队、负载均衡、消息持久化等

heipacker commented 7 years ago

啥时候更新一下多idc的文档以及goim IDC的patch的合并?

Terry-Mao commented 6 years ago

更新下,最近我们内部再开发基于Gossip 全局Router数据同步

aclisp commented 6 years ago

我们把客户端的心跳消息,也通过logic,都发到router。如果router挂掉,可以根据这些心跳重建在线用户map。这是最简单的做法了:在router挂掉的时间内,这些uid无法收到推送;router重启之后,心跳陆续上来,就恢复了。

如果不能容忍这个缺陷,更完美的做法是每个router都把在线用户map,持续同步到自己的备份router,挂掉之后,立刻主从切换。

心跳消息发给router,还有一个好处是,能清理太久没有下线的用户脏数据。

beiciye commented 6 years ago

@aclisp 有一个疑问, router 重启后心跳恢复前, 如果这个 uid 又新建立了连接,对应在 router 那边维护的 seq 怎么生成, 请问你们是怎么处理的?

tonybase commented 6 years ago

目前v2.0通过comet端到logic这边进行压缩后的sever heartbeat给redis expire,如果掉线一段时间内会自动恢复回来