首页 > 解决方案 > 为什么 Google PubSub 总是创建 60 个永久线程?

问题描述

我的应用程序发布的消息量很少(最多每隔几秒钟发布一次)。它不订阅。

首次使用时,PubSub 会创建 60 个永久保持活动的线程,如下所示:

"grpc-default-worker-ELG-1-1 Id\u003d115 RUNNABLE (in native)...
"grpc-default-worker-ELG-1-10 Id\u003d160 RUNNABLE (in native)":...
....
"Gax-16 Id\u003d141 TIMED_WAITING on java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@24f8d334": ...
"Gax-17 Id\u003d142 WAITING on java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject@24f8d334":....

我们在本示例中使用 Java 代码。Publisher 对象在进程的生命周期内保留,如此处所推荐

六十是一个非常高的默认值。

此外,如果我 setExecutorThreadCount 到 4(代码如下),我仍然会获得额外的 26 个永久线程。将此线程数设置为 1 或 2 仍会产生大约 20 个额外线程。

ExecutorProvider executorProvider = InstantiatingExecutorProvider.newBuilder().setExecutorThreadCount(4).build();
Publisher.Builder builder = Publisher.newBuilder(ProjectTopicName.of(proj, topic)).setExecutorProvider(executorProvider);

我们的应用程序已经是线程繁重的,并且不能容忍为 PubSub 留出超过一两个额外的线程。

如何解决?有这方面的文件吗?

标签: google-cloud-pubsub

解决方案


对于单个订阅者,看到 60-65 个线程是正常行为。

因为每个订阅者都需要一定数量的 gRPC 流,并且对于每个流,我们都有:

  1. 从流中接收消息的单独线程
  2. 一个线程池处理回调
  3. 一个线程池发送确认/延迟消息

可以控制线程池,但一直存在面临死锁的问题:

ExecutorProvider executorProvider =
   InstantiatingExecutorProvider.newBuilder()
  .setExecutorThreadCount(1)
  .build();

Publisher publisher =
    Publisher.defaultBuilder(ProjectTopicName.of(proj, topic)).setExecutorProvider(executorProvider).build();

Subscriber subscriber =
    Subscriber.defaultBuilder(ProjectTopicName.of(proj, topic)).setExecutorProvider(executorProvider).build();

推荐阅读