本文由作者郑银燕授权网易云社区发布。

本文是我在测试过程中的记录,实现了单台测试机发起最大的websocket长连接数。在一台测试机上,连接到一个远程服务时的本地端口是有限的。根据TCP/IP协议,由于端口是16位整数,也就只能是0到 65535,而0到1023是预留端口,所以能分配的端口只是1024到65534,也就是64511个。也就是说,一台机器一个IP只能创建六万多个websocket长连接。

一、客户端参数调优

本文采用的测试机分别为黑mac系统和linux系统(由于黑mac机器本身性能问题,最大只能达到2万连接,于是换用linux)。下面先以mac系统为例,阐述下客户端参数调优,linux系统类似,这里不做阐述。

1、修改全局限制,系统默认的最大连接数限制

命令:sysctl kern.maxfiles

说明:全局限制,也就是系统默认的最大连接数限制是12288

修改大小: sudo sysctl -w kern.maxfiles=1048600

说明:设置系统最大连接数从12288到1048600

2、测试脚本是一个进程,开启上万个长连接,还需要修改单个进程的最大连接数。

命令:sysctl kern.maxfilesperproc

说明:单个进程默认最大连接数限制是10240

修改大小:sudo sysctl -w kern.maxfilesperproc=1048576

说明:设置进程连接数限制,进程的最大连接数要小于等于全局连接数

3、由于客户端与服务端需要建立大量的socket,所以我们需要调速一下最大文件描述符。

命令:ulimit -n

说明:“ulimit -n”命令显示当前shell能打开的最大文件数,默认值:256,该值总是小于kern.maxfilesperproc的值,因为一个shell就是一个进程。

修改大小:ulimit n 1048576

说明:设置当前shell能打开的最大文件数为1048576,该值不能大于kern.maxfilesperproc,否则会提示设置失败。

4、由于系统默认参数,自动分配的端口数有限,所以我们需要更改客户端ip端口号的参数

命令:sysctl net.inet.ip.portrange,查询得到的系统默认的端口号分配如下:

将可分配的首个端口号设置为1024

修改大小:sudo sysctl net.inet.ip.portrange.first=1024

5、按以上的方式设置参数有个问题,当系统重启后,这些参数又恢复成了默认值,解决办法就是把参数写到/etc/sysctl.conf文件中,但是,默认这个文件是不存在的,所以首先就要创建它:

sudo touch /etc/sysctl.conf

然后把参数写到文件里

kern.maxfiles=1048600

kern.maxfilesperproc=1048576

net.inet.ip.portrange.first=1024

net.inet.ip.portrange.last=65535

重启系统,查看结果,显示成功。

至于ulimit -n的值,可以把ulimit -n 1048576 写到.bashrc中实现自动修改。

二、测试脚本

客户端脚本采用nodejs编写,之所以不采用jmeter的方式,是因为jmeter每个连接都是线程的方式,而单台测试机最好保持开启1000个以内的线程,否则机器容易崩溃。

测试脚本如下:

var cwd = process.cwd();var WebSocketClient = require('websocket').client;var size = 10000;var host = 'example.com:80';var port = 443;var authInterval = 10;var index = 0;

setInterval(function(){		if(index < size){
uid = index;
cid = index;
init(uid, cid);
index++;
}
},authInterval);console.log('begin...');
init = function(uid, cid){ var client = new WebSocketClient();
client.connect('ws://XX.XX.XX.XX:XXXX/ws?token='+index,"","http://example.com:80");
client.on('connectFailed', function(error) { console.log('Connect Error: ' + error.toString());
}); client.on('connect', function(connection) { console.log(index+' Connected');
connection.on('error', function(error) { console.log("Connection Error: " + error.toString());
});
connection.on('close', function(error) { console.log(error + ';  Connection Closed');            //client.close();
reconnect();
});
connection.on('message', function(message) { });
});
};function timeLogout(){ return setTimeout(function (){
logout(uid);
}, StartTime);
}

三、测试结果

在相应的目录下输入命令node websocket.js,即可建立websocket连接。由于机器性能问题,连接数达到2w左右,就无法建立新的连接了。后面将机器改成云主机,可以达到6万的连接数。

四、后续展望

我的测试目标不是实现单台6万的连接数。我的目标是可以达到百万级稳定的长连接,并且可以向websocket服务器收发信息,计算每个消息从服务器发送到客户端接收的平均耗时时间,以及查看建立百万级连接,服务器的内存和cpu的使用情况。最终限制于机器的性能,暂时还没做到。并且业务需求繁忙,这个测试就暂时告一段落了。后续想要通过使用虚拟IP的方式来实现百万级连接,比如增加了18个IP地址,这样就可以产生18 * 60000 = 1080000个连接。或者借用更多的机器数,每台机器维持6万连接。

