ActiveMQ默认使用异步发送的模式:除非明确指定使用同步发送的方式或者在未使用事务的前提下发送持久化的消息,这两种情况都是同步发送的。
如果你 没有使用事务且发送的是持久化的消息,每一次发送都是同步发送的且会阻塞producer知道broker返回一个确认,表示消息已经被安全的持久化到磁盘。确认机制提供了消息安全的保障,但同时会阻塞客户端带来了很大的延时。很多高性能的应用,允许在失败的情况下有少量的数据丢失。如果你的应用满足这个特点,你可以使用异步发送来提高生产率,即使发送的是持久化的消息。
异步发送:它可以最大化producer端的发送效率。我们通常在发送消息量比较密集的情况下使用异步发送,它可以很大的提升Producer性能,不过这也带来了额外的问题:就是需要消耗更多的Client端内存同时也会导致broker端性能消耗增加;此外它不能有效的确保消息的发送成功。在userAsyncSend=true的情况下客户端需要容忍消息丢失的可能。
自我理解:此处的异步是指生产者和broker之间发送消息的异步。不是指生产者和消费者之间异步。
说明:对于一个Slow Consumer,使用同步发送消息可能出成Producer堵塞等情况,慢消费者适合使用异步发送。(这句话我认为有误)
总结:① 异步发送可以让生产者发的更快。② 如果异步投递不需要保证消息是否发送成功,发送者的效率会有所提高。如果异步投递还需要保证消息是否成功发送,并采用了回调的方式,发送者的效率提高不多,这种就有些鸡肋。
参考官网代码实现
异步消息如何确定发送成功?
异步发送丢失消息的场景是:生产者设置userAsyncSend=true,使用producer.send(msg)持续发送消息。如果消息不阻塞,生产者会认为所有send的消息均被成功发送至MQ。
如果MQ突然宕机,此时生产者端内存中尚未被发送至MQ的消息都会丢失。
所以正确的异步发送方法是需要接收回调的。
同步发送和异步发送的区别就在此,同步发送等send不阻塞了就表示一定发送成功了,异步发送需要客户端回执并由客户端再判断一次是否发送成功。
10.3 延迟投递和定时投递官网说明:
四大属性
案例
要在activemq.xml中配置schedulerSupport属性为true
Java代码里面封装的辅助消息类型:ScheduledMessage
10.4 分发策略 10.5 ActiveMQ消息重试机制官网说明:
是什么
消费者收到消息,之后出现异常了,没有告诉broker确认收到该消息,broker会尝试再将该消息发送给消费者。尝试n次,如果消费者还是没有确认收到该消息,那么该消息将被放到死信队列重,之后broker不会再将该消息发送给消费者。
具体哪些情况会引发消息重发
Client用了transactions且再session中调用了rollback
Client用了transactions且再调用commit之前关闭或者没有commit
Client再CLIENT_ACKNOWLEDGE的传递模式下,session中调用了recover
请说说消息重发时间间隔和重发次数
间隔:1
次数:6
每秒发6次
有毒消息Poison ACK
一个消息被redelivedred超过默认的最大重发次数(默认6次)时,消费的回个MQ发一个“poison ack”表示这个消息有毒,告诉broker不要再发了。这个时候broker会把这个消息放到DLQ(私信队列)。
属性说明
10.6 死信队列官方文档:
是什么
异常消息规避处理的集合,主要处理失败的消息。
使用:处理失败的消息
一般生产环境中在使用MQ时设计两个队列:一个核心业务队列,一个死信队列
核心业务队列:比如下图专门用来让订单系统发送订单消息的,然后另一个死信队列就是用来处理异常情况的。
假如第三方物流系统故障了,此时无法请求,那么仓储系统每次消费到一条订单消息,尝试通知发货和配送都会遇到对方的接口报错。此时仓储系统就可以把这条消息拒绝访问或者标志位处理失败。一旦标志这条消息处理失败了之后,MQ就会把这条消息转入提前设置好的一个死信队列中。