SpringBoot2.x下RabbitMQ的并发参数(concurrency和prefetch)

点击上方“猿芯”,选择“设为星标

后台回复"1024",有份惊喜送给面试的你

RabbitMQ消费端配置

spring:
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest
    listener:
      simple:
#        acknowledge-mode: manual  # 手动确定(默认自动确认)
        concurrency: 1 # 消费端的监听个数(即@RabbitListener开启几个线程去处理数据。)
        max-concurrency: 10 # 消费端的监听最大个数
        prefetch: 10
    connection-timeout: 15000   # 超时时间

在消费端,配置prefetchconcurrency参数便可以实现消费端MQ并发处理消息,那么这两个参数到底有什么含义??

1. prefetch

每个customer会在MQ预取一些消息放入内存的LinkedBlockingQueue中,这个值越高,消息传递的越快,但非顺序处理消息的风险更高。如果ack模式为none,则忽略。如有必要,将增加此值以匹配txSize或messagePerAck。从2.0开始默认为250;设置为1将还原为以前的行为。

prefetch默认值以前是1,这可能会导致高效使用者的利用率不足。从spring-amqp 2.0版开始,默认的prefetch值是250,这将使消费者在大多数常见场景中保持忙碌,从而提高吞吐量。

不过在有些情况下,尤其是处理速度比较慢的大消息,消息可能在内存中大量堆积,消耗大量内存;以及对于一些严格要求顺序的消息,prefetch的值应当设置为1。

对于低容量消息和多个消费者的情况(也包括单listener容器的concurrency配置)希望在多个使用者之间实现更均匀的消息分布,建议在手动ack下并设置prefetch=1

模拟:
生产者每次生产10条消息:

spring:
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest
    publisher-confirms: true
    publisher-returns: true
@RestController
public class RabbitMQController {
    @Autowired
    private RabbitTemplate rabbitTemplate;
    //直接向队列中发送数据
    @GetMapping("send")
    public String send() {
        for (int i = 0; i < 10; i++) {
            String content = "Date:" + System.currentTimeMillis();
            content = content + ":::" + i;
            rabbitTemplate.convertAndSend("kinson", content);
        }
        return "success";
    }
}

控制页面:

 

消费端直接预取了10条消息.png

2. concurrency

上面配置中,concurrency =1,即每个Listener容器将开启一个线程去处理消息。

在2.0版本后,可以在注解中配置该参数:

@Component
@Slf4j
public class CustomerRev {
  //会覆盖配置文件中的参数。
    @RabbitListener(queues = {"kinson"},concurrency =   "2")
    public void receiver(Message msg, Channel channel) throws InterruptedException {

//        Thread.sleep(10000);
        byte[] messageBytes = msg.getBody();

        if (messageBytes != null && messageBytes.length > 0) {
            //打印数据
            String message = new String(msg.getBody(), StandardCharsets.UTF_8);
            log.info("【消3】:{}", message);
        }
    }

}

启动服务:

 

可以看到MQ有两个消费者.png

即该Listener容器产生了两个线程去消费queue。如果在Listener配置了exclusive参数,即确定此容器中的单个customer是否具有对队列的独占访问权限。如果为true,则容器的并发性必须为1。

 


 

往期推荐

 

  1. 肝九千字长文 | MyBatis-Plus 码之重器 lambda 表达式使用指南,开发效率瞬间提升80%

  2. 用 MHA 做 MySQL 读写分离,频繁爆发线上生产事故后,泪奔分享 Druid 连接池参数优化实战

  3. 微服务架构下,解决数据库跨库查询的一些思路

  4. 一文读懂阿里大中台、小前台战略

作者简介猿芯,一枚简单的北漂程序员。喜欢用简单的文字记录工作与生活中的点点滴滴,愿与你一起分享程序员灵魂深处真正的内心独白。我的微信号:WooolaDunzung,公众号【猿芯输入 1024 ,有份面试惊喜送给你哦

< END >

【猿芯】

 微信扫描二维码,关注我的公众号。

分享不易,莫要干想,如果觉得有点用的话,动动你的发财之手,一键三连击:分享、点赞、在看,你们的鼓励是我分享优质文章的最强动力 ^_^

分享、点赞、在看,3连3连!

