今天我遇到了tomcat日志报的错误信息”too many open files”,第一意识就想到了是ulimit控制的”open files“限制。然而问题来了。我在/etc/profile里加入了 ulimit -n 4096保存之后,普通用户登录的时候均会收到一条错误信息ulimit: open files: cannot modify limit: Operation not permitted。然后普通用户的open files限制还是默认值1024。
The kernel allocates file handles dynamically, but as yet it doesn’t free them again. The value in file-max denotes the maximum number of file-handles that the Linux kernel will allocate. When you get lots of error messages about running out of file handles, you might want to increase this limit.
The three values in file-nr denote the number of allocated file handles, the number of unused file handles and the maximum number of file handles. When the allocated file handles come close to the maximum, but the number of unused file handles is significantly greater than 0, you’ve encountered a peak in your usage of file handles and you don’t need to increase the maximum.
再回过头来看这两段话,不知道你意识到了没有,文中只提到了file-max的增加,而没有提到了该值的减少。那些在操作ulimit时同时操 作了file-max的哥们儿,估计无一例外地将file-max设置成了4096或者2048。但以似乎也没有因此而导致系统无法打开文件或者建议连 接。(实际上,我将file-max的值设备成256,然后使用shell编写用vi打开500个文件角本运行,并没有得到任何错误信息,查看file- nr的值,系统当前分配的句柄值已经远超过了后面的最大值。所以我猜想对于file-max的任何减少的操作都是毫无意义的,姑且不去管他。实践中需要减 少file-max的时候总是不多见的。 )实事证明我犯了一个致命的错误。我测试的时候使用的是root用户,而当我再次使用普通用户测试的时候,预料中的错误信息出现了:”Too many open files in system”。可见,file-max的减少对系统也是影响力的。前面的结论“所以我猜想对于file-max的任何减少的操作都是毫无意义的”是错误 的。
然后便是/etc/security/limits.conf文件,这个文件很简单,一看就能明白。
于是我按照注释中描述的格式两个两行:
* soft nofile 4096
* hard nofile 4096
恐怖的是,网上居然有人说改了这个设置是需要重启系统的!实在是让人想不通啊,鼎鼎大名的UNIX系统,怎么可能因为这么小小的一个改动就需要 重启系统呢?结果当我再次以普通用户登录的时候,那个”ulimit: open files: cannot modify limit: Operation not permitted”提示没有了,查看ulimit -n,果然已经变成了4096。
对于一般的应用来说(象Apache、系统进程)1024完全足够使用。但是如何象squid、mysql、java等单进程处理大量请求的应用来说就有点捉襟见肘了。如果单个进程打开的文件句柄数量超过了系统定义的值,就会提到“too many files open”的错误提示。如何知道当前进程打开了多少个文件句柄呢?下面一段小脚本可以帮你查看: