内容字号:默认大号超大号

段落设置:段首缩进取消段首缩进

字体设置:切换到微软雅黑切换到宋体

Message Queue的设计和实现(六)

2017-03-26 17:20 出处:清屏网 人气: 评论(0

时光飞逝啊,感觉一周周过的好快。 MQ 我们也聊了 5 期了,今天我们的第六期,要聊聊 Send Module 。这个模块看起来似乎很简单,但是实际上实现起来却是比较复杂,这里面包含分发逻辑和数据一致性的东西。

大家还记得我们第一期讲的时候,说 MQ 有多种发送逻辑嘛?我们把当时的文档翻出来再看看。

==== 发送模式的分割线 ====

[ 广播:一份数据,发送多份 ]

当我们后端处理的系统,每一个部署都需要全量数据的时候,就需要支持这种模式。拿发贴来打比方。我们的贴子存储系统,为了保证数据的冗余和可恢复,一般需要至少存储三份(就是同一个贴子需要存储到三台机器或者三个磁盘上)。这样,就需要我们把每一个贴子的数据转发到多个机器上,那就需要 MQ 具有数据多机发送的能力。

实现方法:

为了实现这个效果,我们需要给每一个客户端记录一个发送的位置。这样,当他再来获取的时候,就会从上一个成功的位置开始接着发送。而由于每个客户端都有一个位置信息,所以不同的客户端是不会出现冲突的。

这个位置的记录有两种方式:

· 一种是放在客户端存放:客户端自己记录上一次请求的 ID ,下一次 +1 后发送给服务器;

· 一种是放在 server 端存放:客户端每次请求成功确认后, ID 存放入文件,下一次取出 ID+1 获取对应的数据。

两种方式实现都是可以的,老王选择的是第一种。

[ 单播:一份数据,仅发送一份 ]

当我们的后端系统,需要去重处理的时候,每一个数据有且仅有一份被转发到后端。还是拿发贴来打比方,我们有一个系统是用来做发贴数统计的。他的作用就是来一个贴子,就把数据库里的贴子数做加一操作(类似: update post_count set count = count + 1 )。但是为了保证线上服务的可用性,需要多台机器提供服务,避免单机挂掉以后,服务不可使用。但是,这些系统之间,不能重复的接收同一个发贴的数据,否则计数就是错误的。所以,需要做单播发送。

实现方式:

这种发送模式就只能在服务器保存一个唯一 ID ,不管谁请求,都从文件取出 ID ,然后 +1 并获取数据。但是,为了保证数据发送的可靠性,这里有一个确认的过程。就是当对应的数据返回给客户端以后,有一个超时时间(比如: 2 秒)。客户端需要在这个时间内返回收到确认。如果没返回,则超时后,系统会将这个 ID 的数据重发给客户端(有可能是其他客户端)。如果在规定时间内返回了确认,则不再重发这个数据。

在实现的时候,就需要有一个 waiting-confirm-list 。发送出去的 ID 放到这个 list 当中,确认回来了,就删除。否则下次发送的时候,先从这个 list 中找超时未发送的 ID ,优先发送。

==== 应用模式的分割线 ====

[ 分组发送 ]

当我们后端有多个功能系统,每个功能系统又需要相同数据的时候,我们的 MQ 就需要分组发送的功能。还是说发贴,如上面我们举例的,后端有两个系统:贴子存储系统 A ,和贴子计数系统 B 。其中我们需要将每个贴子发送到系统 A 的每个机器上,而对于 B ,则只需要将每个贴子只发送到其中某一台即可,不能重复。那上面讲的广播和单播的方式都满足不了。这个时候,我们就需要加入分组功能,每个组里面实现广播和单播的功能。

实现方式:

我们可以为每一个组的客户端设置一个 Group (或者 channel )。客户端请求的时候,带上 Group-ID 。这样,按照这个组的发送方式,将数据发送给对应的客户端。

如果这个组是广播方式,则用广播的模式发送;如果这个组是单播的模式,则按单播的方式发送。

[ 数据重放 ]

当我们后端系统某个模块挂掉了,需要重新恢复数据的时候,我们就希望用 MQ 来做数据回放。那这种东西怎么弄呢?

实现方式:

如果是广播模式,这个应用就很简单,就直接将请求 ID 恢复到我们想要的位置,直接请求就可以了。

如果是单播模式,这种模式就不适合重放数据。最好的做法,就是后端模块有多个备份。

好了,老王今天差不多就把发送的模块讲的差不多了。下周我们再聊聊怎么样让 MQ 不是单点就差不多把 MQ 的内容讲的差不多了。大家觉得呢?


分享给小伙伴们:
本文标签: MessageQueue

相关文章

发表评论愿您的每句评论,都能给大家的生活添色彩,带来共鸣,带来思索,带来快乐。

CopyRight © 2015-2016 QingPingShan.com , All Rights Reserved.

清屏网 版权所有 豫ICP备15026204号