RabbitMQ 属性参数配置详情

RabbitMQ 属性参数配置详情

01、SpringBoot 配置参数详解

参考:
https://www.chihiro.org.cn/archives/20200522150924
https://blog.csdn.net/girlgolden/article/details/97915368

1、application.yml

spring:
  rabbitmq:
    host: 127.0.0.1 #ip
    port: 5672      #端口
    username: guest #账号
    password: guest #密码
    virtualHost:    #链接的虚拟主机
    addresses: 127.0.0.1:5672     #多个以逗号分隔,与host功能一样。
    requestedHeartbeat: 60 #指定心跳超时,单位秒,0为不指定;默认60s
    publisherConfirms: true  #发布确认机制是否启用
    publisherReturns: #发布返回是否启用
    connectionTimeout: #链接超时。单位ms。0表示无穷大不超时
    ### ssl相关
    ssl:
      enabled: #是否支持ssl
      keyStore: #指定持有SSL certificate的key store的路径
      keyStoreType: #key store类型 默认PKCS12
      keyStorePassword: #指定访问key store的密码
      trustStore: #指定持有SSL certificates的Trust store
      trustStoreType: #默认JKS
      trustStorePassword: #访问密码
      algorithm: #ssl使用的算法,例如,TLSv1.1
      verifyHostname: #是否开启hostname验证
    ### cache相关
    cache:
      channel: 
        size: #缓存中保持的channel数量
        checkoutTimeout: #当缓存数量被设置时,从缓存中获取一个channel的超时时间,单位毫秒;如果为0,则总是创建一个新channel
      connection:
        mode: #连接工厂缓存模式:CHANNEL 和 CONNECTION
        size: #缓存的连接数,只有是CONNECTION模式时生效
    ### listener
    listener:
       type: #两种类型,SIMPLE,DIRECT
       ## simple类型
       simple:
         concurrency: #最小消费者数量
         maxConcurrency: #最大的消费者数量
         transactionSize: #指定一个事务处理的消息数量,最好是小于等于prefetch的数量
         missingQueuesFatal: #是否停止容器当容器中的队列不可用
         ## 与direct相同配置部分
         autoStartup: #是否自动启动容器
         acknowledgeMode: #表示消息确认方式,其有三种配置方式,分别是none、manual和auto;默认auto
         prefetch: #指定一个请求能处理多少个消息,如果有事务的话,必须大于等于transaction数量
         defaultRequeueRejected: #决定被拒绝的消息是否重新入队;默认是true(与参数acknowledge-mode有关系)
         idleEventInterval: #container events发布频率,单位ms
         ##重试机制
         retry: 
           stateless: #有无状态
           enabled:  #是否开启
           maxAttempts: #最大重试次数,默认3
           initialInterval: #重试间隔
           multiplier: #对于上一次重试的乘数
           maxInterval: #最大重试时间间隔
       direct:
         consumersPerQueue: #每个队列消费者数量
         missingQueuesFatal:
         #...其余配置看上方公共配置
     ## template相关
     template:
       mandatory: #是否启用强制信息;默认false
       receiveTimeout: #`receive()`接收方法超时时间
       replyTimeout: #`sendAndReceive()`超时时间
       exchange: #默认的交换机
       routingKey: #默认的路由
       defaultReceiveQueue: #默认的接收队列
       ## retry重试相关
       retry: 
         enabled: #是否开启
         maxAttempts: #最大重试次数
         initialInterval: #重试间隔
         multiplier: #失败间隔乘数
         maxInterval: #最大间隔

2、application.properties

############################ base ############################
spring.rabbitmq.host: 服务Host
spring.rabbitmq.port: 服务端口
spring.rabbitmq.username: 登陆用户名
spring.rabbitmq.password: 登陆密码
spring.rabbitmq.virtual-host: 连接到rabbitMQ的vhost
spring.rabbitmq.addresses: 指定client连接到的server的地址,多个以逗号分隔(优先取addresses,然后再取host)
spring.rabbitmq.requested-heartbeat: 指定心跳超时,单位秒,0为不指定;默认60s
spring.rabbitmq.publisher-confirms: 是否启用【发布确认】
spring.rabbitmq.publisher-returns: 是否启用【发布返回】
spring.rabbitmq.connection-timeout: 连接超时,单位毫秒,0表示无穷大,不超时
 
############################ ssl ############################
spring.rabbitmq.ssl.enabled: 是否支持ssl
spring.rabbitmq.ssl.key-store: 指定持有SSL certificate的key store的路径
spring.rabbitmq.ssl.key-store-password: 指定访问key store的密码
spring.rabbitmq.ssl.trust-store: 指定持有SSL certificates的Trust store
spring.rabbitmq.ssl.trust-store-password: 指定访问trust store的密码
spring.rabbitmq.ssl.trust-store-type: JKS:Trust store 类型
spring.rabbitmq.ssl.algorithm: ssl使用的算法,默认由rabiitClient配置,例如,TLSv1.1
spring.rabbitmq.ssl.validate-server-certificate=true:是否启用服务端证书验证
spring.rabbitmq.ssl.verify-hostname=true 是否启用主机验证
 
############################ cache ############################
spring.rabbitmq.cache.channel.size: 缓存中保持的channel数量
spring.rabbitmq.cache.channel.checkout-timeout: 当缓存数量被设置时,从缓存中获取一个channel的超时时间,单位毫秒;如果为0,则总是创建一个新channel
spring.rabbitmq.cache.connection.size: 缓存的连接数,只有是CONNECTION模式时生效
spring.rabbitmq.cache.connection.mode: 连接工厂缓存模式:CHANNEL 和 CONNECTION
 
############################ listener ############################
spring.rabbitmq.listener.type=simple: 容器类型.simple或direct

spring.rabbitmq.listener.simple.auto-startup: 是否启动时自动启动容器
spring.rabbitmq.listener.simple.acknowledge-mode: 表示消息确认方式,其有三种配置方式,分别是none、manual和auto;默认auto
spring.rabbitmq.listener.simple.concurrency: 最小的消费者数量
spring.rabbitmq.listener.simple.max-concurrency: 最大的消费者数量
spring.rabbitmq.listener.simple.prefetch: 指定一个请求能处理多少个消息,如果有事务的话,必须大于等于transaction数量.
spring.rabbitmq.listener.simple.transaction-size: 指定一个事务处理的消息数量,最好是小于等于prefetch的数量.
spring.rabbitmq.listener.simple.default-requeue-rejected: 决定被拒绝的消息是否重新入队;默认是true(与参数acknowledge-mode有关系)
spring.rabbitmq.listener.simple.missing-queues-fatal=true 若容器声明的队列在代理上不可用,是否失败; 或者运行时一个多多个队列被删除,是否停止容器
spring.rabbitmq.listener.simple.idle-event-interval: 多少长时间发布空闲容器时间,单位毫秒
spring.rabbitmq.listener.simple.retry.enabled: 监听重试是否可用
spring.rabbitmq.listener.simple.retry.max-attempts: 最大重试次数
spring.rabbitmq.listener.simple.retry.initial-interval: 第一次和第二次尝试发布或传递消息之间的间隔
spring.rabbitmq.listener.simple.retry.multiplier: 应用于上一重试间隔的乘数
spring.rabbitmq.listener.simple.retry.max-interval: 最大重试时间间隔
spring.rabbitmq.listener.simple.retry.stateless: 重试是有状态or无状态

spring.rabbitmq.listener.direct.acknowledge-mode= ack模式
spring.rabbitmq.listener.direct.auto-startup=true 是否在启动时自动启动容器
spring.rabbitmq.listener.direct.consumers-per-queue= 每个队列消费者数量.
spring.rabbitmq.listener.direct.default-requeue-rejected= 默认是否将拒绝传送的消息重新入队.
spring.rabbitmq.listener.direct.idle-event-interval= 空闲容器事件发布时间间隔.
spring.rabbitmq.listener.direct.missing-queues-fatal=false若容器声明的队列在代理上不可用,是否失败.
spring.rabbitmq.listener.direct.prefetch= 每个消费者可最大处理的nack消息数量.
spring.rabbitmq.listener.direct.retry.enabled=false  是否启用发布重试机制.
spring.rabbitmq.listener.direct.retry.initial-interval=1000ms # Duration between the first and second attempt to deliver a message.
spring.rabbitmq.listener.direct.retry.max-attempts=3 # Maximum number of attempts to deliver a message.
spring.rabbitmq.listener.direct.retry.max-interval=10000ms # Maximum duration between attempts.
spring.rabbitmq.listener.direct.retry.multiplier=1 # Multiplier to apply to the previous retry interval.
spring.rabbitmq.listener.direct.retry.stateless=true # Whether retries are stateless or stateful.
 
