赞
踩
解耦 例如:创建订单操作需要调库存系统、支付系统、物流系统等,可以不用等待直接返回结果,也会减少因某个系统故障而导致一条链路都蹦
1)生产者
productor-->exchange丢失:
开启confirm机制(发布确认机制),实现confirmCallback接口
productor-->queue路由失败:
开启return机制,实现returnCallback接口
setMandatory(true)或者如上图在配置文件开启return机制
confirm机制会重写confirm方法,根据ack判断,如果返回false则失败,编写业务逻辑,重试,重试达到3次仍然失败就持久化到数据库,人工处理。如果return机制失败,此时不可以放到死信队列,因为队列都没到达,可以放到redis去,然后用定时任务,重发。又或者放到备份交换机。
2)MQ服务器
3)消费者
消费者确认机制。默认情况下,MQ服务器的消息到达消费者后,消息者会立即发送ACK确认消息给MQ服务器,MQ服务器获取ACK后,从队列中删除消息。
如果执行自动ACK确认机制的话,MQ服务器可能会在消息者接受到消息但未执行成功业务的时候,主动删除MQ消息,导致消息的丢失。
我们可以开启手动ACK模式,然后在消费者的业务执行成功后,才使用代码发送ACK确认,以实现消息可靠。但是这种方式代码侵入性较高。Spring集成auto模式ACK机制,本质上利用AOP代理把手动ACK代码在业务执行成功后进行切入,从而既实现了手动ACK确认方式,也降低了代码耦合度。所以在开发中,直接使用Spring的ACK的manaual模式即可。
无法被消费的消息
应用场景:1、保证业务订单的消息不丢失,消费者发生异常时,可以放到死信队列 2、三十分钟不支付订单自动取消。 另外,延迟队列的实行方式也可以是java的delayQueue、quartz、kafka的时间轮。
死信来源:
注意:消息TTL有几种实现方式。1、消息TTL,这种情况如果遇到队列堵塞,前面的任务ttl比后面的ttl时间长,那任务也不会过期,因为是在发送消费者前判断过期时间 2、队列TTL,这种模式下,适用于单一的,整个任务都是一样的过期时间,像会议取消这种场景就不适用了 3、安装插件,这种情况可以解决1的问题。
1、消息携带业务id,消费者去查询数据库是否存在数据,如果存在证明已经消费过,不处理。或者插入,插入利用主键唯一性约束,插入不成功报键重复异常。
2、redis setnx,利用redis原子性特性
1、因为高峰导致的,可以利用死信队列
2、消费能力不足导致
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。