keep live c100w - yaokun123/php-wiki GitHub Wiki
如何做到单机百万长连接
一、too many open files问题解决
linux下一切皆文件,包括socket
1、ulimit -n 单个用户能打开的文件上线
1、ulimit -n:查看当前设置。
2、ulimit -n 1000000:进行临时性设置。
3、要想永久生效,你可以修改/etc/security/limits.conf文件,增加下面的行:
* hard nofile 1000000
* soft nofile 1000000
root hard nofile 1000000
root soft nofile 1000000
hard limit不能大于/proc/sys/fs/nr_open,因此有时你也需要修改nr_open的值
2、fs.nr_open 单个进程上可打开的文件数
1、临时性设置:执行echo 2000000 > /proc/sys/fs/nr_open
2、永久设置:修改/etc/sysctl.conf文件,增加fs.nr_open = 2000000
3、fs.file-max 整个系统上可打开的最大文件数
1、临时性设置:echo 1000000 > /proc/sys/fs/file-max
2、永久设置:修改/etc/sysctl.conf文件,增加fs.file-max = 1000000
4、查看当前系统使用的打开文件描述符数,可以使用下面的命令:
cat /proc/sys/fs/file-nr
10208 0 1582530
其中第一个数表示当前系统已分配使用的打开文件描述符数
第二个数为分配后已释放的(目前已不再使用)
第三个数等于file-max。
二、Cannot assign requested address问题解决
端口号限制
sysctl -a|grep net.ipv4.ip_local_port_range
net.ipv4.ip_local_port_range = 32768 61000
端口范围:61000 - 32768 = 28232
sudo sysctl -w net.ipv4.ip_local_port_range="1025 61000"
三、Connect耗时越来越大,怎么解决?
1、临时端口分配策略
/proc/sys/net/ipv4/ip_local_port_range文件指定了临时端口号的下界low和上界high,默认情况下,low是偶数,在我的电脑上low和hight的值分别是32768和61000
-
优先给bind(分配随机的与low奇偶性不同的端口,也就是奇数端口。如果奇数端口号分配完了,才会尝试分配偶数端口。
-
优先给connect分配与low奇偶性相同的临时端口,也就是偶数端口。如果偶数端口号分配完了,才去尝试分配奇数端口。
2、connect性能衰减的原因
-
获取port range中设置的端口范围,将端口资源按照偶数、奇数分为两组,依次尝试去获取,每次获取的起点是随机的。
-
当我们完全占用偶数组的端口后,所有后续的connect调用,所需的源端口应该位于奇数组中,然而该函数依旧会尝试完整遍历偶数组资源。
3、高版本 Linux 协议栈源端口选择性能急剧衰减问题
自kernel 4.2开始,端口资源的分配策略改了
4、解决方式 由于是linux内核随机选择端口的问题,无法有效解决这个问题,临时解决方式就是人为指定端口。
四、虚拟IP
每台机器的临时端口数量会有限制,那么单台机器怎么能发送百万长连接呢?可以使用多台机器、虚拟机、虚拟IP等方式来解决。
ifconfig enp0s31f6:0 192.168.31.10 netmask255.255.224.0 up
enp0s31f6:0:表示这个VIP绑定的多目标网卡
192.168.31.10:这个虚拟IP
up:表示启用这个VIP
创建多个虚拟IP的脚本
#!/bin/bash
NETMASK="255.255.224.0"
IFS=$'\n' IPS=($(cat ip.txt))
for i in "${!IPS[@]}";do
echo ifconfig enp0s31f6:$i ${IPS[$i]} netmask $NETMASK up
ifconfig enp0s31f6:$i ${IPS[$i]} netmask $NETMASK up
done
ip.txt
192.168.31.10
192.168.31.11
192.168.31.12
......
五、Linux中每个TCP连接最少占用多少内存
(3605592KB-355880kB)/1000/1000 = 3.25KB