rabbitmq消费端auto和manual区别;处理mq的requeue

概述

automanual区别其实就如字面意思一般,auto代表自动确认消息,只要消费者的方法执行完了,就自动告诉mq当前消息确认.manual则是需要手动通知mq。不需要想的很复杂就是这么直接.

auto自动确认

  1. 消息成功被消费,没有抛出异常,则自动确认,回复ack。
  2. 当抛出ImmediateAcknowledgeAmqpException异常,则视为成功消费,确认该消息。
  3. 当抛出AmqpRejectAndDontRequeueException异常的时候,则消息会被拒绝丢弃,并且不会重新入队。
  4. 其他的异常,则消息会被拒绝,且requeue = true(默认就是true)时会重新入队

manual人工确认

无论有没有异常,标准只有是否主动调用basicAck()、basicNack()等方法,没有调用则一直阻塞.

因此有异常时,(有重试就重试),抛出异常后,没有调用时,还是会一直阻塞。即使是auto模式的那两个特殊的异常,在manual中都是一样的,不会有特殊处理.

关于default-requeue-rejected(重新入队)属性的优先级

server:
  port: 9009
spring:
  rabbitmq:
    host: xxxx
    port: 5672
    username: xxxx
    password: xxxx
    virtual-host: /fchan
    listener:
      simple:
        #(默认值为true)在消费者出现异常时是否丢弃该消息还是重新入队,true:重新入队,入队后在队首
        #default-requeue-rejected: true
        #qos = concurrency * prefetch
        #concurrency: 1 
        #max-concurrency: 5
        #qos = concurrency * prefetch
        prefetch: 2
        #acknowledge-mode: auto
  1. 最高优先级:AmqpRejectAndDontRequeueException处理的requeue = false(剩下那个特殊异常视为成功,与此处无关),抛出这个异常的时候直接就是拒绝并且丢弃。
  2. 其次是手动确认时basicNack()boolean requeue 参数
  3. 接着便是这个参数定义的重新入队default-requeue-rejected
  4. auto模式中,处理其他异常时,拒绝消息,此时如果配置了default-requeue-rejected=false则会丢弃消息