<think> 我们正在讨论Spring Boot 3.x版本下RabbitMQ的YML配置。根据之前的上下文,用户已经引用了两个关于RabbitMQ配置的示例(引用[1]引用[2]),但这些都是针对Spring Boot 2.x版本的。在Spring Boot 3.x中,一些配置项可能有所变化。 特别要注意的是,在引用[2]中提到了一个变化:在Spring Boot 2.x中,我们使用`publisher-confirms``publisher-returns`,但在新版本中,推荐使用`publisher-confirm-type`。 因此,在Spring Boot 3.x中,RabbitMQ配置应该使用新的配置项。下面是一个完整的Spring Boot 3.x的RabbitMQ配置示例(application.yml格式): ```yaml spring: rabbitmq: host: localhost # RabbitMQ服务器主机 port: 5672 # 端口 username: guest # 用户名 password: guest # 密码 virtual-host: / # 虚拟主机 # 连接池配置(可选) connection-timeout: 5s # 连接超时时间 # 生产者相关配置(消息确认) publisher-confirm-type: correlated # 确认模式:correlated(关联的)表示发布消息到交换器后触发回调 publisher-returns: true # 开启返回模式(当消息无法路由到队列时触发回调) # 消费者相关配置 listener: type: simple # 监听器类型:simple(简单监听器)或direct(直接监听器) simple: acknowledge-mode: manual # 手动确认(也可设置为auto自动确认,none不确认) prefetch: 1 # 每次预取的消息数量 concurrency: 1 # 最小消费者数量 max-concurrency: 1 # 最大消费者数量 default-requeue-rejected: true # 默认重新入队被拒绝的消息(当抛出异常时) retry: # 重试机制 enabled: true # 开启重试 max-attempts: 3 # 最大重试次数 initial-interval: 1000ms # 初始重试间隔 multiplier: 1.0 # 间隔乘数 max-interval: 3000ms # 最大重试间隔 # 模板相关配置(用于发送消息) template: retry: # 发送消息的重试配置 enabled: true # 开启重试 max-attempts: 3 # 最大重试次数 initial-interval: 1000ms # 初始重试间隔 multiplier: 1.0 # 间隔乘数 max-interval: 3000ms # 最大重试间隔 ``` ### 配置说明: 1. **`publisher-confirm-type`**(取代了旧版的`publisher-confirms`)有三种取值: - `none`:禁用发布确认(默认) - `simple`:同步等待确认(会阻塞) - `correlated`:异步关联确认(使用回调) 2. **消费者确认模式**(`acknowledge-mode`): - `manual`:手动确认(需要在代码中调用`channel.basicAck`等) - `auto`:自动确认(Spring会在监听方法执行成功后自动确认) - `none`:不确认(RabbitMQ自动确认,消息被发送后即认为成功) 3. **重试机制**: - 消费者重试(`listener.simple.retry`):当消费者处理消息抛出异常时,会进行重试(在应用内重试,不是重新入队) - 生产者重试(`template.retry`):当消息发送失败时,会进行重试(网络问题等) 4. **其他配置**: - `virtual-host`:虚拟主机,默认为`/` - `connection-timeout`:连接超时时间,Spring Boot 3.x允许使用`Duration`格式(如5s) ### 注意事项: - 在Spring Boot 3.x中,配置项命名规范遵循小写字母横杠分隔(kebab-case)。 - 关于消费者并发设置:`concurrency``max-concurrency`用于控制消费者容器的并发线程数。 - 重试机制中的`multiplier`表示间隔乘数,例如1.0表示每次重试间隔不变,2.0表示每次间隔加倍。 ### 代码中使用: 在生产者端,你需要配置`RabbitTemplate`来支持确认返回。在消费者端,你需要使用`@RabbitListener`并手动确认(如果使用`manual`模式)。 生产者配置示例(如果需要,可以注入RabbitTemplate并设置ConfirmCallbackReturnCallback): ```java @Configuration public class RabbitConfig { @Bean public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) { RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory); rabbitTemplate.setMandatory(true); // 开启强制消息推送(确保消息路由失败时能触发ReturnCallback) // 设置确认回调 rabbitTemplate.setConfirmCallback((correlationData, ack, cause) -> { if (ack) { System.out.println("消息发送到交换器成功:" + correlationData); } else { System.out.println("消息发送到交换器失败:" + cause); } }); // 设置返回回调(当消息无法路由到队列时触发) rabbitTemplate.setReturnsCallback(returned -> { System.out.println("消息路由到队列失败:消息=" + new String(returned.getMessage().getBody()) + ", 回应码=" + returned.getReplyCode() + ", 回应内容=" + returned.getReplyText() + ", 交换器=" + returned.getExchange() + ", 路由键=" + returned.getRoutingKey()); }); return rabbitTemplate; } } ``` 消费者手动确认示例: ```java @Component public class MyMessageListener { @RabbitListener(queues = "myQueue") public void handleMessage(String message, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag) throws IOException { try { // 处理消息 System.out.println("收到消息:" + message); // 手动确认(multiple=false表示只确认当前消息) channel.basicAck(deliveryTag, false); } catch (Exception e) { // 拒绝消息(requeue=true表示重新入队) channel.basicReject(deliveryTag, true); } } } ``` 以上配置代码适用于Spring Boot 3.x版本。请注意,根据实际需求调整配置值。 ### 参考来源: - 引用[2]中提到的配置变化(`publisher-confirm-type`替代`publisher-confirms`)已经在示例中体现[^2]。 - 引用[3]提醒我们Spring Boot 3.x是一个新的时代,配置可能有所更新[^3]。 §§相关问题§§ 1.Spring Boot 3.x中,如何实现RabbitMQ消息的延迟队列2. RabbitMQSpring Boot 3.x中如何配置多虚拟主机(Virtual Host)? 3. 如何监控Spring Boot 3.x应用中RabbitMQ的健康状况? </think> ### Spring Boot 3.x 中 RabbitMQ 的完整 YML 配置指南 #### 一、核心配置项(基于 Spring Boot 3.x 语法) ```yaml spring: rabbitmq: # 基础连接配置 host: localhost port: 5672 username: guest password: guest virtual-host: / # 虚拟主机路径 # 生产者配置Spring Boot 3.x 新语法) publisher-confirm-type: correlated # 替换旧版 publisher-confirms[^2] publisher-returns: true # 消费者配置 listener: type: simple # 监听器类型 simple: acknowledge-mode: manual # 确认模式:manual/auto/none concurrency: 1 # 最小消费者数 max-concurrency: 5 # 最大消费者数 prefetch: 10 # 每次预取消息数 retry: enabled: true # 开启消费重试 max-attempts: 3 # 最大重试次数 initial-interval: 2000ms # 初始间隔 # 模板配置(生产者重试) template: retry: enabled: true initial-interval: 1000ms max-attempts: 3 max-interval: 5000ms multiplier: 1.5 # 高级配置 connection-timeout: 5s # 连接超时时间 requested-heartbeat: 60s # 心跳间隔 ``` #### 二、关键配置说明 1. **确认机制升级** Spring Boot 3.x 使用 `publisher-confirm-type` 替代旧版 `publisher-confirms`[^2],可选值: - `none`:禁用确认 - `simple`:同步等待确认 - `correlated`:异步回调确认(推荐) 2. **消费重试策略** 消息处理失败时的重试配置: ```yaml listener: simple: retry: enabled: true max-attempts: 5 max-interval: 10s multiplier: 2 # 间隔时间倍增因子 ``` 3. **并发控制** 动态调整消费者数量: ```yaml concurrency: 2 # 初始消费者数 max-concurrency: 10 # 最大消费者数 prefetch: 20 # 单次预取消息量 ``` #### 三、多环境配置示例 ```yaml # 开发环境 --- spring: config: activate: on-profile: dev rabbitmq: host: dev-rabbitmq port: 5672 listener.simple.concurrency: 3 # 生产环境 --- spring: config: activate: on-profile: prod rabbitmq: host: prod-rabbitmq-cluster port: 5671 virtual-host: /prod listener.simple.concurrency: 10 publisher-confirm-type: correlated ``` #### 四、Java 代码集成示例 ```java // 生产者配置(使用ConfirmCallback) @Bean public RabbitTemplate rabbitTemplate(ConnectionFactory factory) { RabbitTemplate template = new RabbitTemplate(factory); template.setConfirmCallback((correlation, ack, reason) -> { if(!ack) logger.error("消息投递失败: {}", reason); }); return template; } // 消费者配置(手动ACK) @RabbitListener(queues = "orders") public void handleOrder(Order order, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long tag) { try { processOrder(order); // 业务处理 channel.basicAck(tag, false); // 手动确认 } catch (Exception e) { channel.basicReject(tag, true); // 重新入队 } } ``` #### 五、注意事项 1. **配置兼容性** Spring Boot 3.x 不再支持以下旧配置: ```diff - publisher-confirms: true + publisher-confirm-type: correlated ``` 2. **健康检查配置** 启用健康端点监控: ```yaml management: health: rabbits: enabled: true timeout: 10s ``` 3. **SSL 安全连接** ```yaml spring: rabbitmq: ssl: enabled: true verify-hostname: false port: 5671 ``` > **最佳实践**:建议使用 `spring.config.import` 分离配置[^3]: > ```yaml > spring: > config: > import: > - rabbitmq-config.yml > ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值