【问题标题】:ExecutorService slow and hung sometimeExecutorService 缓慢并有时挂起
【发布时间】:2020-08-01 06:37:46
【问题描述】:

我正在调用多个rest API,为此我使用ExecutorService 进行并行处理。消费者每秒点击我的应用程序超过 10 次,我观察到 ExecutorService 响应非常缓慢。我已经使用 tomcat Web 服务器在kubernetes 上部署了我的应用程序。 下面是我的代码,不知道是什么原因导致它变慢。

   ExecutorService WORKER_THREAD_POOL = Executors.newFixedThreadPool(100);

            Collection tasks = new ArrayList();
  for( String str: datalist){
 tasks.add(new MyThreadPool(str)); // MyThreadPool internally calls the REST API using Google HttpRequest.
}
 List<Future<BasePolicy>> futures = null;
            try {
                long startProcessingTime = System.currentTimeMillis();
                futures = WORKER_THREAD_POOL.invokeAll(tasks);
                WORKER_THREAD_POOL.shutdown();

                if (!WORKER_THREAD_POOL.awaitTermination(60000, TimeUnit.SECONDS)) {
                    WORKER_THREAD_POOL.shutdownNow();
                }

                long totalProcessingTime = System.currentTimeMillis() - startProcessingTime;
                log.info("total time to complete the thread pool- " + totalProcessingTime);
            } catch (InterruptedException e) {
                log.error("error occured during ASYNC process ");
                e.printStackTrace();
            }
            log.info("Finished Waiting All threads completed ");
            for (Future<Data> mFuture : futures) {
               // my logic 
            }

【问题讨论】:

  • 我相信可能是外部服务没有快速响应。您是否检查了从外部服务获得响应需要多长时间?。
  • @harry,我的后端休息服务响应速度很快,我已经设置并验证了计时器。如果我一次收到一个请求,它只有在多个请求到达我的服务时才有效,那么我会看到缓慢和挂起的问题

标签: java multithreading kubernetes executorservice threadpoolexecutor


【解决方案1】:

我观察到 ExecutorService 的响应速度非常慢。

ExecutorService WORKER_THREAD_POOL = Executors.newFixedThreadPool(100);

让我们从这个问题开始:您的机器有多少个内核?
对于newFixedThreadPool,建议从与机器中的内核数一样多的线程开始(如果任务是长时间运行的任务)。如果值为 100,您的 CPU 将忙于调度和上下文切换。最重要的是,因为它是一个newFixedThreadPool,所以即使负载较少,也会有很多线程留在池中 - 对 CPU 没有帮助。

正如 Effective Java 中所建议的那样,newCachedThreadPool 通常会做好事Here 更多关于线程池。

如果您期望负载非常重,我认为在多台服务器上部署应用程序是明智之举(这取决于您的单台服务器的容量)。线程无济于事,最终会使您的应用变慢。

【讨论】:

    【解决方案2】:

    当您在 kubernetes 中部署应用程序时,如果您未指定 memorycpu 要求,则 kubernetes 调度程序会尽最大努力将 pod 调度到节点中,这可能导致 pod 饥饿甚至驱逐。

    您可以通过指定以下memorycpu 要求来帮助调度程序做出更好的调度决策

    apiVersion: v1
    kind: Pod
    metadata:
      name: frontend
    spec:
      containers:
      - name: app
        image: images.my-company.example/app:v4
        env:
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m"
          limits:
            memory: "128Mi"
            cpu: "500m" 
    

    这将确保 pod 被调度在一个节点上,该节点可以满足以64Mi memory、250m cpu 开头的要求,并允许它爆发到128Mi memory、500m cpu。

    【讨论】:

      猜你喜欢
      • 2018-09-05
      • 2019-05-20
      • 2013-09-24
      • 1970-01-01
      • 1970-01-01
      • 2016-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多