【问题标题】:Tomcat 8 JSR 356 WebSocket ThreadingTomcat 8 JSR 356 WebSocket 线程
【发布时间】:2013-10-13 06:05:53
【问题描述】:

我正在使用 Tomcat 8 中的 JSR-356 WebSocket 支持来驱动我正在开发的应用程序。到目前为止,看起来所有消息都在一个线程中处理。虽然我理解这背后的原因 - 以及为什么以这种方式实现 websockets,但有没有办法使用 ExecutorService 来处理传入的消息(而不在我的代码中创建 ExecutorService)?

这将允许拥有 1 个(或只有几个)网络选择器线程(以支持大量连接的客户端)的可扩展性,同时允许对实际消息进行基于标准线程的处理(当消息需要为客户处理)。

我看不出有什么特别的地方可以改变它。

【问题讨论】:

    标签: tomcat websocket tomcat8


    【解决方案1】:

    线程模型因您使用的连接器而异。对于可伸缩性,您想使用 NIO(默认)或 APR/native(8.0.0-RC3 的错误)。 NIO确实是目前唯一的选择。 APR/native 问题应该很快就会得到解决(当我看到这个问题时,我正在处理这个问题)。

    NIO 使用选择器和线程池来处理接收到的消息。 When the selector detects that data is available it passes the socket to a thread from the thread pool (via an executor) to process it.该处理可能导致数据在内部被缓冲,应用程序被通知部分消息,应用程序被通知完整消息或这些的组合。应用程序的通知由处理传入数据的同一线程处理。

    如果从多个客户端接收到多条消息,则将调度多个线程来处理这些消息。

    JSR 356 API 中没有允许应用程序选择通过 ExecutorService 处理消息或部分消息的功能,即应用程序已被通知新消息而没有应用程序实现。对于只处理整个消息的应用程序来说,实现这一点应该相对简单。如果应用程序处理部分消息,那么这将更加困难。

    APR/native(一旦修复)的行为方式与 NIO 相同。 BIO 始终使用阻塞 IO(即使 JSR356 API 指示非阻塞)并且还需要每个连接的客户端一个线程,而不是每个连接的客户端一个线程来处理数据。

    【讨论】:

    • 好的,你是说它确实使用线程池来处理传入的数据?每个客户端最多有一个线程吗?
    • 我问是因为当我在测试时,看起来第二条消息正在等待第一条消息完成处理。但是我们都是从同一个会话中发送的(也许这就是原因)。旁注:很好的答案
    • 分配给每个客户端处理数据的线程不超过一个。如果客户端发送多条消息,那么它们将按顺序处理 - 可能由同一个线程处理。当线程完成第一条消息时,它会看到有更多数据要读取。如果有,它将读取它。如果没有,套接字将返回到选择器/轮询器,直到有更多数据到达。数据必须以这种方式处理。一旦消息(或部分消息)准备好传递给应用程序,就有更多线程的空间,这可以在新线程中完成(但不是)。
    • @MarkThomas,很好的解释。我有一个问题问你。是否可以配置 tomcat 以便为每个 websocket 分配多个工作线程,以便同时处理消息?如果你看看这个问题,我真的很感激:stackoverflow.com/q/33357860/266659
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-04
    • 2017-07-20
    • 1970-01-01
    • 2016-04-23
    • 1970-01-01
    • 1970-01-01
    • 2015-05-26
    相关资源
    最近更新 更多