`
peng_wp
  • 浏览: 41387 次
社区版块
存档分类
最新评论

[zz]linux进程打开文件数限制

阅读更多
   这是一篇转载的分析。源地址是:http://www.cnblogs.com/aka-blog/articles/filemax.html
   最近一个群里同志问了个问题,运行一个网络服务程序是提示打开的文件太多,是个多进程的程序,当时想到的是链接太多用尽了进程的文件描述符,又不知道具体的系统限制的值是多少所以用sysconf(3)测试了一下:sysconf(_SC_OPEN_MAX);,我的系统是ubuntu10.10,结果是1024。仔细查了下APUE,书中的linux kernel是2.4版本的,最大文件数限制也是1024,同时查到进程最大创建的子进程数目是999,因为socket链接是要占用文件描述符的,所以太多链接是会耗尽进程的描述符导致错误的。然后又搜索了下此限制的一些处理方法,不去更改服务器的设计,找到一个比较详细的,共同学习下,linux和类unix的其他系统都有相应的限制,各标准都有相应的限制项,可以用三个conf(sys/path/fpathconf(3))查看相应的限制的值,对跨平台的程序是很重要的。
源地址:http://bbs.51cto.com/thread-592461-1.html
提升linux下tcp服务器限制

  1 . 修改用户进程可打开文件数限制
  在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 <file_num>
  上述命令中,在<file_num>中指定要设置的单一进程允许打开的最大文件数。如果系统回显类似于“Operation notpermitted”之类的话,说明上述限制修改失败,实际上是因为在<file_num>中指定的数值超过了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连接处理的通讯处理程序解除关于打开文件数量方面的系统限制。
  2 . 修改网络内核对TCP连接的有关限制
  在Linux上编写支持高并发TCP连接的客户端通讯处理程序时,有时会发现尽管已经解除了系统对用户同时打开文件数的限制,但仍会出现并发TCP连接数增加到一定数量时,再也无法成功建立新的TCP连接的现象。出现这种现在的原因有多种。
  第一种原因可能是因为Linux网络内核对本地端口号范围有限制。此时,进一步分析为什么无法建立TCP连接,会发现问题出在connect()调用返回失败,查看系统错误提示消息是“Can't assign requestedaddress”。同时,如果在此时用tcpdump工具监视网络,会发现根本没有TCP连接时客户端发SYN包的网络流量。这些情况说明问题在于本地Linux系统内核中有限制。其实,问题的根本原因在于Linux内核的TCP/IP协议实现模块对系统中所有的客户端TCP连接对应的本地端口号的范围进行了限制(例如,内核限制本地端口号的范围为1024~32768之间)。当系统中某一时刻同时存在太多的TCP客户端连接时,由于每个TCP客户端连接都要占用一个唯一的本地端口号(此端口号在系统的本地端口号范围限制中),如果现有的TCP客户端连接已将所有的本地端口号占满,则此时就无法为新的TCP客户端连接分配一个本地端口号了,因此系统会在这种情况下在connect()调用中返回失败,并将错误提示消息设为“Can't assignrequested address”。有关这些控制逻辑可以查看Linux内核源代码,以linux2.6内核为例,可以查看tcp_ipv4.c文件中如下函数:
  static int tcp_v4_hash_connect(struct sock *sk)
  请注意上述函数中对变量sysctl_local_port_range的访问控制。变量sysctl_local_port_range的初始化则是在tcp.c文件中的如下函数中设置:
  void __init tcp_init(void)
  内核编译时默认设置的本地端口号范围可能太小,因此需要修改此本地端口范围限制。
  第一步,修改/etc/sysctl.conf文件,在文件中添加如下行:
  net.ipv4.ip_local_port_range = 1024 65000
  这表明将系统对本地端口范围限制设置为1024~65000之间。请注意,本地端口范围的最小值必须大于或等于1024;而端口范围的最大值则应小于或等于65535。修改完后保存此文件。
  第二步,执行sysctl命令:
  [speng@as4 ~]$ sysctl -p
  如果系统没有错误提示,就表明新的本地端口范围设置成功。如果按上述端口范围进行设置,则理论上单独一个进程最多可以同时建立60000多个TCP客户端连接。
  第二种无法建立TCP连接的原因可能是因为Linux网络内核的IP_TABLE防火墙对最大跟踪的TCP连接数有限制。此时程序会表现为在 connect()调用中阻塞,如同死机,如果用tcpdump工具监视网络,也会发现根本没有TCP连接时客户端发SYN包的网络流量。由于 IP_TABLE防火墙在内核中会对每个TCP连接的状态进行跟踪,跟踪信息将会放在位于内核内存中的conntrackdatabase中,这个数据库的大小有限,当系统中存在过多的TCP连接时,数据库容量不足,IP_TABLE无法为新的TCP连接建立跟踪信息,于是表现为在connect()调用中阻塞。此时就必须修改内核对最大跟踪的TCP连接数的限制,方法同修改内核对本地端口号范围的限制是类似的:
   第一步,修改/etc/sysctl.conf文件,在文件中添加如下行:
  net.ipv4.ip_conntrack_max = 10240
  这表明将系统对最大跟踪的TCP连接数限制设置为10240。请注意,此限制值要尽量小,以节省对内核内存的占用。
  第二步,执行sysctl命令:
  [speng@as4 ~]$ sysctl -p
  如果系统没有错误提示,就表明系统对新的最大跟踪的TCP连接数限制修改成功。如果按上述参数进行设置,则理论上单独一个进程最多可以同时建立10000多个TCP客户端连接。

  3 . 使用支持高并发网络I/O的编程技术

  在Linux上编写高并发TCP连接应用程序时,必须使用合适的网络I/O技术和I/O事件分派机制。
  可用的I/O技术有同步I/O,非阻塞式同步I/O(也称反应式I/O),以及异步I/O。在高TCP并发的情形下,如果使用同步I/O,这会严重阻塞程序的运转,除非为每个TCP连接的I/O创建一个线程。但是,过多的线程又会因系统对线程的调度造成巨大开销。因此,在高TCP并发的情形下使用同步I /O 是不可取的,这时可以考虑使用非阻塞式同步I/O或异步I/O。非阻塞式同步I/O的技术包括使用select(),poll(),epoll等机制。异步I/O的技术就是使用AIO。

  从I/O事件分派机制来看,使用select()是不合适的,因为它所支持的并发连接数有限(通常在1024个以内)。如果考虑性能,poll()也是不合适的,尽管它可以支持的较高的TCP并发数,但是由于其采用“轮询”机制,当并发数较高时,其运行效率相当低,并可能存在I/O事件分派不均,导致部分 TCP连接上的I/O出现“饥饿”现象。而如果使用epoll或AIO,则没有上述问题(早期 Linux内核的AIO技术实现是通过在内核中为每个I/O请求创建一个线程来实现的,这种实现机制在高并发TCP连接的情形下使用其实也有严重的性能问题。但在最新的Linux内核中,AIO的实现已经得到改进)。

  综上所述,在开发支持高并发TCP连接的Linux应用程序时,应尽量使用epoll或AIO技术来实现并发的TCP连接上的I/O控制,这将为提升程序对高并发TCP连接的支持提供有效的I/O保证。
分享到:
评论

相关推荐

    应用广泛的嵌入式操作系统——ZZ-Linux.pdf

    应用广泛的嵌入式操作系统——ZZ-Linux.pdf

    base zz zz zz zz

    base zz zz zz zz zz base zz zz zz zz zz base zz zz zz zz zz base zz zz zz zz zz

    linux db2 安装过程中可能缺少的 libaio 安装文件

    linux db2 安装过程中可能缺少的 libaio 安装文件

    paxos-simple.7zz

    paxos-simple描述分布式一致性的经典算法,许多的算法都是其变种,有兴趣的可以下载看看

    linux教程——很使用的那种

    linux中的文件(普通文件或设备文件等)都必须有挂在点,只有挂载到一个目录下才能访问,swap分区是不需要挂载点的,在分区的时候,将文件系统类型选为swap,挂载点自动会变为灰色。一般linux中的swap大小为内存的两倍。...

    7zip_linux_21.7.deb

    根据 7zip 官方版本制作的 deb 安装包,可以直接在Linux 系统上使用 `dpkg...本资源仅仅是为方便安装进行的deb包封装,并对可执行文件 `7zz` 进行了重命名复制为 `7zip`,因此安装后使用时可以直接使用`7zip`作为命令。

    ZZ561401.CAB

    ZZ561401.CAB ZZ561401.CAB ZZ561401.CAB

    基于Linux下的Web服务器配置与基于域名的虚拟主机.pdf

    通过本文档,可以掌握Linux中架设Web服务的工作技能,理解主配置文件中的语句格式、虚拟目录、虚拟主机等,在掌握了Web服务器的基本配置后,可以拓展Web服务器的一些其他功能。 此外,本文档还介绍了基于域名的虚拟...

    wincc AX NF ZZ

    wincc SIMATIC WinCC是第一个使用最新的32位技术的过程监视系统,具有良好的开放性和灵活性。 从面市伊始,用户就对SIMATIC WinCC印象深刻。

    vim安装包,用于linux十分便捷

    o 后面跟文件路径,可以横分屏打开文件 O 后面跟文件路径,可以竖分屏打开文件 w 保存 q 退出 qall 全部退出 wqall 全部保存退出 qall 全部强制退出 s/if/hello/ 把本行的第一个if替换成hello 1,$s/if/...

    ZZ-2021012 数控综合应用技术赛项规程.pdf

    2021年全国职业院校技能大赛参赛选手备赛参照使用。

    利用C语言程序编辑GDSII文件(zz).pdf

    利用C语言程序编辑GDSII文件(zz).pdf

    Advanced Linux Programming.pdf

    Advanced Linux Programming zz from: 20本最好的Linux免费书籍 http://cocre.com/?p=355

    china_zz_20191009.json

    该文件是中国包含省市县的geojson数据,下载后需要将文件打开,然后删除首行"china_zz_20191009 ",包含空格一起删除即可使用

    入门学习Linux常用必会60个命令实例详解...

    :split file或:new file 用新窗口打开文件 split打开的窗口都是横向的,使用vsplit可以纵向打开窗口。 Ctrl+ww 移动到下一个窗口 Ctrl+wj 移动到下方的窗口 Ctrl+wk 移动到上方的窗口 关闭窗口 :close 最后一个窗口...

    ZZ_MODIFIED_GEEBINF.ENS.zip endnote的样式文件

    适合中国论文参考文献的一般格式

    zz CAD快速计算长度插件

    在CAD中想要快速测量长度,在CAD工具栏找到加载应用程序,再点击加载 加载成功后在输入栏输入“zz”(不分大小写)在选择你需要测量的线段即可。

    超出NLO QCD的高横向动量的ZZ产生

    我们研究了四轻子最终状态ℓ+ℓ-ℓ+ℓ-的产生,这些状态主要由一对弱电Z玻色子ZZ产生。 使用LoopSim方法,我们合并ZZ和ZZ + jet的NLO QCD结果,并获得ZZ产生的近似NNLO预测。 还包括对ZZ过程的精确胶子融合环平方的...

    vi编辑器的使用,linux快速入门

    ZZ 快速保存文件的内容,然后退出vi。功能和“:wq”相同。 :w filename 相当于“另存为”。 :n,mw filename 将第n-m行的文本保存到指定的文件filename中。 三、vi长指令和短指令 长指令:以冒号开头,键入冒号后...

Global site tag (gtag.js) - Google Analytics