免费领取验证码、内容安全、短信发送、直播点播体验包及云服务器等套餐

更多网易技术、产品、运营经验分享请访问网易云社区

相关文章:
【推荐】 邪恶的三位一体:机器学习、黑暗网络和网络犯罪

实现单台测试机6万websocket长连接的更多相关文章

  1. 当web应用包含了websocket长连接,如何在web应用前加一层nginx转发

    1 通过在web应用的前面加一层nginx ,可以实现一台主机部署多个应用,每个应用都可以用不同的域名去访问,并且端口都是80 2 nignx 转发websocket长连接 1 每个web应用,他们运 ...

  2. Spring+Stomp+ActiveMq实现websocket长连接

    stomp.js+spring+sockjs+activemq实现websocket长连接,使用java配置. pom.xml(只列出除了spring基本依赖意外的依赖,spring-version为 ...

  3. WebSocket长连接

    WebSocket长连接 1.概述 1.1 定义 1.2 原理 2.Django中配置WebSocket 2.1安装第三方法包 pip install channels 2.2 Django 中的配置 ...

  4. Python WebSocket长连接心跳与短连接

    python websocket 安装 pip install websocket-client 先来看一下,长连接调用方式: ws = websocket.WebSocketApp("ws ...

  5. WebSocket 长连接 及超时问题解决

    <?phpset_time_limit(0); class SocketService { private $address = 'localhost'; private $port = 80; ...

  6. 雨露均沾的OkHttp—WebSocket长连接的使用&源码解析

    前言 最近老板又来新需求了,要做一个物联网相关的app,其中有个需求是客户端需要收发服务器不定期发出的消息. 内心OS:

  7. Django websocket 长连接使用

    下载  pip install dwebsocket WebSocket是一种在单个TCP连接上进行全双工通信的协议 WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客 ...

  8. Browser 與 Server 持續同步的作法介紹 (Polling, Comet, Long Polling, WebSocket)长连接

    對 Comet 的懵懂 記得兩年多前,第一次看到 Gmail 中的 GTalk 覺得很好奇:「咦?線上聊天且是 Google 的熱門系統,只用傳統的 AJAX 應該會操爆伺服器吧?」很幸運的,當時前公 ...

  9. 微信小程序 实现websocket长连接 以及断开连接之后自动重连

    app.js let socketMsgQueue = [] let isLoading = false App({ globalData: { userInfo: null, localSocket ...

随机推荐

  1. linux的ssh服务

    1.检查是否安装ssh > rpm -qa|grep ssh 2.安装ssh服务 > yum install ssh 配置 /etc/ssh/sshd_config 端口 22 3.启动s ...

  2. C#开发中常用加密解密方法解析

    一.MD5加密算法 我想这是大家都常听过的算法,可能也用的比较多.那么什么是MD5算法呢?MD5全称是message-digest algorithm 5,简单的说就是单向的加密,即是说无法根据密文推 ...

  3. 201621123008 《Java程序设计》第五周学习总结

    1. 本周学习总结 1.1 写出你认为本周学习中比较重要的知识点关键词 关键词:接口,内部类. 1.2 尝试使用思维导图将这些关键词组织起来.注:思维导图一般不需要出现过多的字. 1.3 可选:使用常 ...

  4. 五步打造APP节日主题设计:以Lofter新年图标设计为例

    我们需要做有依据,有逻辑,有理念的设计,需要发散思维,整合创意,严谨输出,让设计经得起推敲 前言 ​ 2018年春节已远去,一直想把Lofter新年Logo设计思路分享给大家,直到现在才整理出来,希望 ...

  5. easyui datagrid编辑

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Datagrid.aspx. ...

  6. 2、HttpClient修改处理策略Strategy

    HttpClient提供了很多接口,让我们能自定义处理逻辑,这些接口可以在AbstractHttpClient中找到: setAuthSchemes(AuthSchemeRegistry); setC ...

  7. Cannot initialize Cluster. Please check your configuration for mapreduce.framework.name and the correspond server addresses.

    解决方法: <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-m ...

  8. JavaScript 代码小片段

    1.获取对象 obj 的所有属性(自有属性和继承属性),保存到数组 lst 中 //获取对象obj的所有属性(自有属性和继承属性),保存到数组lst 中 var lst = []; function ...

  9. KBMMW 4.70.00 发布

    We are happy to announce the release of kbmMW v. 4.70.00 Professional and Enterprise Edition. kbmMW ...

  10. DevExpress VCL 13.1.2 发布

    DevExpress VCL 的2013 第一个公开版发布, 基本上就是一些维护,没有大的变化,也没有FM 的支持. What's New in DevExpress VCL 13.1.2   Rel ...