记一次优化线程池的maxPoolSize来提高接口的QPS

前言

项目中有一个逻辑是消费kafka消息,然后调用下游接口处理逻辑,作者在用kafka处理消息的时候,通过google的rateLimiter.acquire()方法来达到接口限流的目的,但是发现,之后无论如何增大RateLimiter.create方法中的permitsPerSecond参数,接口QPS都没有变化,于是就有了下面的一系列猜测+验证的解决方法。

猜测+验证

首先可以从自己应用到的组件开始排查,然后定位到大概的地方,优化并验证。

比如:
在项目中的kafka消费端,有以下线程池的应用

@Autowired
private ThreadPoolTaskExecutor taskExecutor;

 // 异步执行
 try {
      taskExecutor.execute(() -> dosomething());
 } catch (Exception e) {
      log.error("execute# 处理dosomething方法发送线程池打满了", e);
  }

于是查看线程池的配置:

@Bean
public ThreadPoolTaskExecutor taskExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(5);
    executor.setKeepAliveSeconds(60);
    executor.setMaxPoolSize(20);
    executor.setQueueCapacity(1000);
    executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
    return executor;
}

线程池的核心数为5,最大线程数为20,队列数量为1000,我猜想是不是有可能线程任务在排队导致处理不过来,从而导致接口的QPS上不去,于是又查看了下调用下游接口的QPS:
记一次优化线程池的maxPoolSize来提高接口的QPS_第1张图片
发现的接口的RPS高峰稳定在1700左右,而我机器的集群QPS配置的是3600,少了一半的量,然后看了下kafka的消费者容器的并发数,根据接口的耗时,也就是1s处理请求的个数 * 我们机器的数量 * kafka的并发数 * 线程池的maxPoolSize等于1700左右,所以猜测是跟线程池的maxPoolSize的大小和下游接口耗时有关系,下游接口耗时没办法优化,于是我将线程池的maxPoolSize改成动态配置(nacos或者apollo)便于动态调整该参数,
将参数调大后,发现调用接口的QPS上来了,
记一次优化线程池的maxPoolSize来提高接口的QPS_第2张图片
高峰QPS稳定在2500左右,问题得已解决

总结

以上问题首先可以根据自己项目的逻辑用到了哪些组件,然后根据这些组件去排查,大概定位到是哪些地方出了问题,然后根据自己的猜测,列举几种解决方案,逐一去尝试,可能问题的答案就在其中,希望以上经验可以帮助到你!!!

你可能感兴趣的:(Java实用型,java,kafka,线程池)