2

我正在编写一个非常基本的 TCP 服务器。服务器跟踪它从客户端接收到的状态。我记录了消息格式发布了源代码。在 2009 MacBookPro(2.26 GHz Core 2 Duo,4 GB RAM)上,吞吐量非常低 - 如果服务器和客户端在同一台机器上运行,则为 1 MB/s。我正在寻找显着提高吞吐量的方法。

服务器和客户端的主循环都相当简单。与服务器建立连接后,客户端创建 UpdateOneMessage 实例,并将它们的 byte[] 表示发送到服务器。从Client.run()

for (int i = 0; i < maxMessageCount; i++) {
  send(new UpdateOneMessage(1 + i, id, "updatedState"));
  // .. read response
}

Client.send()将消息序列化并写入 DataOutputStream。

private int send(final Message message) throws Exception {
  final byte[] bytes = message.serialize();
  out.write(bytes);
  out.flush();
  return bytes.length;
}

使用JVM Monitor分析客户端和服务器,显示 CPU 时间主要由从InputStreamReader读取和向DataOutputStream写入。但是以 1 MB/s 的速度,这个应用程序甚至还没有接近IO-bound

  • 考虑到每条消息都相当小(平均 55 字节),我可以从我的应用程序中获得哪些吞吐量?
  • 我还能做些什么来找到这个简单应用程序中的瓶颈?
4

2 回答 2

3

以下代码

send(new UpdateOneMessage(1 + i, id, "updatedState"));
// .. read response

建议您在每条消息上切换流量方向。也就是说,您在发送下一个请求之前等待每个请求的响应。这种架构将对您的运行速度施加一些限制。每条消息将经历的延迟将影响服务器的总体吞吐量。

如果您将客户端和服务器移动到两个不同的位置,它们之间有一定距离,您会看到传输速率更慢。以例如1500 公里的网络,光速将确保您每秒最多获得 100 次往返。每条消息 55 个字节,每秒只有5.5 Kb

如果您需要更快的传输,您可以做几件事。

  • 最明显的解决方法是增加消息大小。这将在更长的距离上发挥最大作用。
  • 在发送下一条消息之前不要等待响应。这可以极大地提高吞吐量。
  • 为每个请求使用新的连接+线程。这样,您可以同时处理多个并行请求。
于 2013-12-29T01:08:20.383 回答
0

为了速度,您最好使用另一个协议,这将节省您发送的字节数和处理时间。

例如,Google 协议缓冲区快速且带宽高效。

http://code.google.com/p/protobuf/

或者,如果对象真的像你说的那么小,那么只需使用自定义协议对它们进行手动编码。

目的是使所需的处理和通过网络发送的字节数尽可能减少。

于 2013-12-29T00:15:48.497 回答