Apache PHP/OSX Mavericks: - 打开流失败:打开的文件太多。

22
我最近升级到了OSX Mavericks,自那以后,在我的开发机上开始出现上述错误。代码中没有明显的问题(它是一个自动生成的Yii示例应用程序)。升级到Mavericks的过程中发生了以下变化:
  1. PHP从OSX Lion捆绑的5.2.x版本升级到了5.4.x。
  2. 我必须获取适用于PHP 5.4的Zend Debugger,方法是安装Zend Server,获取ZendDebugger.so并卸载Zend Server(这是因为Zend不提供独立的php 5.4.x调试器版本)。
自那时起,可能加载和重新加载网站几次后就会出现此问题。在出现此错误后,我的Web服务器将为本地主机上托管的任何其他应用程序返回相同的错误。我必须提到静态网页可以正常服务。
我看到了关于这个主题的几个threads。大多数指出代码中存在问题,其中文件句柄未被正确关闭,从而超过了打开文件限制阈值。我还发现了这个thread,它似乎表明这可能是一个zend调试器问题。也有一个bug report针对php 5.2.x进行了提交。在here的线程中,我尝试了以下操作:
$ ulimit -a

报告如下:

open files (-n) 256

另外,

sysctl -a | grep files

返回,

kern.maxfiles = 12288
kern.maxfilesperproc = 10240
kern.maxfiles: 12288
kern.maxfilesperproc: 10240
kern.num_files: 3248

另一个有趣的thread建议使用以下方法来提高此限制(目前为256):

ulimit -n 1024

我已经尝试了所有方法,但似乎没有任何作用。问题也不是一致性可重现的。
我想知道是否使用 "ulimit -n 1024" 会影响 Apache,因为根据我所读的,它会影响 shell 可以打开的文件数。
感谢任何帮助。
编辑:
1. 重新启动 Apache 有所帮助,直到再次遇到错误。 2. 让 Web 服务器闲置一段时间(没有确定的间隔)也有所帮助。
7个回答

19

不要抄袭,这篇文章来自http://docs.basho.com/riak/latest/ops/tuning/open-files-limit/#Mac-OS-X

要检查您的Mac OS X系统上当前的限制,请运行以下命令:

$ launchctl limit maxfiles

最后两列分别是软限制和硬限制。

要调整OS X 10.7(Lion)或更新版本中的最大打开文件限制,请编辑/etc/launchd.conf并适当增加两个值的限制。

例如,要将软限制设置为16384个文件,硬限制设置为32768个文件,请执行以下步骤:

验证当前限制:

$ launchctl limit

    cpu         unlimited      unlimited
    filesize    unlimited      unlimited
    data        unlimited      unlimited
    stack       8388608        67104768
    core        0              unlimited
    rss         unlimited      unlimited
    memlock     unlimited      unlimited
    maxproc     709            1064
    maxfiles    10240          10240

编辑(或创建)/etc/launchd.conf 并增加限制。添加类似以下内容的行(使用适合您环境的值):

limit maxfiles 16384 32768

保存文件,并重新启动系统以使新的限制生效。重新启动后,使用launchctl limit命令验证新的限制:

$ launchctl limit

    cpu         unlimited      unlimited
    filesize    unlimited      unlimited
    data        unlimited      unlimited
    stack       8388608        67104768
    core        0              unlimited
    rss         unlimited      unlimited
    memlock     unlimited      unlimited
    maxproc     709            1064
    maxfiles    16384          32768

感谢您的努力。我提到过我尝试增加最大打开文件限制,但这并没有帮助我太多,因为最终每个限制都会被触及。 - Code Poet
1
嗨,我尝试了这个方法,但即使在重新启动我的Mac后,launchctl limit仍然返回原始值。似乎/etc/launchd.conf没有被考虑进去。我正在运行Mavericks 10.9。有什么想法吗? - BoilingLime
在Mavericks上,“maxfiles”硬限制应该是“无限制”。无论如何,您仍然可以在“/etc/launchd.conf”中设置不同的限制和其他环境变量。但要注意:如果此文件中存在语法错误,则所有内容都将被忽略(虽然这仍然比拒绝引导或登录要好)。 - okket
3
不再适用,请查看http://unix.stackexchange.com/questions/108174/how-to-persist-ulimit-settings-in-osx-mavericks。 - Dewayne

