1.MQ基本概念
2.MQ优势
1.服务解耦
**降低服务间耦合性,提升可维护性及扩展性。**
如下图:订单系统发送数据给库存、支付、物流三个系统,但后期又需增加X系统,此时只需X系统自己从MQ获取信息即可,无需改动订单系统代码。
2.流量削锋 (削锋填谷)
3.异步调用
如下图:用户下单之后直接由订单系统返回下单成功即可,而不需等后面的库存系统、支付系统、物流系统都返回才通知用户,异步处理,提速。
3.MQ的劣势
小结
4.常见MQ对比
5.RabbitMQ
1.RabbitMQ是基于AMQP协议使用ErLang语言开发的一种消息队列产品。
AMQP:是一种高级消息队列协议,类比Http
2.RabbitMQ有六种工作模式
官网:https://www.rabbitmq.com/
5.1 RabbitMQ的工作模式
1.简单模式
一个生产者一个消费者
2. work Queues 工作队列模式
多个队列之间属于竞争关系,一条消息只会被一个消费者消费
3.发布订阅模式
声明交换机,生产者发送消息到交换机后,交换机会将消息发送至所有与之绑定的消息队列,以供不同的消费者消费。
4.Routting 路由模式
小结:
Routting路由模式在绑定交换机的时候必须必须指定RouttingKey,消息会转发到符合的Routting key的队列。
交换机的类型必须为direct
5.Topics 通配符模式
小结:
6.RabbitMQ工作模式总结
工作模式官网:https://www.rabbitmq.com/getstarted.html
5.2 RabbitMQ高级特性
1.消息的可靠性投递
使用RabbitMQ的时候,发送方为了防止消息丢失,RabbitMQ提供了两种方式来确保消息投递的可靠性。
·confirm 确认模式:
消息从producer到exchange(交换机),会返回一个confirmCallBack。
·return 退回模式:
消息从producer到exchange失败后会返回一个returnCallBack。
我们利用两种callBack控制消息可靠性投递。
2.Consumer ACK机制
手动签收:
1.开启手动签收:acknowledge=“manual”
2.监听器实现ChannelLawareMessageListener接口
3.如果消息处理成功,则调用channel的basicAck()签收
4.如果消息处理失败,则调用channel的basicNack()拒绝签收,broker重新发送给Consumer。
3.消费端限流
首先需要确保签收模式为ACK手动签收
listener-consumer 配置属性:perfetch=1 (表示消费端每次从MQ拉取一条消息进行消费,直到手动签收完成才会拉取下一条消息)
4. TTL
TTL:全称time to live(存活时间/过期时间)
当消息到达过期时间后若还未被消费会被移除。
两种过期模式:
1.队列统一过期时间;
2.消息单独过期时间;
注:如果同时设置了队列过期时间以及消息单独过期时间,以时间短的为准。
5. 死信队列
死信队列,英文缩写:DLX 。Dead Letter Exchange (死信交换机),当消息成为Dead message后,可以被重新发送到另一个交换机,这个交焕机就是DLX。
消息成为死信的三种情况:
1.队列消息长度到达限制
2.消费者拒接消费消息,basicNack/basicReject,并且不把消息重新放入原目标队列,requeue=false;
3.原队列存在消息过期设置,消息到达超时时间未被消费;
队列如何绑定死信队列
队列绑定死信交换机:
给队列设置参数:x-dead-letter-exchange和x-dead-letter-routing-key
6.延迟队列
延迟队列,即消息进入队列后不会立即被消费,只有到达指定时间后,才会被消费。
需求:
1.下单后,30分钟未支付,取消订单,回滚库存。
2.新用户注册成功7天后,发送短信问候。
实现方式:
1.定时器:
2.延迟队列:如下图
RabbitMQ如何实现延迟队列?
RabbitMQ可以通过 TTL+死信队列 来实现延迟队列效果。
7.日志与监控
RabbitMQ默认日志存放路径: /var/log/rabbitmq/rabbit@xxx.log
查看日志命令:(控制台查看更直观)
查看队列
# rabbitmqctl list queues
查看exchanges
# rabbitmgctl list exchanges
查看用户
# rabbitmgctl list users
查看连接
# rabbitmgctl list connections
查看环境变量
# rabbitmgctl environment
查看未被确认的队列
# rabbitmqctl list queues name messages unacknowledged
查看单个队列的内存使用
# rabbitmqctl list queues name memory
查看准备就绪的队列
# rabbitmactl list queues name messages ready
查看消费者信息
# rabbitmgctllist consumers
8.消息追踪
在使用任何消息中间件的过程中,难免会出现某条消息异常丢失的情况。
对于RabbitMQ而言,可能是因为生产者或消费者与RabbitMQ断开了连接,而它们与RabbitMQ又采用了不同的确认机制;也有可能是因为交换器与队列之间不同的转发策略;甚至是交换器并没有与任何队列进行绑定,生产者又不感知或者没有采取相应的措施;另外RabbitMQ本身的集群策略也可能导致消息的丢失。
这个时候就需要有一个较好的机制跟踪记录消息的投递过程,以此协助开发和运维人员进行问题的定位
在RabbitMQ中可以使用Firehose和rabbitmg tracing插件功能来实现消息追踪。
9.RabbitMQ应用问题
1.消息的可靠性保障
·消息补偿机制
需求:
确保消息100%发送成功。
消息补偿方案如下图:
2.消息的幂等性保障
·乐观锁解决方案
幂等性指一次和多次请求某一个资源,对于资源本身应该具有同样的结果。也就是说,其任意多次执行对资源本身所产生的影响均与一次执行的影响相同
在MQ中指,消费多条相同的消息,得到与消费该消息一次相同的结果
常用幂等性方案,使用数据库的乐观锁,如下图: