gpt4 book ai didi

Java NIO - 消息的积累

转载 作者:行者123 更新时间:2023-12-01 13:37:21 25 4
gpt4 key购买 nike

我正在编写一个使用 NIO 套接字的 Java 应用程序。
它由 3 个服务器和一组客户端组成。客户端可以与服务器通信,服务器可以与客户端和其他服务器通信。

服务器到服务器和客户端到服务器发送 Message序列化为 byte[] 的 s大批。每个Message的第一个字节包含消息的大小,自然保证每条消息不超过127 (2^8 -1)字节。
您可以将服务器和客户端的消息发送视为循环操作:

Message msg = new Message()
while (true) {
sendMessage(msg, server or client)
receiveMessage()
}

然后,实现利用 ByteBuffer .自然,就像在任何 Java NIO 实现中一样,每个服务器都做 selector.select()然后检索 SelectionKey s 看看是否 read ing(调用 handleRead() 方法), write ing(调用 handleWrite()),或 accept ing(调用 handleAccept() )需要处理。所有 handleXX方法采取有限数量的步骤,并且不会阻塞等待其他任何事情。

检索特定 handleRead() 的数据 ( key ) 时,我只是将数据存储在特定的 map 中 Map<SelectionKey, List<byte[]>> readDataForKey;然后我遍历列表并提取所有已收到的消息。

但是,我注意到有时在输入 handleRead 时一些 key有数以千计的消息等待处理。我不明白为什么会这样?
我希望 handleRead看到几条消息,就是这样。

事实上,数以千计的消息在被处理之前就已经积累起来了。这意味着什么?这是否意味着我的 handleReadhandleWrite或者 NIO 实现的其他部分需要太长时间并且底层缓冲区已满?这是否意味着偶尔我会得到一个 GC(大约 10 毫秒),同时缓冲区已满?这是否意味着我在 handleRead 中的代码可能很慢?因此消息会累积?

这么多消息堆积正常吗?

最佳答案

你的消息很小。所以发送和接收缓冲区可以包含很多消息 .如果您没有明确指定发送和接收缓冲区的大小,TCP 堆栈将尽最大努力优化大小,以便在您的网络上进行有效传输。虽然大多数 Linux 发行版的默认大小约为 128 KB,但最大大小可能是数兆字节(例如,在具有非常高延迟的网络上)。 因此,单个 handleRead 可以轻松查看成百上千条消息 . TCP 尝试尽可能好地使用您的网络带宽。在接收缓冲区中看到大量消息并不自动意味着您的接收器过载。 TCP 甚至可以避免您的接收器过载。衡量您的系统是否“过载”的唯一方法是衡量发送消息所需的时间(例如,在发送消息之前将消息排队并测量其大小)

在某些情况下,手动优化缓冲区大小是有意义的(例如,具有非常高延迟的网络),但大多数时候 TCP 堆栈在这里做得很好。在极少数情况下,禁用 Nagle 的算法(例如 Telnet 和 SSH)以最大程度地减少用户输入的 react 时间是有意义的,但在大多数情况下,绝对不需要手动干预。让 TCP 完成它的工作,它优化高效传输并避免接收器过载。

关于Java NIO - 消息的积累,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61824846/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com