一、模拟单机连接瓶颈
我们知道,通常启动一个服务端会绑定一个端口,例如8000端口,当然客户端连接端口是有限制的,除去最大端口65535和默认的1024端口及以下的端口,就只剩下1024~65535个,再扣除一些常用端口,实际可用端口只有6万个左右。
那么,我们如何实现单机百万连接呢?假设在服务端启动[8000,8100]这100个端口,100×6万就可以实现600万左右的连接,这是TCP的一个基础知识,虽然对于客户端来说是同一个端口号,但是对于服务端来说是不同的端口号,由于TCP是一个私源组概念,也就是说它是由源IP地址、源端口号、目的IP地址和目的端口号确定的,当源IP地址和源端口号是一样的,但是目的端口号不一样,那么最终系统底层会把它当作两条TCP连接来处理,所以这里取巧给服务端开启了100个端口号,这就是单机百万连接的准备工作,如下图所示。
单机1024及以下的端口只能给ROOT保留使用,客户端端口范围为1025~65535,接下来用代码实现单机百万连接的模拟场景。先看服务端类,循环开启[8000-8100)这100个监听端口,等待客户端连接。下面已Netty为例编写代码如下。
案例见:springboot-netty-demo
二、服务器和客户端配置
1. 修改server配置
1.1 突破局部文件句柄的限制
首先在服务端输入命令,看一下单个进程所能支持的最大句柄数。
$ ulimit -n
输入命令后,会出现1024的数字,表示Linux系统中一个进程能够打开的最大文件数,由于开启一个TCP连接就会在Linux系统中对应创建一个文件,所以就是受这个文件的最大文件数限制。
那为什么前面演示的服务端连接数最终定格在870,比1 024小呢?其实是因为除了连接数,还有JVM打开的文件Class类也算作进程内打开的文件,所以,1 024减去JVM打开的文件数剩下的就是TCP所能支持的连接数。接下来想办法突破这个限制,首先在服务器命令行输入以下命令,打开/etc/security/limits.conf文件。
$ vim /etc/security/limits.conf
然后在这个文件末尾加上下面两行代码。
* hard nofile 1000000 * soft nofile 1000000
前面的*表示当前用户,hard和soft分别表示限制和警告限制,nofile表示最大的文件数标识,后面的数字1000 000表示任何用户都能打开100万个文件,这也是操作系统所能支持的最大值,如下图所示。
接下来,输入以下命令。
$ ulimit -n
这时候,我们发现还是1 024,没变,重启服务器。将服务端程序和客户端程序分别重新运行,这时候只需静静地观察连接数的变化,最终连接数停留在137 920,同时抛出了异常,如下所示。
1.2 突破全局文件句柄限制
首先在Linux命令行输入以下命令,可以查看Linux系统所有用户进程所能打开的文件数。
$ cat /proc/sys/fs/file-max 3210650 $ vim /etc/sysctl.conf fs.file-max=1000000
重启Linux服务器
$ cat /proc/sys/fs/file-max 1000000
2. 修改客户机设置
cat /proc/sys/net/ipv4/ip_local_port_range 值为32768 61000
大概也就是共61000-32768=28232个端可用,单个IP对外只能发送28232个TCP请求。
以管理员身份,把端口的范围区间增到最大
echo "1024 65535"> /proc/sys/net/ipv4/ip_local_port_range
现在有64511个端口可用.
以上做法只是临时,系统下次重启,会还原。 需要做永久修改, vi /etc/sysctl.conf文件,增加一行内容
net.ipv4.ip_local_port_range= 1024 65535 sysctl -p
标签:Netty,文件,单机,端口,TCP,端口号,连接,服务端 From: https://www.cnblogs.com/linjiqin/p/17052096.html