############################ template ############################
spring.rabbitmq.template.mandatory: 启用强制信息;默认false
spring.rabbitmq.template.receive-timeout: receive() 操作的超时时间
spring.rabbitmq.template.reply-timeout: sendAndReceive() 操作的超时时间
spring.rabbitmq.template.retry.enabled: 发送重试是否可用
spring.rabbitmq.template.retry.max-attempts: 最大重试次数
spring.rabbitmq.template.retry.initial-interval: 第一次和第二次尝试发布或传递消息之间的间隔
spring.rabbitmq.template.retry.multiplier: 应用于上一重试间隔的乘数
spring.rabbitmq.template.retry.max-interval: 最大重试时间间隔

02、创建队列附加参数详解

1、Web端查看

20210418110847

2、代码设置

SpringBoot 创建queue设置附加参数(附加参数类型为Map

package com.example.config;

import org.springframework.amqp.core.Queue;
import org.springframework.amqp.core.QueueBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;

/**
 * 简单队列模式
 **/
//@Configuration
public class QueueParamRabbitMQConfig {
    @Bean
    public Queue queue() {
        /**
         * durable:是否持久化,默认是false,持久化队列(内部会有一个actualName: 队列的真实名称,默认用name参数,如果name为空,则根据规则生成一个)
         * exclusive:默认也是false,只能被当前创建的连接使用,而且当连接关闭后队列即被删除。此参考优先级高于durable
         * autoDelete:是否自动删除,当没有生产者或者消费者使用此队列,该队列会自动删除。
         * arguments:设置队列的属性参数
         *  1、x-message-ttl:消息的过期时间,单位:毫秒;
         *  2、x-expires:队列过期时间,队列在多长时间未被访问将被删除,单位:毫秒;
         *  3、x-max-length:队列最大长度,超过该最大值,则将从队列头部开始删除消息;
         *  4、x-max-length-bytes:队列消息内容占用最大空间,受限于内存大小,超过该阈值则从队列头部开始删除消息;
         *  5、x-overflow:设置队列溢出行为。这决定了当达到队列的最大长度时消息会发生什么。有效值是drop-head、reject-publish或reject-publish-dlx。仲裁队列类型仅支持drop-head;
         *  6、x-dead-letter-exchange:死信交换器名称,过期或被删除(因队列长度超长或因空间超出阈值)的消息可指定发送到该交换器中;
         *  7、x-dead-letter-routing-key:死信消息路由键,在消息发送到死信交换器时会使用该路由键,如果不设置,则使用消息的原来的路由键值
         *  8、x-single-active-consumer:表示队列是否是单一活动消费者,true时,注册的消费组内只有一个消费者消费消息,其他被忽略,false时消息循环分发给所有消费者(默认false)
         *  9、x-max-priority:队列要支持的最大优先级数;如果未设置,队列将不支持消息优先级;
         * 10、x-queue-mode(Lazy mode):将队列设置为延迟模式,在磁盘上保留尽可能多的消息,以减少RAM的使用;如果未设置,队列将保留内存缓存以尽可能快地传递消息;
         * 11、x-queue-master-locator:在集群模式下设置镜像队列的主节点信息。
         */
        Map<String, Object> args = new HashMap<>();
        args.put("x-message-ttl", 5000);
        Queue queue = new Queue("ttl.direct.queue", true, false, false, args);
        // 也可以用build模式创建
        Queue build = QueueBuilder.durable("test.queue")
                .exclusive()
                .autoDelete()
                .withArguments(args)
                .build();
        return build;
    }
}
// Java 版本参数可直接参考上面SpringBoot即可
channel.queueDeclare("ttl-queue", false, false, false, arguments);

arguments:设置队列的属性参数

1、x-message-ttl:消息的过期时间,单位:毫秒;

2、x-expires:队列过期时间,队列在多长时间未被访问将被删除,单位:毫秒;

3、x-max-length:队列最大长度,超过该最大值,则将从队列头部开始删除消息;

4、x-max-length-bytes:队列消息内容占用最大空间,受限于内存大小,超过该阈值则从队列头部开始删除消息;

5、x-overflow:设置队列溢出行为。这决定了当达到队列的最大长度时消息会发生什么。
               有效值是drop-head、reject-publish或reject-publish-dlx。仲裁队列类型仅支持drop-head;

6、x-dead-letter-exchange:死信交换器名称,过期或被删除(因队列长度超长或因空间超出阈值)的消息可指定发送到该交换器中;

7、x-dead-letter-routing-key:死信消息路由键,在消息发送到死信交换器时会使用该路由键,
                              如果不设置,则使用消息的原来的路由键值

8、x-single-active-consumer:表示队列是否是单一活动消费者,true时,注册的消费组内只有一个消费者消费消息,
                             其他被忽略,false时消息循环分发给所有消费者(默认false)

9、x-max-priority:队列要支持的最大优先级数;如果未设置,队列将不支持消息优先级;

10、x-queue-mode(Lazy mode):将队列设置为延迟模式,在磁盘上保留尽可能多的消息,以减少RAM的使用;
                              如果未设置,队列将保留内存缓存以尽可能快地传递消息;

11、x-queue-master-locator:在集群模式下设置镜像队列的主节点信息。

03、发送消息附加参数详解

https://blog.csdn.net/u010520146/article/details/103288443
https://blog.csdn.net/yaomingyang/article/details/102636666

1、Web 端查看

20210418110846

2、AMQP.BasicProperties

JAVA版:附加参数类型为:AMQP.BasicProperties

RabbitMQ发布消息的方法为:

void basicPublish(String exchange, String routingKey, BasicProperties props, byte[] body) throws IOException;

其中 props 参数可为消息体赋予多种的功能特性。BasicProperties的属性有以下:

String contentType, //消息内容的类型
String contentEncoding, //消息内容的编码格式
Map<String,Object> headers,//header类型的交换机可以用到
Integer deliveryMode,//消息持久化 1 不持久化 2 持久化
Integer priority,//优先级
String correlationId, //关联id
String replyTo,//通常用于命名回调队列
String expiration,//设置过期消息过期时间
String messageId, //消息id
Date timestamp, //消息的时间戳
String type,  //类型
String userId, //用户ID
String appId, //应用程序id
String clusterId //集群id

参考示例:

Map<String, Object> headers = new HashMap<String, Object>();
headers.put("arg1", "aaa");
AMQP.BasicProperties properties = new AMQP.BasicProperties().builder()
                    .deliveryMode(2) // 传送方式
                    .contentEncoding("UTF-8") // 编码方式
                    .expiration("10000") // 过期时间
                    .headers(headers) //自定义属性
                    .build();

RabbitMQ内部封装的几个方法:

public class MessageProperties {

    /** Empty basic properties, with no fields set */
    public static final BasicProperties MINIMAL_BASIC =
        new BasicProperties(null, null, null, null,
                            null, null, null, null,
                            null, null, null, null,
                            null, null);
    /** Empty basic properties, with only deliveryMode set to 2 (persistent) */
    public static final BasicProperties MINIMAL_PERSISTENT_BASIC =
        new BasicProperties(null, null, null, 2,
                            null, null, null, null,
                            null, null, null, null,
                            null, null);

    /** Content-type "application/octet-stream", deliveryMode 1 (nonpersistent), priority zero */
    public static final BasicProperties BASIC =
        new BasicProperties("application/octet-stream",
                            null,
                            null,
                            1,
                            0, null, null, null,
                            null, null, null, null,
                            null, null);

    /** Content-type "application/octet-stream", deliveryMode 2 (persistent), priority zero */
    public static final BasicProperties PERSISTENT_BASIC =
        new BasicProperties("application/octet-stream",
                            null,
                            null,
                            2,
                            0, null, null, null,
                            null, null, null, null,
                            null, null);

    /** Content-type "text/plain", deliveryMode 1 (nonpersistent), priority zero */
    public static final BasicProperties TEXT_PLAIN =
        new BasicProperties("text/plain",
                            null,
                            null,
                            1,
                            0, null, null, null,
                            null, null, null, null,
                            null, null);

    /** Content-type "text/plain", deliveryMode 2 (persistent), priority zero */
    public static final BasicProperties PERSISTENT_TEXT_PLAIN =
        new BasicProperties("text/plain",
                            null,
                            null,
                            2,
                            0, null, null, null,
                            null, null, null, null,
                            null, null);
}

3、MessageProperties

SpringBoot版:附加参数类型:MessageProperties

可以直接参考源码:org.springframework.amqp.core.MessageProperties,查看内部的字段即可,由于字段太多没有贴出来了。

参考示例:

    /**
     * Headers模式
     */
    @Test
    public void headersSend() {
        MessageProperties messageProperties1 = new MessageProperties();
        messageProperties1.setHeader("header1","value1");
        messageProperties1.setHeader("header11","value11");
        Message message1 = new Message(("Header模式—单个匹配").getBytes(), messageProperties1);
        rabbitTemplate.convertAndSend("header_exchange","",message1);

        MessageProperties messageProperties2 = new MessageProperties();
        messageProperties2.setHeader("header2","value2");
        messageProperties2.setHeader("header22","value22");
        Message message2 = new Message(("Header模式—全部匹配").getBytes(), messageProperties2);
        rabbitTemplate.convertAndSend("header_exchange","",message2);
    }

    /**
     * TTL过期时间测试——对消息本身设置过期时间
     * 测试发送后查看web页面,5秒后消息自动消失了
     */
    @Test
    public void ttlMessageDirectSend() {
        MessagePostProcessor messagePostProcessor = message -> {
            MessageProperties messageProperties = message.getMessageProperties();
            messageProperties.setExpiration("5000");
            messageProperties.setContentEncoding("UTF-8");
            return message;
        };
        rabbitTemplate.convertAndSend("ttl_direct_exchange","ttl.message","TTL-消息过期时间", messagePostProcessor);
    }

04、@RabbitListener 详解

case1:exchange_queue 已存在

package com.example.config;

import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.stereotype.Component;

@Component
public class AutoCreateQueueExchange {

    /**
     * 队列和交换机已经存在,只用使用queues,消费指定的queue即可.
     * 可以单独监听一个或者多个队列。如下只用其一即可
     * queues参数值为对列名(queueName)
     */
    //@RabbitListener(queues = {"exist.queue1", "exist.queue2"})
    @RabbitListener(queues = "simple.queue")
    public void receive1(String msg){
    }

    /**
     * 单独声明队列
     */
    //@RabbitListener(queuesToDeclare = {@Queue(value = "queue1"),@Queue(value = "queue2")})
    @RabbitListener(queuesToDeclare = @Queue(value = "declare.queue"))
    public void receive2(String msg){
    }
}

case2:exchange_queue 不存在

    /**
     * 发布/订阅模式 Fanout
     * @QueueBinding 注解的三个属性
     *   value: @Queue注解用于声明队列,value:queueName,durable: 队列是否持久化,autoDelete: 否自动删除
     *   exchange: @Exchange 注解,用于声明 exchange, type 指定消息投递策略,我们这里用的 fanout 方式
     *   key: 这个就是我们熟知的 routingKey,在fanout方式下是没有routingKey的
     */
    @RabbitHandler
    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue(value = "fanout.queue1",durable = "true", autoDelete = "false"),
                    exchange = @Exchange(value = "fanout.exchange1", type = ExchangeTypes.FANOUT)
            )
    })
    public void receive3(String msg){
    }

    /**
     * 路由模式 Direct
     * @QueueBinding 注解的三个属性
     *   value: @Queue注解用于声明队列,value:queueName,durable: 队列是否持久化,autoDelete: 否自动删除
     *   exchange: @Exchange 注解,用于声明 exchange, type 指定消息投递策略,我们这里用的 fanout 方式
     *   key: 这个就是我们熟知的 routingKey,在fanout方式下是没有routingKey的
     * 注意:由于@Exchange 中 type默认值就是DIRECT,所以可以省略:type = ExchangeTypes.DIRECT
     */
    @RabbitHandler
    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue(value = "direct.queue1", durable = "true", autoDelete = "false"),
                    exchange = @Exchange(value = "direct.exchange1"),
                    key = "direct.key1"
            )
    })
    public void receive4(String msg){
    }

    /**
     * 主题模式 Topic—单个申请
     */
    @RabbitHandler
    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue(value = "topic.queue1",autoDelete = "false"),
                    exchange = @Exchange(value = "topic.exchange1", type = ExchangeTypes.TOPIC),
                    key = "topic.key1"
            )
    })
    public void receive5(String msg){
    }

    /**
     * 主题模式 Topic—多个申请
     */
    @RabbitHandler
    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue(value = "topic.queue1",autoDelete = "false"),
                    exchange = @Exchange(value = "test.exchange1", type = ExchangeTypes.TOPIC),
                    key = "topic.key1"
            ),
            @QueueBinding(
                    value = @Queue(value = "topic.queue2",autoDelete = "false"),
                    exchange = @Exchange(value = "test.exchange1", type = ExchangeTypes.TOPIC),
                    key = "topic.key2"
            )
    })
    public void receive6(String msg){
    }

    /**
     * Headers 模式
     */
    @RabbitHandler
    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue(value = "headers.queue1",autoDelete = "false"),
                    exchange = @Exchange(value = "headers.exchange1", type = ExchangeTypes.HEADERS),
                    arguments = {
                            @Argument(name = "x-match", value = "any"),
                            @Argument(name = "key-one", value = "1"),
                            @Argument(name = "key-two", value = "2")
                    }
            )
    })
    public void receive7(String msg){
    }

