如何在这个简单的基于Java的TCP服务器应用程序中增加吞吐量?

时间:2013-12-29 00:09:45

标签: java sockets tcp java-server

我正在编写一个非常基本的TCP服务器。服务器跟踪从客户端收到的状态。我documented the message formatpublished the source。在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字节),我可以从我的应用程序中获得哪些吞吐量?
  • 我还能做些什么来找到这个简单应用程序的瓶颈?

2 个答案:

答案 0 :(得分:3)

以下代码

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

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

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

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

  • 最明显的解决方法是增加邮件大小。这将在更长的距离上提供最多。
  • 在发送下一封邮件之前,请勿等待回复。这可以极大地提高吞吐量。
  • 为每个请求使用新连接+主题。通过这种方式,您可以同时进行多个并行请求。

答案 1 :(得分:0)

为了提高速度,最好使用另一种协议,它可以节省发送的字节数和处理时间。

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

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

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

目标是将所需的处理和通过网络发送的字节数降至最低。