package com.ever.config.mq; import com.tongtech.client.core.TLQTemplate; import lombok.extern.slf4j.Slf4j; import org.springframework.amqp.core.Binding; import org.springframework.amqp.core.BindingBuilder; import org.springframework.amqp.core.Queue; import org.springframework.amqp.core.TopicExchange; import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Slf4j @Configuration public class MqConfig { public static final String ITEM_QUEUE = "system-queue_factory3"; /** * 路由key名称 */ public static final String ITEM_KEY = "system.#"; public static final String TOPIC_KEY = "system.bpm.event"; public static final String MQ_TYPE_NAME = "mq.type-name"; /** * 获取系统消息的队列 * * @return */ @Bean @ConditionalOnProperty(name = MQ_TYPE_NAME, havingValue = MqTypeNameConstant.RABBIT, matchIfMissing = true) public Queue sysManagementQueue() { return new Queue(ITEM_QUEUE); } /** * 获取交换机 * * @return */ @Bean @ConditionalOnProperty(name = MQ_TYPE_NAME, havingValue = MqTypeNameConstant.RABBIT, matchIfMissing = true) public TopicExchange sysExchange() { return new TopicExchange(com.ever.digitalfactory.system.commons.Config.RabbitMqConfig.ITEM_TOPIC_EXCHANGE); } /** * 交换机与队列绑定 * * @return */ @Bean @ConditionalOnProperty(name = MQ_TYPE_NAME, havingValue = MqTypeNameConstant.RABBIT, matchIfMissing = true) public Binding sysExchangeBind(Queue sysManagementQueue, TopicExchange sysExchange) { return BindingBuilder.bind(sysManagementQueue).to(sysExchange).with(ITEM_KEY); } @Bean @ConditionalOnProperty(name = MQ_TYPE_NAME, havingValue = MqTypeNameConstant.RABBIT, matchIfMissing = true) public MqTemplate rabbitMqTemplate(RabbitTemplate rabbitTemplate) { return new RabbitMqTemplate(rabbitTemplate); } @Bean @ConditionalOnProperty(name = MQ_TYPE_NAME, havingValue = MqTypeNameConstant.TONGTECH) public MqTemplate tongtechMqTemplate(TLQTemplate tLQTemplate) { return new TongtechMqTemplate(tLQTemplate); } } 发送消息是这样的, package com.ever.digitalfactory.ppm.usage.rabbitmq; import com.ever.digitalfactory.ppm.usage.rabbitmq.tongtech.MqTypeNameConstant; import com.ever.digitalfactory.system.commons.Config.RabbitMqConfig; import lombok.extern.slf4j.Slf4j; import org.springframework.amqp.core.Binding; import org.springframework.amqp.core.BindingBuilder; import org.springframework.amqp.core.Queue; import org.springframework.amqp.core.TopicExchange; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * 配置类 * * @author Enmaai */ @Slf4j @Configuration @ConditionalOnProperty(name = Config.MQ_TYPE_NAME, havingValue = MqTypeNameConstant.RABBIT, matchIfMissing = true) public class Config { /** * 队列名称 */ public static final String ITEM_QUEUE = "ppm"; /** * 路由key名称 */ public static final String ITEM_KEY = "system.#"; public static final String MQ_TYPE_NAME = "mq.type-name"; /** * 获取系统消息的队列 * * @return */ @Bean public Queue sysManagementQueue() { return new Queue(ITEM_QUEUE); } /** * 获取交换机 * * @return */ @Bean public TopicExchange sysExchange() { return new TopicExchange(RabbitMqConfig.ITEM_TOPIC_EXCHANGE); } /** * 交换机与队列绑定 * * @return */ @Bean public Binding sysExchangeBind(Queue sysManagementQueue, TopicExchange sysExchange) { return BindingBuilder.bind(sysManagementQueue).to(sysExchange).with(ITEM_KEY); } } 这两个队列用的一个交换机 package com.ever.config.mq; import com.ever.digitalfactory.system.commons.Config.RabbitMqConfig; import lombok.extern.slf4j.Slf4j; import org.springframework.amqp.core.Binding; import org.springframework.amqp.core.BindingBuilder; import org.springframework.amqp.core.Queue; import org.springframework.amqp.core.TopicExchange; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * 配置类 * * @author Enmaai */ @Slf4j @Configuration @ConditionalOnProperty(name = Config.MQ_TYPE_NAME, havingValue = MqTypeNameConstant.RABBIT, matchIfMissing = true) public class Config { /** * 队列名称 */ public static final String ITEM_QUEUE = "h3-ips-queue"; /** * 路由key名称 */ public static final String ITEM_KEY = "system.#"; /** * mq类型名称 */ public static final String MQ_TYPE_NAME = "mq.type-name"; /** * 获取系统消息的队列 * * @return */ @Bean public Queue sysManagementQueue() { return new Queue(ITEM_QUEUE); } /** * 获取交换机 * * @return */ @Bean public TopicExchange sysExchange() { return new TopicExchange(RabbitMqConfig.ITEM_TOPIC_EXCHANGE); } /** * 交换机与队列绑定 * * @return */ @Bean public Binding sysExchangeBind(Queue sysManagementQueue, TopicExchange sysExchange) { return BindingBuilder.bind(sysManagementQueue).to(sysExchange).with(ITEM_KEY); } } 我需要通过交换机把ppm的消息被ppm消费,confirmModelSend这个方法不能改 public void sendBpmMsg(JSONObject msg) { confirmModelSend(com.ever.digitalfactory.system.commons.Config.RabbitMqConfig.ITEM_TOPIC_EXCHANGE, MqConfig.TOPIC_KEY, msg.toJSONString()); }
最新发布
06-19
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值