ulimit的坑让我一次次失败。转载本文请联系味觉小姐公众号。最近遇到一个很有意思的问题。其中有一组HAProxy,问题频发。登录服务器,查看cpu、内存、网络、io。最后发现机器上有60000多个连接处于TIME_WAIT状态。TIME_WAIT状态一般出现在HAProxy、Nginx等代理机器上,主要是频繁主动关机。通过修改reuse和recycling参数,可以比较快的解决问题。可以使用以下命令收集网络状态的统计信息。netstat-ant|awk'/^tcp/{++S[$NF]}END{for(ainS)print(a,S[a])}'ESTABLISHED70FIN_WAIT230CLOSING33TIME_WAIT65520这个没什么神奇的,但是65535这个数字真的太敏感了.它应该是某种上限触发的。更让我们不解的是:为什么处于TIME_WAIT状态的连接只到65535,服务不可用?号称是单机的百万连接是在吹牛吗?怎么会这么不堪?65535表示等于2的16次方减去1是一个幻数。抛开这个小数字不谈,让我们看看Linux可以支持多少个连接。1.Linux可以支持多少个连接?答案数不胜数。但是只有65535个端口。为什么只有65535个端口?这是历史原因,因为在TCP和UDP协议的开头,都会有16位分别存放源端口号和目的端口号。不幸的是,这个值是short类型,它的大小也是2^16-1。历史原因造成的一成不变的标准,就是如此根深蒂固。Linux可以支持多少个连接?答案数不胜数。以nginx为例,我们监听80端口,此时机器A连接Nginx时,最多可以发起6万个长连接。如果B机连接Nginx,也能发起6万多连接。这是因为决定一个连接是由src和dst共同决定的。Linux只能接受65535个连接的想法只能说是一个很简单的假设。65535端口对于压力测试人员来说可能太小了。但是对于服务器来说,已经绰绰有余了。2、如何支持百万级连接?从上面可以看出,连接数是没有限制的。但是Linux还有另外一层保护,那就是文件句柄的数量。通过lsof命令查看的那些东西就是所谓的文件句柄。让我们看一下几个命令的显示。ulmit,显示每个进程可以占用的文件句柄数。ulimit-n65535file-max,显示操作系统可以占用的文件句柄数的总和,对于所有进程。cat/proc/sys/fs/file-max766722file-nr,显示当前正在使用的句柄数和总句柄数。可用于监控。cat/proc/sys/fs/file-nr18240766722必须支持百万连接,操作系统级句柄和进程级句柄都必须释放。也就是说ulimit和file-max的显示必须大于一百万。3.如何设置?设置进程句柄数,常用的方式是ulimit,但是非常非常不推荐。没有别的原因,只有在同一个shell中启动的进程,ulimit设置才会生效。您打开另一个shell,或重新启动机器,ulimit更改将丢失。这是如下方式:ulimit-n1000000正确的方式是修改/etc/security/limits.conf文件。比如下面的内容。rootsoftnofile1000000roothardnofile1000000*softnofile1000000*hardnofile1000000可以看到我们可以修改特定用户的句柄数。安装es等应用时经常会遇到这种情况。es-nofile65535但即使是这种方式也需要你打开一个新的shell来运行。在当前修改的shell和修改前的shell中也不生效。xjjdog遇到过很多这样的情况,明明放宽了限制,但问题还是出现了。要查看这些更改是否对进程生效,请查看进程的内存映射文件。比如cat/proc/180323/limits,会详细显示。这个值没有你想设置的那么大。它的上限由nr_open决定。如果想要更大,需要修改/ect/sysct.conf中fs.nr_open的值。cat/proc/sys/fs/nr_open1048576如何修改file-max?建议修改/etc/sysctl.conf文件,增加如下内容。有超过600万!fs.file-max=6553560当文件数超过时,会报错kernel:VFS:file-maxlimit65535reached。综上所述。Linux即使开放一个端口,也能接受大量的连接。这些连接的上限受限于单进程文件句柄数和操作系统文件句柄数,即ulimit和file-max。为了能够持久化参数更改,我们倾向于将更改写入文件。进程的文件句柄限制可以放在/etc/security/limits.conf中,其上限由fs.nr_open限制;操作系统的文件句柄限制可以放在/etc/sysctl.conf文件中。最后别忘了在/proc/$id/limits文件中确认修改是否对进程生效。这样一来,百万人脉也是当之无愧的。我比较好奇,为什么linux默认不放过这些配置呢?它也认65535,为什么要弄成1024呢?作者简介:品味小姐姐(xjjdog),一个不允许程序员走弯路的公众号。专注于基础架构和Linux。十年架构,每天百亿流量,与你探讨高并发世界,给你不一样的滋味。我的个人微信xjjdog0,欢迎加好友进一步交流。
