将许多套接字连接到服务器时出现奇怪的延迟

时间:2015-05-05 23:05:19

标签: java linux windows sockets

我看到一些奇怪的行为试图预热使用java.net.Socket进行连接的连接池。

这是一个连接大量套接字的小程序:

public class SocketTest {
    public static void main(String[] args) throws Exception {
        for (int i = 0; i < 4000; i++) {
            long t = System.currentTimeMillis();
            new Socket("localhost", 3306);
            long total = System.currentTimeMillis() - t;
            if (total > 10)
                System.out.format("%5d %dms\n", i, total);
        }
    }
}

我在机器上的开放端口上尝试了这个。

MySQL的:

  0 34ms
  468 1000ms
  676 997ms
  831 998ms
  970 997ms
  ...

IPP:

    0 41ms
  231 998ms
  232 998ms
  233 999ms
  234 999ms
  236 3002ms
  238 3002ms
  240 3002ms
  ...

eJabberd(xmpp服务器):

    0 45ms
   27 998ms
   42 999ms
   81 997ms
   99 1000ms
  120 997ms
  135 998ms
  147 997ms

MongoDB的:

    0 73ms
 1314 999ms
 1791 998ms
 2098 999ms
 2466 1000ms
 2717 1000ms

nginx 不会出现此行为(并且连接速度非常快)。

在多线程测试中,我总是只看到非常接近1000毫秒,3000毫秒,7000毫秒或15000毫秒的数字。

在套接字连接之间放置Thread.sleep(50)会延迟一段时间内发生的行为。

我最初在Windows上观察到这种行为,但上面的内容在XUbuntu 14.04上进行了测试。

我分析了应用程序,花费在PlainSocketImpl.socketConnect()上的时间,该时间委托给unix系统上的OS本机方法。

我也尝试过使用Oracle JDK 8和OpenJDK 7,并获得相同的结果。

数字的一致性使我认为它是操作系统层的某种限制或调度行为,而不是内置于服务器中的内容。

在较小的情况下,例如连接100个插座,总时间可能是10秒,但在Thread.sleep(10)之间下降到2秒。

任何人都能解释一下吗?

编辑:使用Windows尝试过。有时获得相似的数字(3000),有时会得到零星的500毫秒。针对Windows上的MySQL,问题根本不会发生。再次,快速Thread.sleep(20)会产生更好的性能,特别是对远程机器。

我猜这是故意的操作系统限制行为,但是想听听熟悉OS堆栈的人的意见。

0 个答案:

没有答案
相关问题