您的位置:首页 > 产品设计 > UI/UE

当说起message queue的时候,都在说什么?

2016-07-24 23:40 429 查看
接触了一些message system的系统(大部分是kafka),对message queue的作用和关键点有了一些了解。这些就谈谈我的认识,和使用注意事项。

message queue的作用

查阅了材料发现总结下来,列举的理由有十几条之多,但是直接貌似没有任何联系和组织方式。很是不好理解。我在这里使用模型的变化来阐述我自己的理解:



从上面的演化图来看,有了消息队列后的一个本质变化就是把收消息和接消息的任务都扔给了第三方,其实这就是软件行业中最一般的做法如果要获得软件的灵活性和扩展性,那么就开始加中间层。计算机网络是这么做的,同样操作系统也是这么做的。

而考虑具体的好处这个问题和系统会出现什么问题是手心手背的关系。我们就来一块一块的说。

我们假设我们要做一个买票系统。数据库使用mysql,前面只有一个售票程序来操作数据。这时候的模型就是第一个模块的样子。初期的时候一切都很完美,这个网站只拥有1万用户,每天只卖500张票。

后来发现有些背后的mysql总是宕机,导致用户订票总是不成功,所以就想着怎么把用户的订单信息先存下来,然后等mysql恢复后马上继续处理。这时候你就开始想着建立一个消息缓存队列,然后程序自然形成了一个生产者消费者模型。同时你还会发现这个不仅仅有消息缓存的好处,还有发现消息现在是可以被保存了(或者说很便捷和自然的保存了)。以前那些因为程序bug处理失败的消息可以被重复处理了。还有就是哪天突然要在mysql之上加上一层redis,那其实也不必修改上游程序。总结下来:

1. 缓冲 – 消息的缓存,当下游处于宕机状态,消息可以被缓存等待重启后继续处理。

2. 解耦 – 项目之间解耦,形成各种微服务

3. 冗余

4. 送达保证

5. 顺序保证能实现了

再后来你的系统的用户增加到了100万,而且因为是买的火车票,所以一到过节订单就出现高峰,这时候辛亏你有了消息队列可以帮你缓存。

6. 消除峰值 – 即消息均衡,当消息的生产速度差距很大的时候,消息可以被缓存,然后转发其他空闲的服务上或者等待等后续措施。

后来再发现一个消息队列因为不够存储高峰期间储蓄的数据了,这时候再增加下游的消费者处理能力很浪费,因为平时你用不着。这时候发现增加一个消息队列服务的成本去很低,那么开始扩展这里。

7. 扩展性

其他feature:

1. 异步通信

这个是好是坏,全看实际的引用场景。对于实时要求性很高,但是不要求消息全部保证被处理就是无所谓的特性。

附赠的feature(只是更方便吧)

因为消息缓存的独立,可以对其处理速度监控,从而得知系统的负载能力。

如果学习一个message queue?

消息可达性保证机制

这个机制或者约定更确切些,就是描述系统到底怎么client进行交互,确保信息是正确的到达了目的地。一般的消息保证机制有:

1.至多一次,保证绝对不重复发,但是有丢数据情况。这种情况server处理是最简单的,发完了就不管了,不需要和client交互。

at-most-once delivery means that for each message handed to the mechanism, that message is delivered zero or one times; in more casual terms it means that messages may be lost.

2.至少一次,保证一定client接收到了信息,如果不能确定client接收到了信息会重复发。做到这点server只要一直发知道接收到了client的ack。

at-least-once delivery means that for each message handed to the mechanism potentially multiple attempts are made at delivering it, such that at least one succeeds; again, in more casual terms this means that messages may be duplicated but not lost.

3.精确的一次,保证不重复发但也不丢数据。exactly-once是最难保证的,因为这涉及到通信中的很多情况。

exactly-once delivery means that for each message handed to the mechanism exactly one delivery is made to the recipient; the message can neither be lost nor duplicated.

The first one is the cheapest—highest performance, least implementation overhead—because it can be done in a fire-and-forget fashion without keeping state at the sending end or in the transport mechanism. The second one requires retries to counter transport losses, which means keeping state at the sending end and having an acknowledgement mechanism at the receiving end. The third is most expensive—and has consequently worst performance—because in addition to the second it requires state to be kept at the receiving end in order to filter out duplicate deliveries.

为什么保证不了消息发送?

The message is sent out on the network?

The message is received by the other host?

The message is put into the target actor’s mailbox?

The message is starting to be processed by the target actor?

The message is processed successfully by the target actor?

其实就从消息传递从出发到结果的整个过程,状体包括出发、路上、进门、喝茶、出门和回家通报。

其中在路上需要花多少时间谁都不知道,还有没有万一进门后被真“喝茶”后,不返回通报的你让发送者的家人怎么办?

消息顺序保证机制

保证消息一定是顺序到达的,这个地方需要考虑如果是一个kafka的系统,同一个group下的不同consumer之间的顺序怎么保证?

不保证消息一定顺序到达

reference

Message Delivery Reliability

Kafka深度解析
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: