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

Posted

技术标签:

【中文标题】Tyrus 使用的每个 websocket 连接有多少个线程?【英文标题】:How many threads per websocket connection Tyrus uses? 【发布时间】:2015-09-29 19:46:37 【问题描述】:

我正在尝试了解 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 连接?我更有兴趣了解以下主题:

WebSocketServer-localhost-ROOT-xxxx tyrus-x-thread-xx nioEventLoopGroup-x-x 保持活动定时器 http-apr-8080-exec-xxx

有人知道每组线程的作用吗?有任何文件可以解释这一点吗?

看起来我的 Tomcat 设置为使用 APR 连接器我想知道在这种情况下使用 NIO 或 NIO2 可能是一个更好的主意?!

【问题讨论】:

你绝对应该使用 ClientProperties.SHARED_CONTAINER .. 在这种情况下你真的不需要设置线程池,因为 grizzly 会自动调整它们。 (634 个选择器运行器太多了,您当前的负载可以由 【参考方案1】:

这取决于您的环境。 Tyrus(服务器!)本身不应该创建新线程,它只是使用容器(Glassfish、WebLogic、...(在独立服务器模式下运行时为 Grizzly))提供的内容。

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

所以,我无法说明为什么您的 JVM 使用了这么多线程(顺便说一句,它们都处于活动状态吗?我对此表示怀疑……) - 如果您想解决此类问题,您需要提供更多信息。您可以从提供代码(最好是可执行的)开始,以便我们能够重现您看到的内容;随意将其移至 users@tyrus.java.net,它可能会以对话结束,这不适合“SO 问题/答案”模型。

【讨论】:

我添加了更多信息。如果您能看一下,我将不胜感激。

以上是关于Tyrus 使用的每个 websocket 连接有多少个线程?的主要内容,如果未能解决你的问题,请参考以下文章

javax.websockets / Tyrus 中的线程

如何以编程方式为 Tyrus WebSocket @ServerEndpoint 启用 WSS

使用 Tyrus javax.websocket 的 Java Websocket 客户端?

tyrus websocket ssl 握手失败

如何使用 Tyrus java 客户端在初始 WebSocket 客户端请求中包含 cookie?

Tyrus websocket:IllegalStateException 无法为非异步请求设置 WriteListener