case3:延迟队列+死信队列声明

    /**
     * 声明延迟队列。并绑定死信交换机。
     * 设置延迟队列消息超过5秒就过期,并且消息最大条数为3条。超过了也会成为死信消息。
     * 并且开启了 消息手动确认ack模式
     */
    @RabbitHandler
    @RabbitListener(ackMode = "MANUAL",bindings = {
            @QueueBinding(value = @Queue(value = "liveQueue", arguments = {
                          @Argument(name = "x-dead-letter-exchange", value = "deadExchange"),
                          @Argument(name = "x-dead-letter-routing-key", value = "deadKey"),
                          @Argument(name = "x-message-ttl", value = "5000", type = "java.lang.Integer"),
                          @Argument(name = "x-max-length",value = "3",type = "java.lang.Integer")
                    }),
                    exchange = @Exchange(value = "liveExchange"),
                    key = {"info", "error", "warning"}
            )
    })
    public void onMessage1(String msg, Message message, Channel channel) throws IOException {
        long consumerTag = message.getMessageProperties().getDeliveryTag();
        try {
            // 模拟消费消息, 回调接收ack是true 因为回调的ack根据exchange是否收到消息判断
            int i = 1/new Random().nextInt(1);
            System.out.println("收到消息:" + new String(message.getBody()));
            channel.basicAck(consumerTag, false);
        } catch (Exception e) {
            // 消费异常消息会添加到死信队列
            channel.basicNack(consumerTag, false, false);
        }
    }

    /**
     * 声明死信交换机和队列 并且绑定
     */
    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue(value = "deadQueue"),
                    exchange = @Exchange(value = "deadExchange"),
                    key = "deadKey"
            )
    })
    public void onMessage2(Message message, Channel channel) throws IOException {
        System.out.println("我是一条死信队列:" + message);
        long consumerTag = message.getMessageProperties().getDeliveryTag();
        channel.basicAck(consumerTag, true);
    }