5

如果您在运行 Apache 时遇到此问题,可以配置 Apache 来增加限制:

$ sudo vi /usr/sbin/apachectl

找到: ULIMIT_MAX_FILES=""

并将此行更改为类似下面的内容:

ULIMIT_MAX_FILES="ulimit 4096"

然后执行: sudo apachectl restart

这对于 CLI 脚本不起作用。但是,在您的 ~/.bash_profile(或等效文件)中直接添加 ulimit 应该可行。

这样做的优点是可以针对 Apache 和终端设置特定的限制,而不影响其他应用程序。

另外,您应该能够通过将适用于该环境的命令替换为 ulimit 来将此方法适应于其他操作系统。


这个方法在我的MAC OS Mojave 10.14.5上解决了问题,谢谢。 - H2ONOCK

2
我在El Capitan上遇到了同样的问题。在这里找到了一篇文章(链接),对解决方案表示感谢。按照以下步骤进行操作:
调整打开文件限制 要在Yosemite及以上版本中全局调整打开文件限制,您需要创建两个配置文件。第一个是属性列表(即plist)文件,在/Library/LaunchDaemons/limit.maxfiles.plist中包含以下XML配置:
    <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  <plist version="1.0">
    <dict>
      <key>Label</key>
        <string>limit.maxfiles</string>
      <key>ProgramArguments</key>
        <array>
          <string>launchctl</string>
          <string>limit</string>
          <string>maxfiles</string>
          <string>65536</string>
          <string>65536</string>
        </array>
      <key>RunAtLoad</key>
        <true/>
      <key>ServiceIPC</key>
        <false/>
    </dict>
  </plist>

这将把打开文件的限制设置为65536。第二个plist配置文件应存储在/Library/LaunchDaemons/limit.maxproc.plist中,其内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple/DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  <plist version="1.0">
    <dict>
      <key>Label</key>
        <string>limit.maxproc</string>
      <key>ProgramArguments</key>
        <array>
          <string>launchctl</string>
          <string>limit</string>
          <string>maxproc</string>
          <string>2048</string>
          <string>2048</string>
        </array>
      <key>RunAtLoad</key>
        <true />
      <key>ServiceIPC</key>
        <false />
    </dict>
  </plist>

两个plist文件必须归属于root:wheel,并且具有-rw-r--r--权限。重新启动系统。

此外,建议在.bashrc中为用户会话设置它们并添加:

ulimit -n 65536
ulimit -u 2048

希望这能有所帮助。

1

我可能遭受了信息过载。这里提供了一个可能的解释,我在原帖中也提到了它。我想我错过了一个小细节,即OP提到他正在使用Mac OSX 10.8.x。我使用的是10.9,所以我从该页面下载了zenddebugger.so文件,情况看起来不错。整天都没有收到过任何一个too many open files

因此,也许这是一个ZendDebugger问题。


这个解决了我的问题。一个多月以来我再也没有看到那个错误了。 - Code Poet

0

0

0
关于上面的调试器补丁答案。不幸的是,上面提供的答案对我无效,因为它适用于php版本5.4,而我必须限制自己使用php 5.3。
Zend发布了他们的服务器6.3版本,支持php 5.3。我已经玩了一会儿安装(在将我的ulimit降回到Apple的默认值后)来测试它,并没有遇到任何问题。在升级之前,我无法进行任何php调试,而不提高那个限制。

是的,这个错误已经在Zend Server 6.2中得到修复了。http://forums.zend.com/viewtopic.php?t=110823&start=10 - drewish

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接