消息队列 :
MQ是消息通信的模型,并发具体实现。现在实现MQ的有两种主流方式:AMQP 和JMS。
两者间的区别和联系:
JMS是定义了统一的接口,来对消息操作进行统一;AMQP是通过规定协议来统一数据交互的格式
JMS限定了必须使用Java语言;AMQP只是协议,不规定实现方式,因此是跨语言的。
JMS规定了两种消息模型;而AMQP的消息模型更加丰富
常见的MQ产品 :
ActiveMQ:基于JMS
RabbitMQ:基于AMQP协议,erlang语言开发,稳定性好
RocketMQ:基于JMS,阿里巴巴产品,目前交由Apache基金会
Kafka:分布式消息系统,高吞吐量
RabbitMQ提供了6种消息模型,但是第6种其实是RPC (远程调用方式),并不是MQ。那么也就剩下5种。
但是其实3、4、5这三种都属于订阅模型,只不过进行路由(RoutingKey)的方式不同。
- 点对点模型
- 任务模型
- 订阅模型 引入交换机和队列 < Fanout, Dirct, Topic>
一、如何避免消息的丢失?
消息的丢失可以通过 消息确认机制Ack 和 消息持久化机制 来解决. 消息确认机制又可以通过 生产者的角度 和 消费者的角度 来避免.
从生产者角度来说 : 在发送消息的同时,记录消息的状态到数据库当中, ( 在发送消息的同时,记录一条消息到数据库中 )
通过记录MQ中的消息状态来确定消息是否发送成功. ( 可以编写定时任务,不断的扫描未发送的消息,进行重新发送或者删除 )
从消费者的角度来说 : 通过消费者的确认机制 ,即 消费者收到消息后给生产者发送一条消息,确认消息已收到.
消息的持久化机制 - > MQ内部的机制 : 消息都是在内存中存储,MQ一旦宕机,交换机,消息队列, 都会消失.
在发送消息到交换机的时候, 设置消息持久化 MessageProperties .persistent_text_plain
消息持久化的 前提是 队列 和 交换机 都持久化.
队列持久化 : 在消息接收方, 声明队列时指定持久化durable 为 true ,
交换机持久化 : 在生产者声明交换机的时候,指定持久化durable为true ,
二、如何避免信息堆积?
避免消息的重复发送 ; 通过保证消息的幂等性 .
如何保证消息的幂等性 ; < 幂等 : 当一件事多次执行和执行一次的效果是一致的 >
1.时间角度 : ,确定是否为同一用户,判断发送消息的时间间隔大于1秒,如果小于1秒,则自动将消息过滤掉.)
2.回收角度 : 在数据库中进行判断,设置定时任务,一定的时间之后 清空/删除 用户下的订单.