这里的测试方法主要是指测试客户端如何发起百万连接并保持它们。由于受到单机单ip的端口数限制,即如下

pomelo@debian:~/socktest$ cat /proc/sys/net/ipv4/ip_local_port_range

2048         65500

  单个客户端ip只能建立6万多连接,所以我们需要大约50个独立ip发起300万的连接。为简单起见,使用50台512M内存的虚拟机作为客户端。问题归结为两个方面:

  1、单客户端如何建立并保持6万连接

  2、如何控制几十个客户端

  我们以java编写客户端代码。首先我们尝试的是一线程一连接的方式。这样在java中需要维护6万个线程及其相关的对象,包括连接对象。很快我们发现客户端java进程出现了OOM,512M内存不够用了。我们分析下测试目标,目的是保持6万个连接对象,在这种方式下我们相当于是使用了线程这种容器来保存这些对象,但由于线程本身的内存开销巨大,因此我们应该考虑换个轻量级的瓶子来装这些连接对象。

  终代码如下,即在一个线程内顺序建立连接,并将连接保存到一个数组中,至此解决了上文问题中的一个方面

private static int n = 0;
private static Socket[] sockList = null;
static {
    n = Integer.valueOf(Config.getProperty("socket.num"));
    sockList = new Socket[n];
}
public void connect(String host, int port) throws UnknownHostException {
    Socket so = null;
    long sleepTime = Integer.valueOf(Config.getProperty("socket.sleep"));
    for (int i=0;i<n;i++) {
        try {
           so = new Socket(host, port);
           sockList[i] = so;
           Thread.sleep(sleepTime);
       } catch (IOException e) {
           logger.error(e.getMessage());
       } catch (InterruptedException e) {
         
       }
    }
}

  接着,又是如何控制几十台客户端呢?其实比较简单,是在shell脚本中通过ssh调用部署在客户端机器上的测试程序。主要有两个问题需要注意,一是ssh需要认证,我们可以在任意机器上产生无密码的ssh公私钥对,将公钥分发到客户端机器上。二是设置一个ip列表的配置文件。

  这样,两个问题都解决了,可以开始测试了。测试过程及其问题不完全记录可以点这里。