gpt4 book ai didi

Java套接字性能瓶颈: where?

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:45:55 24 4
gpt4 key购买 nike

我最近开始开发一个大量使用网络的应用程序。第一次尝试是使用 RMI,出于几个原因,我们切换到纯套接字。然而,当通过网络测试套接字时,甚至在本地主机上,我们的速度下降到 25 个请求/秒。使用 RMI 时,它高出两个数量级。

通过更多的测试,我们获得了以下信息(针对本地主机):

  • 始终发送相同的对象:31628 个请求/秒
  • 始终发送新对象:25 个请求/秒
  • 仅对象创建速率:每秒 3-4 百万(因此这不是瓶颈)

这是客户端代码:(服务器端只是回复一个“ACK”)

public static void main(String[] args) throws IOException, ClassNotFoundException
{
Socket kkSocket = null;
ObjectOutputStream out = null;
ObjectInputStream in = null;


kkSocket = new Socket("barium", 4444);
out = new ObjectOutputStream(kkSocket.getOutputStream());
in = new ObjectInputStream(kkSocket.getInputStream());


long throughput;
long millis;

TcpRequest hello = null;


throughput = 0;
millis = System.currentTimeMillis();
while (System.currentTimeMillis() < millis + 1000)
{
hello = new TcpRequest();
hello.service = "hello";
hello.payload = Math.random();
throughput++;
}

System.out.println("-------------------------------------------------------");
System.out.println("| Objects created: " + (throughput) + " requests/sec.");
System.out.println("-------------------------------------------------------");


throughput = 0;
millis = System.currentTimeMillis();
while (System.currentTimeMillis() < millis + 1000)
{
out.writeObject(hello);
Object res = in.readObject();
throughput++;
}
System.out.println("-------------------------------------------------------");
System.out.println("| Same object throughput: " + (throughput) + " requests/sec.");
System.out.println("-------------------------------------------------------");


throughput = 0;
millis = System.currentTimeMillis();
while (System.currentTimeMillis() < millis + 1000)
{
hello = new TcpRequest();
out.writeObject(hello);
Object res = in.readObject();
throughput++;
}
System.out.println("-------------------------------------------------------");
System.out.println("| New objetcs throughput: " + (throughput) + " requests/sec.");
System.out.println("-------------------------------------------------------");


out.close();
in.close();

kkSocket.close();
}

TcpRequest 类只是一个虚拟类,没有任何特殊之处。

那么,如果创建对象很快,如果通过网络发送它也很快......为什么通过网络发送一个新对象这么慢?!?!

如果你保留一个相同的对象并在发送之前修改它的内容,你也会有很高的传输率......但是陷入了令人讨厌的陷阱:

When working with object serialization it is important to keep in mind that the ObjectOutputStream maintains a hashtable mapping the objects written into the stream to a handle. When an object is written to the stream for the first time, its contents will be copied to the stream. Subsequent writes, however, result in a handle to the object being written to the stream.

...这发生在我们身上,导致我们调试了几个小时才弄明白。

所以基本上...您如何使用套接字实现高吞吐量? (...我的意思是,RMI 是它的包装器,我们已经高出两个数量级!)

已解决:

通过替换:

out = new ObjectOutputStream(kkSocket.getOutputStream());

与:

out = new ObjectOutputStream(new BufferedOutputStream(kkSocket.getOutputStream()))

性能再次正常(与相同对象情况几乎相同的高吞吐量)

最佳答案

找到了:

代替:

out = new ObjectOutputStream(kkSocket.getOutputStream());

你应该使用:

out = new ObjectOutputStream(new BufferedOutputStream(kkSocket.getOutputStream()));

out.flush();

发送消息时。

...有很大的不同...虽然我不知道为什么。

关于Java套接字性能瓶颈: where?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4451410/

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