Socket并发配置之一config的配置

一、Socket并发的配置

在Socket并发访问中,五元组(源IP,目的IP,协议号,源端口,目的端口)的存在,使得其的可变化比较大,但其中大多数应用的场景可以抽象到一个具体的机器中来,在这一个具体的机器的配置中,引申出未来集群和分布式的配置管理。在一个具体应用中,一般来说的是一个单机,IP是固定的,但是端口是可以动态扩展的(0~65536,但是其中有不少被默认占用了),也就是说,作为一个单机,只考虑简单的变化情况,那么只有IP和端口两个作为组合的条件。如果有写过实际程序的,可以发现在客户端,一般就是自动寻找端口的。也就是说IP和自动配置的端口来实现对不同服务器的绑定(或者说关闭后再次连接)。
服务端也可以利用这种情况来实现多进程多并发的监听,比如同时监听多个IP+不同的端口。但是,如果再进一步限制,只在单IP和同一个端口上进行高并发如何设置呢?也就是说,如果解决了这种单一的情况,那么其它复杂的情况就都可以顺理成章的解决。
下面就对这个问题进行一个初步的回答,首先要解决的是,一个进程或者一个线程,到底能打开多少个文件?因为在LINUX中,一切都是文件。网络Socket也是fd。在网上有很多回答,也有很多大牛的精彩回复,结论是2**32*2**16 = 2^48个(即两单一乘多端口)。但是其中有一些是保留的或者被天然占有的,所以会少一些,但这无所谓。
但是应该知道,理论是理论,实际是实际,在实际的开发中,每个TcpIP连接的建立,都是要耗费资源的,一般认为创建连接要创建接收和发送缓冲区各4KB共8KB,再加上协议控制块的2KB,共10KB,因为它们用:

$ sysctl -A |grep tcp_.mem
net.ipv4.tcp_rmem = 4096        87380   6291456
net.ipv4.tcp_wmem = 4096        16384   4194304

但是很遗憾,这个不太准确,因为还是常说的那句话,理论是理论,实际是实际,在实际情况中,为了更好的利用Socket通信,其实,在TCP建立连接时,并不会立刻去分配两个缓冲区。而实际情况是大约会在3K略多一些,如果有兴趣可以查找一下相关资料。
但是,再进一步,真正的应用场景中,或多或少都会有业务逻辑,这才是真正的吃资源的大户,比如你是做短视频的,单纯上亿个连接有什么意义?你必须把用户的视频分发出去,同样回到一个机器上,就是如何压榨出单机最大的负荷,从而降低成本。而视频最吃的是什么,是CPU,是显卡还是带宽还是内存,亦或是其中几个组合等。就需要根据实际情况不断的调整。
回到正题,仍然要解决最基础的问题,如何扩大并发数量,服务端默认的连接数量是1024,也就是超过这个数量,一个进程就无法再打开多的文件句柄了,也就是无法再接收更多的连接了。请继续向下看,来解决这些问题。

二、修改用户及内核配置文件

要解决问题,先得找到问题的症结,需要修改文件打开数量的限制,需要同时修改内核及用户配置文件以适应更高并发,做如下改动:
1、用户态修改:

/etc/security/limits.conf
vim /etc/security/limits.conf
* soft  nofile  65536
* hard  nofile  65536

将上面两个65536修改成了1065536。

2、修改内核态的配置
在/proc/sys/fs文件夹下,有两个文件,一个为nr_open,表示单个进程打开文件句柄数上限;另一个为file-max,表示系统范围内所有进程可打开的文件句柄的数量限制。用下面的命令看一下:

cat /proc/sys/fs/nr_open                    
cat /proc/sys/fs/file-max                    

其中nr_open默认为1048576,即一百万,暂时不用修改。
file-max默认为180566,那么就将其修改为1048576,和上面保持一致。
修改/etc/sysctl.conf文件,在里面修改file-max的值为1048576,然后保存退出。
通过运行sysctl命令,将/etc/sysctl.conf文件的内容写到/proc/sys/fs/file-max中。
注意:上述修改完成后,要使用命令重新查看,防止由于种种原因导致未修改成功。

3、为了调试,增加了修改内核转储文件大小设置
使用ulimit命令来操作:

ulimit -c  查看
ulimit -c N  设置大小,N单位为k。

上面的设置只适合当前终端,退出后变为0
永久修改:

/etc/profile:全局
.bash_profile:当前用户
ulimit  -c  N
source .bash_profile

三、问题及解决

1、出现问题
上述配置修改完成后,远程连接突然失败,然后再也无法SSH登陆。用了各种办法,咨询运维表示是22端口被占用。修改密码啥的都用了,仍然无法登陆。只好再次新开一个虚拟机,再次重复上面的第一步,然后突然无法登陆。高度怀疑是不是修改此处造成的,幸而还有一台电脑仍在此虚拟机内,将值改回,立刻可以登陆。这才明白 。那么有没有办法来规避这个问题呢?看下面的命令:

ulimit -n  查看当前值
ulimit - n  N,临时设置一个值,如果N合适,则成功,不合适,则报一个错误。

用这个条命令测试,结果发现,设置成1024*1024成功,再大则不可以。即这种设置的验证方法,可以防止出现上面的错误 。

2、解决问题
经过查询资料,发现只要设置:nr_open>=limits.conf 的 hard nofile,就不会出现这种问题,方法如下:
a、sysctl 设置 fs.nr_open 大于等于 /etc/security/limits.conf 的 hard nofile
b、直接设置 /proc/sys/fs/nr_open 会报fsync写入问题,可以echon N > /proc/sys/fs/nr_open

四、总结

一些小细节的问题,看似简单,其实挺复杂,一些看上去挺扎手的问题,其实就是一个小小的配置文件造成的。理论一定要和实践相结合!
在这里插入图片描述

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值