rabbitMq设置多线程并设置线程池消费处理

本文详细介绍了 RabbitMQ 中消费者配置项的作用及应用场景,特别是如何通过调整并发消费者数量和预取计数来优化消息处理流程。适用于需要长时间处理的文件转换任务或高并发的短信发送场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第一步,先写配置

@Configuration
public class RabbitmqConfig {
    @Bean("batchQueueRabbitListenerContainerFactory")
    public RabbitListenerContainerFactory<?> rabbitListenerContainerFactory(ConnectionFactory connectionFactory){
        SimpleRabbitListenerContainerFactory factory = new SimpleRabbitListenerContainerFactory();
        factory.setConnectionFactory(connectionFactory);
        factory.setMessageConverter(new Jackson2JsonMessageConverter());
        //确认方式,manual为手动ack.
        factory.setAcknowledgeMode(AcknowledgeMode.MANUAL);
        //每次处理数据数量,提高并发量
        //factory.setPrefetchCount(250);
        //设置线程数
        //factory.setConcurrentConsumers(30);
        //最大线程数
        //factory.setMaxConcurrentConsumers(50);
        /* setConnectionFactory:设置spring-amqp的ConnectionFactory。 */
        factory.setConnectionFactory(connectionFactory);
        factory.setConcurrentConsumers(1);
        factory.setPrefetchCount(1);
        //factory.setDefaultRequeueRejected(true);
        //使用自定义线程池来启动消费者。
        factory.setTaskExecutor(taskExecutor());
        return factory;
    }

    @Bean("correctTaskExecutor")
    @Primary
    public TaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 设置核心线程数
        executor.setCorePoolSize(100);
        // 设置最大线程数
        executor.setMaxPoolSize(100);
        // 设置队列容量
        executor.setQueueCapacity(0);
        // 设置线程活跃时间(秒)
        executor.setKeepAliveSeconds(300);
        // 设置默认线程名称
        executor.setThreadNamePrefix("thread-file-queue");
        // 设置拒绝策略rejection-policy:当pool已经达到max size的时候,丢弃
        // executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
        // 等待所有任务结束后再关闭线程池
        executor.setWaitForTasksToCompleteOnShutdown(true);
        return executor;
    }
}

主要看这两个配置 

factory.setConcurrentConsumers(1);

factory.setPrefetchCount(1); 

如果设置为1,在消费的时候线程池就会开启多个线程来消费进行,意思就是一个线程只消费一条消息,这种适于消费时间处理长,处理的流程比较复杂,这种例如文件转换,需要时间

如果是大于1的,看具体设置的值,比如50,那每个线程就会消费50个消息,等到消息满了,才会开启其他线程来消费,这种适用于高并发的情况,消费时间短,消费量很大,比如发短信

消费者配置 

@RabbitListener(queues = "${xx.queue}", containerFactory = "batchQueueRabbitListenerContainerFactory") //指定上面配置的连接bean对象
@RabbitHandler
public void handlexxxQueue(@Payload Media media, Message message, Channel channel) throws IOException, InterruptedException {
    //提交单条消息
    channel.basicAck(deliveryTag, false);
}
### RabbitMQ消费者线程模型 在 RabbitMQ 中,消费者处理方式取决于应用程序如何配置和实现消费逻辑。当创建一个新的 `Channel` 调用诸如 `basicConsume` 方法时,会启动一个用于接收消息的消费者实例[^1]。 对于每个 Channel 上注册的消费者而言,默认情况下不是单一线程来处理所有传入的消息。相反,在同一连接下的不同 Channels 可能由不同的操作系统线程负责监听来自服务器的通知分发给相应的回调函数执行业务逻辑。这意味着即使是在同一个物理 TCP 连接上建立起来的多个 Channels 也可以发地处理各自收到的任务项[^2]。 然而需要注意的是,虽然可以有多个 Consumers 同时运行在一个 Connection 下的不同 Channels 上,但对于特定 Consumer 来说其内部确实是以串行的方式逐条确认已成功处理过的每一条 Message——即每次只有一条未被应答的消息处于待处理状态直到它完成之后才会继续拉取下一批数据进入内存缓冲区等待进一步操作[^3]。 因此可以说: - **不是严格意义上的单线程模型**:因为可以在多核 CPU 或者分布式环境中通过开启更多 Connections/Channels 实现真正的行化; - **但就单一 Consumer 而言又是相对独立且有序的一系列事件驱动过程**,这有助于简化编程复杂度同时也保证了一定程度上的事务一致性[^4]。 ```csharp // C# 示例代码展示如何设置基本消费者 var consumer = new EventingBasicConsumer(channel); consumer.Received += (model, ea) => { var body = ea.Body.ToArray(); string message = Encoding.UTF8.GetString(body); Console.WriteLine($"Received {message}"); }; channel.BasicConsume(queue: "queue_name", autoAck: true, consumer: consumer); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一名陈序员

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

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

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

打赏作者

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

抵扣说明:

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

余额充值