RabbitMQ 高级特性
TTL队列/消息
TTL是Time To Live的缩写, 指消息存活时间
RabbitMQ支持消息的过期时间, 在消息发送时可以进行指定 (设置消息有效时间expiration)
RabbitMQ支持队列的过期时间, 从消息入队列开始计算, 只要超过了队列的超时时间配置, 那么消息会自动清除 (设置队列有效时间x-message-ttl)
消费端限流
当队列中有大量的消息待消费,消费端程序启动运行时可能会在短时间内收到大量消息,会造成服务端压力,甚至崩溃。因此有必要在消费端做限流处理,消费端限流是指由消费端接收到消息通过业务处理之后手动签收消息,而不是由服务端把消息送达消费端之后由服务端发起签收。当消息被签收后消费端会收到下一条消息,服务端只负责消息送达不负责处理,因此它的签收一条消息的时间很短;而消费端需要对消息进行处理,因此签收消息需要较长的时间。所以获取下一条消息的时机由消费端手动ack是合理的。
a、xml配置方式
消费端的确认模式一定为手动确认,acknowledge="manual",prefetch="5"属性设置消费端一次拉取多少消息
<rabbit:listener-container connection-factory="connectionFactory" acknowledge="manual" prefetch="2">
<rabbit:listener ref="confirmListener" queue-names="queue_confirm"></rabbit:listener>
</rabbit:listener-container>
b、java代码方式
//prefetchSize表示不限制消息大小, prefetchCount一次只处理多少消息, global true表示对channel有效,false只是当前consumer有效
channel.basicQos(int prefetchSize,int prefetchCount,boolean global);
//queue消费队列, autoAck true自动签收,false手动签收,消费者类一般实现DefaultConsumer接口
channel.basicConsume(String queue, boolean autoAck, Consumer callback);
死信队列
代码实现参考:https://www.jianshu.com/p/986ee5eb78bc
死信队列:DLX,dead-letter-exchange
消息变成死信后,会被重新投递(publish)到另一个交换机上(Exchange),这个交换机往往被称为DLX(dead-letter-exchange)“死信交换机”,
然后交换机根据绑定规则转发到对应的队列上,监听该队列就可以被重新消费。
消息变成死信有以下几种情况
消息被拒绝(basic.reject / basic.nack),并且requeue = false
消息TTL过期
队列达到最大长度
死信队列绑定关系
1、创建两个交换器:common.exchange(普通交换器)、dlx.exchange(死信交换器也是普通交换器,由于用在死信队列上因此给一个特定的名字)
2、建立dlx.queue与dlx.exchange之间的绑定关系,实际是在创建dlx.queue时候添加参数设置:x-dead-letter-exchange=dlx.exchange;
3、建立dlx.queue与common.exchange之间的绑定关系(交换器与队列之间正常绑定)
4、建立common.queue与dlx.exchange之间的绑定关系,当出现死信消息时,会根据消息所带的routekey与binding中设置的routekey将消息publish绑定的对列中。
消息流转过程:publisher-->common.exchange-->dlx.queue(成为死信的消息)-->dlx.exchange-->common.queue
延迟队列
即消息进入队列后不会立即被消费,只有到达指定时间后,才会被消费。
死信队列与延迟队列的区别
1、死信通常在异常运行情况下产生,可以通过绑定死信交换器重新发布消息,避免消息接收遗漏(被动发生)
2、延迟队列一般是根据业务场景采取的业务逻辑实现方式,可以通过TTL + DLX实现(主动实现)
消息幂等性保障
幂等性指一次和多次请求某一个资源,对于资源本身应该具有同样的结果。也就是说,其任意多次执行对资源本身所产生的影响均与一次执行的影响相同
参考:https://www.jianshu.com/p/d8042d7f62e1