一、修改用户进程可打开文件数限制
在Linux平台上,不管编写客户端程序仍是服务端程序,在进行高并发TCP链接处理时,
最高的并发数量都要受到系统对用户单一进程同时可打开文件数量的限制(这是由于系统
为每一个TCP链接都要建立一个socket句柄,每一个socket句柄同时也是一个文件句柄)。
可以使用ulimit命令查看系统容许当前用户进程打开的文件数限制:
[speng@as4 ~]$ ulimit -n
1024
这表示当前用户的每一个进程最多容许同时打开1024个文件,这1024个文件中还得除去
每一个进程必然打开的标准输入,标准输出,标准错误,服务器监听 socket,
进程间通信的unix域socket等文件,那么剩下的可用于客户端socket链接的文件数就
只有大概1024-10=1014个左右。也就是说缺省状况下,基于Linux的通信程序最多容许
同时1014个TCP并发链接。
对于想支持更高数量的TCP并发链接的通信处理程序,就必须修改Linux对当前用户的
进程同时打开的文件数量的软限制(soft limit)和硬限制(hardlimit)。其中软限制
是指Linux在当前系统可以承受的范围内进一步限制用户同时打开的文件数;硬限制
则是根据系统硬件资源情况(主要是系统内存)计算出来的系统最多可同时打开的文件数量。
一般软限制小于或等于硬限制。
修改上述限制的最简单的办法就是使用ulimit命令:
[speng@as4 ~]$ ulimit -n
上述命令中,在中指定要设置的单一进程容许打开的最大文件数。若是系统回显
相似于“Operation notpermitted”之类的话,说明上述限制修改失败,其实是
由于在中指定的数值超过了Linux系统对该用户打开文件数的软限制或硬限制。
所以,就须要修改Linux系统对用户的关于打开文件数的软限制和硬限制。
第一步,修改/etc/security/limits.conf文件,在文件中添加以下行:
speng soft nofile 10240
speng hard nofile 10240
其中speng指定了要修改哪一个用户的打开文件数限制,可用’*'号表示修改全部用户的限制;
soft或hard指定要修改软限制仍是硬限制;10240则指定了想要修改的新的限制值,
即最大打开文件数(请注意软限制值要小于或等于硬限制)。修改完后保存文件。
第二步,修改/etc/pam.d/login文件,在文件中添加以下行:
session required /lib/security/pam_limits.so
这是告诉Linux在用户完成系统登陆后,应该调用pam_limits.so模块来设置系统对
该用户可以使用的各类资源数量的最大限制(包括用户可打开的最大文件数限制),
而pam_limits.so模块就会从/etc/security/limits.conf文件中读取配置来设置这些限制值。
修改完后保存此文件。
第三步,查看Linux系统级的最大打开文件数限制,使用以下命令:
[speng@as4 ~]$ cat /proc/sys/fs/file-max
12158
这代表这台Linux系统最多容许同时打开(即包含全部用户打开文件数总和)12158个文件,
是Linux系统级硬限制,全部用户级的打开文件数限制都不该超过这个数值。一般这个系统级
硬限制是Linux系统在启动时根据系统硬件资源情况计算出来的最佳的最大同时打开文件数限制,
若是没有特殊须要,不该该修改此限制,除非想为用户级打开文件数限制设置超过此限制的值。
修改此硬限制的方法是修改/etc/rc.local脚本,在脚本中添加以下行:
echo 22158 > /proc/sys/fs/file-max
这是让Linux在启动完成后强行将系统级打开文件数硬限制设置为22158。修改完后保存此文件。
完成上述步骤后重启系统,通常状况下就能够将Linux系统对指定用户的单一进程容许同时
打开的最大文件数限制设为指定的数值。若是重启后用 ulimit-n命令查看用户可打开文件数限制
仍然低于上述步骤中设置的最大值,这多是由于在用户登陆脚本/etc/profile中使用ulimit -n命令
已经将用户可同时打开的文件数作了限制。因为经过ulimit-n修改系统对用户可同时打开文件的
最大数限制时,新修改的值只能小于或等于上次 ulimit-n设置的值,所以想用此命令增大这个
限制值是不可能的。
因此,若是有上述问题存在,就只能去打开/etc/profile脚本文件,
在文件中查找是否使用了ulimit-n限制了用户可同时打开的最大文件数量,若是找到,
则删除这行命令,或者将其设置的值改成合适的值,而后保存文件,用户退出并从新登陆系统便可。
经过上述步骤,就为支持高并发TCP链接处理的通信处理程序解除关于打开文件数量方面的系统限制。
二、修改网络内核对TCP链接的有关限制
在Linux上编写支持高并发TCP链接的客户端通信处理程序时,有时会发现尽管已经解除了系统
对用户同时打开文件数的限制,但仍会出现并发TCP链接数增长到必定数量时,再也没法成功
创建新的TCP链接的现象。出现这种如今的缘由有多种。
第一种缘由多是由于Linux网络内核对本地端口号范围有限制。此时,进一步分析为何没法
创建TCP链接,会发现问题出在connect()调用返回失败,查看系统错误提示消息是“Can’t assign requestedaddress”。同时,若是在此时用tcpdump工具监视网络,会发现根本没有TCP链接时客户端
发SYN包的网络流量。这些状况说明问题在于本地Linux系统内核中有限制。
其实,问题的根本缘由
在于Linux内核的TCP/IP协议实现模块对系统中全部的客户端TCP链接对应的本地端口号的范围
进行了限制(例如,内核限制本地端口号的范围为1024~32768之间)。当系统中某一时刻同时