Tyrus 使用每个 websocket 连接多少个线程?

How many threads per websocket connection Tyrus uses?

我正在尝试了解 Tyrus websocket 连接的线程模型。 Tyrus 是否为每个 websocket 连接使用一个线程?是否涉及一些线程池机制?

我试图找到一个文档来描述 Tyrus 实现的内部结构或 Java 的任何 websocket 实现,以了解线程模型的工作原理,但我找不到任何文档。

有关线程模型如何维护 websocket 连接的任何信息都会有所帮助。

我正在尝试优化我的服务器以支持数千个 websocket 连接。现在只有 1000 个 websocket 连接,JVM 使用了大约 1800 个线程!

更新 1:

我在 Tomcat 8 上使用 Tyrus 1.9。

服务器终止了大约 500 个 websocket 连接,并启动了 500 个到不同服务器的 websocket 连接。所以我们现在在服务器上有大约 1000 个 websocket 连接。

我注意到的一件事是 TYRUS-275 问题,我想这与我的情况有关。看起来 Tyrus 客户端默认为每个 websocket 连接创建 3 个线程。在我的例子中,我有大约 500 个连接,所以我最终应该有大约 1500 个线程用于传出的 websocket 连接。

看起来如果我在 Tyrus 中启用共享容器,那么我可以从使用 SELECTOR 和 WORKER 线程池中获益。

client.getProperties().put(ClientProperties.SHARED_CONTAINER, true);
client.getProperties().put(GrizzlyClientProperties.SELECTOR_THREAD_POOL_CONFIG, ThreadPoolConfig.defaultConfig().setMaxPoolSize(3));
client.getProperties().put(GrizzlyClientProperties.WORKER_THREAD_POOL_CONFIG, ThreadPoolConfig.defaultConfig().setMaxPoolSize(10));

我现在想知道如何优化线程池? 500 个 websocket 连接需要多少个 SELECTOR 和 WORKER 线程?有公式吗?

更新 2:

当我连接到 JVM 时,我看到以下线程(仅列出有趣的线程):

- 24   x WebSocketServer-localhost-ROOT-xxxx [mostly parked]
- 1    x WebSocket background processing [mostly asleep]
- 10   x tyrus-1-thread-xx [mostly parked]
- 10   x tyrus-2-thread-xx [mostly parked]
- 1    x Tomcat JDBC Pool Cleaner [waiting]
- 1    x Signal Dispatcher [all running]
- 9    x nioEventLoopGroup-x-x [all running]
- 1    x main [all running]
- 177  x Keep-Alive-Timer [sleeping]
- 1    x java-sdk-htttp-connection-reaper [sleeping]
- 1    x http-apr-8080-Sendfile [waiting]
- 1    x http-apr-8080-Poller [running]
- 200  x http-apr-8080-exec-xxx [mostly parked with running slices]
- 1    x http-apr-8080-AsyncTimeout [sleeping]
- 1    x http-apr-8080-Acceptor-0 [running]
- ~630 x Grizzly(1) [mostly parked]
- ~634 x Grizzly(1) SelectorRunner [mostly running]
- ~635 x Grizzly(2) [moslty parked]

我猜 Grizzly 线程是 Tyrus 客户端为每个 websocket 创建的线程(顺便说一句,我想我没有仔细计算 Grizzly 线程。我认为它们三个的计数应该相同)。一个选择两个工人,对吗?

我认为 http-apr-8080-exec-xxx 是由 tomcat 创建的线程。这些线程是否负责传入的 websocket 连接?我更有兴趣了解以下话题:

有谁知道每组线程的作用?有没有解释这个的文件?

看起来我的 Tomcat 设置为使用 APR 连接器我想知道在这种情况下使用 NIO 或 NIO2 会更好吗?!

这取决于您的环境。 Tyrus(服务器!)本身不应该创建新线程,它只是使用容器(Glassfish,WebLogic,...(Grizzly when 运行 in standalone server mode))提供的。

此外,这取决于您在 Endpoints 中进行的操作。如果您在每个连接中不断地收到 receiving/sending 消息,那么它必须有一个线程。否则,如果你只是连接而不做任何事情,Tyrus 本身不应该做任何事情,除非你正在使用心跳功能或类似的东西。

所以,我不知道为什么你的 JVM 使用那么多线程(顺便说一句,它们都是活动的吗?我对此表示怀疑..) - 如果你想解决这样的问题,你需要提供更多信息。您可以从提供代码(最好是可执行文件)开始,以便我们能够重现您所看到的内容;请随意将其移至 users@tyrus.java.net,它可能会以不适合 "SO question/answer" 模型的对话结束。