掌握之分布式-3.消息队列
掌握高并发、高可用架构
第三章 分布式
本章介绍分布式架构的底层技术。主要说明面试过程中可能被问到的技术点。
成都创新互联公司专业为企业提供龙川网站建设、龙川做网站、龙川网站设计、龙川网站制作等企业网站建设、网页设计与制作、龙川企业网站模板建站服务,十载龙川做网站经验,不只是建网站,更提供有价值的思路和整体网络服务。
第三节 消息队列(MQ,Message Queue)
消息队列
MQ
JMS
AMQP
ActiveMQ
RabbitMQ
RocketMQ
kafka
1. 什么是消息队列
可以把消息队列简单理解为存放消息的容器,并且当我们需要消息的时候可以取出消息供自己使用。消息队列是分布式系统中重要的中间件,它可以通过异步操作来实现提高系统性能、流量削峰、降低系统耦合。
目前比较流行的消息队列有:ActiveMQ、RabbitMQ、RocketMQ、Kafka
2. 为何要用消息队列,它的优势
消息队列的优势主要体现在:
- 通过异步处理来提高系统性能
使用了消息队列后,用户的请求发送到消息队列后就返回了,由消息队列的消费者把消息异步的写到数据库。由于消息队列服务器的处理速度大于数据库,所以系统性能大幅提高
降低系统的耦合性
使用了消息队列后,应用之间不再是强耦合关系,各个应用从消息队列获取需要的消息,从而降低耦合
限流削峰
购物网站的秒杀活动,在秒杀开始的一瞬间流量巨大,可能会导致系统无法处理而崩溃。加入消息队列后,用户请求都会放入消息队列,系统处理则从消息队列获取数据,不至于导致系统崩溃
- 请求先入消息队列,而不是直接交给业务处理,做了一次缓冲,极大的降低了系统的压力
- 队列长度可以进行限制,后面的请求无法入队,就可以直接抛弃了
3. 使用消息队列带来的问题
- 系统可用性降低:加入MQ后,需要考虑服务器宕机的问题
- 系统复杂性提高:消息丢失、重复消费、消息传递的顺序性
- 一致性问题:消息被正确的消费
4. JMS VS AMQP
JMS,Java Message Service即Java消息服务,它是消息服务的规范。JMS API允许应用程序组件基于JMEE平台创建 、发送、接收、读取消息。它使分布式通信耦合性降低、消息服务更加可靠
ActiveMQ就是基于JMS规范实现的
JMS支持两种消息模型:
点对点(P2P)模型
使用队列(Queue)来满足生产者消费者模式,一条消息只能被一个消费者消费
发布/订阅(Pub/Sub)模型
发布-订阅模型使用主题(Topic)作为消息通信载体,发布者发布一条消息,该消息通过主题传递给所有的订阅者
JMS支持的五种消息格式
- StreamMessage,Java原始值的数据流
- MapMessage,键值对
- TextMessage,字符串
- ObjectMessage,序列化的对象
- BytesMessage,字节数据流
AMQP,Advanced Message Queuing Protocol,高级消息队列协议(二进制应用层协议)。它是一个协议,兼容JMS。基于它实现的消息队列,不收客户端、中间件的开发语言限制
RabbitMQ就是基于AMQP实现的
比较内容 | JMS | AMQP |
---|---|---|
定义 | JMS API,是一种规范 | 是一个协议 |
跨语言 | 否,仅支持JAVA | 是 |
夸平台 | 否 | 是 |
消息模型 | 点对点模型、发布-订阅模型 | 提供了五种消息模型: 1.direct exchange 2.fanout exchange 3.topic change 4.header exchange 5.system exchange 后四种和发布订阅仅是在路由机制上做了更详细的划分 |
消息类型 | 上述的五种消息格式 | byte[] 二进制 |
5. 消息队列选型
比较目前流行的四种消息队列
特性 | ActiveMQ | RabbitMQ | RocketMQ | Kafka |
---|---|---|---|---|
开发语言 | java | erlang | java | scala |
单机吞吐量 | 万级(最差) | 万级(其次) | 十万级(最高) | 十万级(次之) |
时效性 | ms级 | us级 | ms级 | ms以内 |
可用性 | 基于Zookeeper + LevelDB的 master-slave模式 |
master/slave模式 master提供服务 slave仅做备份 |
多master模式 多master多slave异步复制模式 多master多slave同步双写模式 |
replica机制, leader宕机备份自动顶替, 并重新选举leader(基于Zookeeper) |
功能特性 | 成熟产品,社区不活跃,文档齐全 | 并发能力强,性能好,管理界面丰富 | 比较成熟,扩展性佳 | 只提供主要的MQ功能,在大数据领域应用广 |
消息推拉 | pull,push都支持 | pull,push都支持 | pull,push都支持 | pull |
6. 如何保证不被重复消费
什么情况会发生重复消费呢?正常情况下,消费者在消费消息完成后,会发送一个确认消息给消息队列,消息队列就知道该消息被消费了,就会将该消息从消息队列中删除。因为网络传输等故障,导致确认消息没有传送到消息队列,继而消息队列不知道该消息已被消费,再次将消息分发消费了
这个问题在不同的场景下有不同的解决方案,主要是在消费方来解决重复问题
- 消息用作DB的insert操作,此时可以把消息作为一个主键,当出现重复消费时,就会主键冲突,自然就避免了
- 消息用作redis的set操作,此时,因为set操作会覆盖上一个值 ,但是两次的值一样,也是无所谓的
- 最坏的情况下,可以准备第三方介质来存储消费的消息。比如Redis,每次操作时都去Redis中查看是否之前操作过
7. 如何保证数据不丢失
消息丢失主要分为:生产者丢失、消息队列丢失、消费者丢失
每种MQ都有不同的处理,这里就不详细论述了
Topic模式
参考资料
一个用消息队列 的人,不知道为啥用 MQ,这就有点尴尬
新手也能看懂,消息队列其实很简单
当前标题:掌握之分布式-3.消息队列
网页路径:http://ybzwz.com/article/gecpgh.html