我正在尝试了解 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]
我猜灰熊线程是 Tyrus 客户端为每个 websocket 创建的线程(顺便说一句,我想我没有仔细计算灰熊线程。我认为这三个线程的计数应该相同)。一个选择器两个工人,对吗?
我认为 http-apr-8080-exec-xxx 是tomcat创建的线程。这些线程是否在处理传入的 websocket 连接?我对以下线程更感兴趣:
- WebSocketServer-localhost-ROOT-xxxx
- tyrus-x-线程-xx
- nioEventLoopGroup-xx
- 保活定时器
- http-apr-8080-exec-xxx
有谁知道每组线程的作用?有任何文件可以解释这一点吗?
看起来我的 Tomcat 设置为使用 APR 连接器我想知道在这种情况下使用 NIO 或 NIO2 可能是一个更好的主意?!