线程池解决RabbitMQ消息堆积

引言

并发量非常大,服务器处理不够及时导致消息堆积的问题是很常见的。上篇文章简单的描述演示了一种解决方案就是增加消费者,提高消息处理速度,使用的是AMQP提供的监听器工厂SimpleRabbitListenerContainerFactory,本篇文章演示另一种方式,在消费者中开启线程池加快消息处理速度。

线程池ThreadPoolExecutor

Java.util提供的ThreadPoolExecutor有七个核心参数

  • corePoolSize 核心线程数
  • maximumPoolSize 最大线程数=核心线程数+备用线程数
  • keepAlivetime 备用线程的生存时间
  • unit 备用线程的生存时间
  • workWueue 阻塞队列
  • threadFactory 线程工厂,定义线程对象的创建
  • handler 拒绝策略 当最大线程数达到并且阻塞队列也满时,会触发拒绝策略。

线程池的种类有四种

固定线程数的线程池:newFixedThreadPool(int Threads)

特点:

  • 核心线程数与最大线程数一样,不存在备用线程
  • 阻塞队列是LinkedBlockingQueue,最大容量为Integer.MAX_VALUE

单线程化的线程池:newSingleThreadExecutor()

只使用为一的工作线程来执行任务,保证所有任务按照指定顺序执行FIFO

特点:

  • 核心线程数和最大线程数都是1
  • 阻塞队列是LinkedBlockingQueue,最大容量为Integer.MAX_VALUE

可缓存线程池:newCachedThreadPool()

特点:

  • 核心线程数为0
  • 最大线程数是Integer.MAX_VALUE
  • 阻塞队列为SynchronousQueue:不存储元素的阻塞队列,每个插入操作都需要等待一个移出操作

具有延迟和周期性执行:newScheduledThreadPoolExecutor(int corePoolSize)

可以执行延迟任务,支持定时以及周期性操作。

环境配置(参考上篇文章)

定义线程池

使用Spring提供的ThreadPoolTaskExecutor

package cn.itcast.mq.thread;


import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.boot.autoconfigure.amqp.SimpleRabbitListenerContainerFactoryConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.*;

@Configuration
@EnableAsync
public class ThreadPoolConfig {

 
    /*定义线程池,提供多个线程消费消息
    */

    @Bean("pooltoconsumer")
    public ThreadPoolTaskExecutor pooltoconsumer()
    {
//
        ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
        threadPoolTaskExecutor.setCorePoolSize(8);
        threadPoolTaskExecutor.setMaxPoolSize(20);
        threadPoolTaskExecutor.setQueueCapacity(100);
        threadPoolTaskExecutor.setKeepAliveSeconds(3);
        threadPoolTaskExecutor.setThreadNamePrefix("开启多个线程消费消息----");
        threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.AbortPolicy());
        threadPoolTaskExecutor.initialize();
        return threadPoolTaskExecutor;
    }
}

 修改MQ监听器

    @Async("pooltoconsumer")
    @RabbitListener(bindings = @QueueBinding(value = @Queue(name="demo.queue2"),exchange = @Exchange(name = "direct",type = ExchangeTypes.DIRECT),key = {"川菜"}) )
    public void chuancai(String msg)
    {
        //拆分消息
        String[] split = msg.split(":");
        order order = new order(split[0], split[1]);
        System.out.println(order.toString());
        //保存MYSQL
        orderService.save(order);

        //测试是否多个消费者
        System.out.println("线程" + Thread.currentThread().getName() + " 执行异步任务" +"----"+"川菜"+"----"+split[1]);

    }

使用JMeter压测,查看结果,成功!

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值