0

我编写了一个用于远程存储的 Java 服务器(一个 iSCSI 目标)。客户端可以通过发送携带数据有效负载的数据包序列来写入数据。这些数据包由一个固定长度的报头(48 个字节)和一个可变长度的数据段组成。数据段的长度在标头中指定,可以认为是固定的(8KiB)。

接收数据包是一个两部分的过程。首先将标头读取到大小为 48 字节的 ByteBuffer 中。之后立即通过 ByteBuffer.allocate(...) 创建第二个 ByteBuffer。第二个缓冲区的大小与标头中指定的数据段长度相匹配。然后使用 SocketChannel.read(ByteBuffer) 方法将数据段读入第二个 ByteBuffer。在简单的情况下,此过程按预期工作 - 更大的数据段和更长的序列会提高 IO 速度。“简单情况”是指有一个线程使用阻塞的 SocketChannel 来接收(和处理)数据包。但是,如果添加第二个具有自己的 TCP 连接和关联的 SocketChannel 的线程,则 SockerChannel.read(ByteBuffer) 执行时间会上升到 2.5 毫秒以上,而客户端服务器在两个连接上都发送 32KiB 写命令(即 4 个连续的数据包)。这增加了 8 到 10 倍。

我想强调的是,在这个阶段,除了同一个网络接口卡之外,两个线程不共享任何资源。每个 SocketChannel 的读取缓冲区大小为 43690 字节(较大的大小对这种现象没有任何影响)。

任何想法可能导致此问题或如何解决此问题?

4

1 回答 1

1

...当客户端服务器在两个连接上发送 32KiB 写入命令(即 4 个连续数据包)时。

你能提供一些关于测试设置的细节吗?客户端是否将数据包串行发送到两个连接?然后根据设置,增加可能是客户端驱动的。

它是本地主机设置(一台机器上的客户端和服务器)还是不同主机上的客户端和服务器?你都测试过吗?不要欺骗自己在 localhost 设置中看到执行时间增加,特别是如果只有一个 cpu 并且测试客户端也在本地运行,甚至可能是单线程的。

于 2012-02-26T17:36:18.990 回答