MQ有以下几个核心:
- 生产者
- 存储消息
- 消费者
本文我们重点关注MQ是如何将消息传递给消费者的,一般而言数据的传递无非就是两种形式,推和拉,比如git。假设此时APP端传来了一个创建订单的请求,MQ会对消息进行一个分发,这当中不仅仅是只有推和拉那么简单,这涉及到了MQ的分发策略
ActiveMQ | RabbitMQ | Kafka | RocketMQ | |
---|---|---|---|---|
发布订阅 | 支持 | 支持 | 支持 | 支持 |
轮询分发 | 支持 | 支持 | 支持 | - |
公平分发 | - | 支持 | 支持 | - |
重发 | 支持 | 支持 | - | 支持 |
消息拉取 | - | 支持 | 支持 | 支持 |
发布订阅
类比公众号,假设公众号A有1000人订阅,当该公众号发布了一条新的文章,这1000人都会收到该文章的推送。也就是说,MQ收到了消息,会将其分发给所有消费者
轮询分发 & 公平分发
轮询分发是指,假设我们现在有三个消费者,此时MQ要分发三条消息,假设消费者A所在的server响应时间为2000ms,消费者B所在的server响应时间为100ms,消费者C所在的server响应时间为500ms,不论服务器的性能如何,这三条消息会公平的分发给消费者,不会进行任何的数据倾斜
如果是公平分发,上述的分发结果可能是A收到0条消息,B收到2条消息,C收到1条消息,该策略会进行数据的倾斜,能者多劳。注意,该策略只支持手动应答,不支持自动应答
它们的共同点:如果一条消息已经被某个消费者消费了,那么该消息不可能再被其它消费者进行重复消费
重发
从分发消息到消费者返回结果给MQ,这个过程中可能会出现异常、出现网络抖动、宕机等情况,导致消息无法被消费。比如用户请求查询客流数据,此时客流模块挂了,导致用户查询客流数据失败
此时消息中间件就需要支持消息重试的策略,说白了,就是系统出现问题的情况下,消息保证不丢失并且还可以支持重发
消息拉取
根据RPC机制实现,很少使用MQ来做消息拉取