尽管使用了java.NIO

时间:2015-09-04 11:10:25

标签: java node.js multithreading go websocket

我尝试创建连接到我的glassfish websocket服务器的大约5千个并发客户端(不停止从服务器发送到客户端的数据)。 (CPU:双核,8 GB RAM)

连接约2500个客户端后,连接时间约为67(!)秒,我无法连接TimeOutException的更多客户端。

一些事实:

  • 线程池最大大小设置为 12.000
  • 在第一次TimeoutException时,我有 2500 个客户端和 2450 主题。所以我们在这里谈到每个连接一个线程。
  • 这不是记忆问题!

然后在 Node.js golang 中写了两个简单的Websocket代理服务器来处理websocket连接。 Proxy Server和glassfish服务器之间的数据交换通过简单的Websocket连接进行。

现在我能够毫无问题地创建超过5,000个并发客户端。与Wildfly 8和Tomcat 8相同的问题。 以下是评估:

avaluation

现在我的问题。 Tyrus是glassfish中Websocket协议的实现,并使用java.nio库进行非阻塞I / O。

那么为什么它的可扩展性如此差?或者为什么可扩展性如此不同。我的意思是我看到java.nio

没有优势

P.S。只是调度开销?

编辑:如何重现问题

用于创建和连接客户端和Websocket服务器的客户端软件位于不同的PC上。

  1. 启动glassfish simple echo websocket服务器。有大约76个活跃的玻璃鱼线程。 GlassFish-2000-connected-And-Idle
  2. 现在连接2000个客户端而不启动任何通信,只需连接到服务器 - 空闲模式。就我而言,它没有问题。由于所有客户端都已连接,因此大约有80个活动线程。几乎未变。
  3. 使用Timer让所有2000个客户端同时开始与websocket服务器通信。您会注意到线程的数量现在约为2019.响应时间约为6.5秒。 GlassFish-2000-connected-And-Active
  4. 最后尝试连接下500个客户端。将发生第一个TimeoutException。只有少数客户将被连接。
  5. 同时停止通讯。 Stop communication

1 个答案:

答案 0 :(得分:2)

包括

有多种可能的答案
  1. 也许Tyrus真的不能很好地扩展。

  2. 也许你没有以正确的方式使用它;即你的代码正在做一些导致Tyrus表现不佳的事情。

  3. 也许你在“比较苹果和橘子”;即你的测试正在比较不同的东西。

  4. 可能 是内存问题。你有什么证据表明它不是?

  5. 可能是由于多种原因造成的。

  6. 不幸的是,您没有提供任何具体信息,可以让我们将可能的原因与可能的原因分开。

    根据您在更新/评论中报告的内容,似乎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。)