在上一篇中我们讲述了百万连接的
测试过程及出现的问题和解决办法,有同学对其中的测试方法也有兴趣,我在这里再补充一下。这里的测试方法主要是指测试客户端如何发起百万连接并保持它们。由于受到单机单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列表的配置文件。
这样,两个问题都解决了,可以开始测试了。测试过程及其问题不完全记录可以点这里。