实现异步消费队列


参考文档:https://blog.csdn.net/u014373554/article/details/109473443

使用阻塞队列+线程池实现异步消费

1. 定义任务队列

/**
 * 定义队列
 */
private static LinkedBlockingDeque<String> deque = new LinkedBlockingDeque<>();

2. 定义线程池(单例、单线程)

  • 线程池只可以有单个线程,这样才可以保证消费队列内容时是顺序的,多线程时会导致重复消费。

  • 线程池需要使用常量存放,避免每次使用时创建新的线程池,而变成多个线程并发操作,也会导致重复消费。

/**
 * 消费者,单一线程, 进行处理业务逻辑
 */
public static final ExecutorService EXECUTOR_SERVICE = Executors.newSingleThreadExecutor();

3. 存储任务和顺序消费逻辑

/**
 * 模拟数据库存放数据,并保证不重复
 */
private List<String> strList = new ArrayList<>();

/**
 * 服务请求生成任务存放至队列,并调用线程消费队列
 */
@PostMapping("/process")
public void process(String equipmentNo)  &#123;
    if (StringUtils.isEmpty(equipmentNo)) &#123;
        log.info("参数不能为空");
    &#125;
    try &#123;
        if(deque.remainingCapacity() > 0)&#123;
            deque.put(equipmentNo);
        &#125;else &#123;
            log.info("队列已经满了,请稍后重试");
        &#125;

        EXECUTOR_SERVICE.submit(() ->&#123;
            //开始处理请求队列中的请求,按照队列的FIFO的规则,先处理先放入到队列中的请求
            while (deque != null && deque.size() > 0)&#123;
                //处理请求
                try &#123;
                    String orderNo = deque.take();
                    if(!strList.contains(orderNo))&#123;
                        log.info("处理订单号:&#123;&#125;",orderNo);
                        strList.add(orderNo);
                    &#125;
                &#125; catch (InterruptedException e) &#123;
                    log.info("处理订单号发生异常,异常信息:&#123;&#125;",e);
                &#125;
            &#125;
        &#125;);
    &#125; catch (InterruptedException e) &#123;
        log.info("处理发生异常,异常信息:&#123;&#125;",e);
    &#125;
&#125;

@GetMapping("/query")
public List<String> query()  &#123;
    log.info("获取strList");
    return strList;
&#125;
  • Executors.newSingleThreadExecutor() 线程池中只有一个线程,而线程中队列是无界队列,如果短时间生产大量任务,可能会导致内存溢出

使用 Jmeter 进行并发测试

官网下载地址

下载 Binaries 文件,解压后运行 jmeter.bat 即可启动 jmeter 程序

  1. 打开程序后,在当前测试项目下,添加线程组,并配置并发数量和启动时间
  2. 在当前线程组下,添加 HTTP 请求信息,可以配置请求信息(地址、参数等)
  3. 在当前测试项目下,添加测试报告,显示并发测试信息

文章作者: shone
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 shone !
评论
 上一篇
Spring ApplicationEvent 事件 Spring ApplicationEvent 事件
事件机制在一些大型项目中被经常使用,Spring 专门提供了一套事件机制的接口,满足了架构原则上的解耦。 ApplicationContext 通过 ApplicationEvent 类和 ApplicationListener 接口进行事
2023-02-02
下一篇 
FutureTask FutureTask
2023-02-02 shone
  目录