case4:手动 Ack + 并发消费

当消息很多,一个消费者吭哧吭哧的消费太慢,但是我的机器性能又杠杠的,这个时候我就希望并行消费,相当于同时有多个消费者来处理数据。要支持并行消费,如下设置即可

    /**
     * 手动ack:ackMode = "MANUAL"
     * 注意:
     * @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag
     * 替代了 参数 Message message
     * long deliveryTag = message.getMessageProperties().getDeliveryTag();
     */
    @RabbitHandler
    @RabbitListener(queues = "simple.queue", ackMode = "MANUAL")
    public void consumerDoAck(String msg, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag,
                              Channel channel) throws IOException {
        if (msg.contains("ok")) {
            channel.basicAck(deliveryTag, false);
        } else {
            channel.basicNack(deliveryTag, false, true);
        }
    }

    /**
     * 并发消费。注意:concurrency = "4"属性,表示固定 4 个消费者;
     */
    @RabbitHandler
    @RabbitListener(queues = "simple.queue", concurrency = "4")
    public void multiConsumer(String data) {
        System.out.println("multiConsumer: " + data);
    }

05、@RabbitListener+@RabbitHandler

自己查资料研究:https://blog.csdn.net/weixin_43343423/article/details/103382661

参与评论 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:大白 设计师:CSDN官方博客 返回首页

打赏作者

路面烧卖

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值