我尝试创建连接到我的glassfish websocket服务器的大约5千个并发客户端(不停止从服务器发送到客户端的数据)。 (CPU:双核,8 GB RAM)
连接约2500个客户端后,连接时间约为67(!)秒,我无法连接TimeOutException
的更多客户端。
一些事实:
然后在 Node.js 和 golang 中写了两个简单的Websocket代理服务器来处理websocket连接。 Proxy Server和glassfish服务器之间的数据交换通过简单的Websocket连接进行。
现在我能够毫无问题地创建超过5,000个并发客户端。与Wildfly 8和Tomcat 8相同的问题。 以下是评估:
现在我的问题。
Tyrus是glassfish中Websocket协议的实现,并使用java.nio
库进行非阻塞I / O。
那么为什么它的可扩展性如此差?或者为什么可扩展性如此不同。我的意思是我看到java.nio
P.S。只是调度开销?
用于创建和连接客户端和Websocket服务器的客户端软件位于不同的PC上。
答案 0 :(得分:2)
此包括:
有多种可能的答案也许Tyrus真的不能很好地扩展。
也许你没有以正确的方式使用它;即你的代码正在做一些导致Tyrus表现不佳的事情。
也许你在“比较苹果和橘子”;即你的测试正在比较不同的东西。
可能 是内存问题。你有什么证据表明它不是?
可能是由于多种原因造成的。
不幸的是,您没有提供任何具体信息,可以让我们将可能的原因与可能的原因分开。
根据您在更新/评论中报告的内容,似乎Tyrus正在为每个WebSocket连接使用一个线程,但其他人使用更具扩展性的方法。
使用NIO并不一定意味着非阻塞I / O.
在用于WebSocket API的Tomcat 7实现的documentation中,它说:
Java WebSocket 1.0规范要求异步写入的回调在与启动写入的线程不同的线程上执行。由于容器线程池不是通过Servlet API公开的,因此WebSocket实现必须提供自己的线程池。此线程池由以下servlet上下文初始化参数控制:
org.apache.tomcat.websocket.executorCoreSize
:执行程序线程池的核心大小。如果未设置,则使用默认值0(零)。请注意,执行程序线程池的最大允许大小硬编码为Integer.MAX_VALUE,这实际上意味着它是无限的。org.apache.tomcat.websocket.executorKeepAliveTimeSeconds
:空闲线程在终止之前保留在执行程序线程池中的最长时间。如果未指定,则使用默认值60秒。
这暗示了为什么在Tyrus中创建线程,并暗示可能Tomcat比Glassfish上的Tyrus更具可扩展性。 (而且我也会在Grizzly上尝试Tyrus。)