我的 Apache 抛出了内部服务器错误 500 错误和如下日志:
> [Sun Apr 07 23:35:24 2013] [error] [client 124.162.30.45] (2)No such
> file or directory: FastCGI: failed to connect to server
> "/home/magda_00aa/sportxxx.pl/sportxxx.pl.0fake": socket file
> descriptor (1063) is larger than FD_SETSIZE (1024), you probably need
> to rebuild Apache with a larger FD_SETSIZE, referer:
> http://www.surf4web.com/surfing.php?id=haoduodeng2012
我已经提高了内部的 FD 限制:
cat /usr/include/bits/typesizes.h | grep FD
#define __FD_SETSIZE 65536
和
cat /usr/include/linux/posix_types.h | grep FD_SETSIZE
#undef __FD_SETSIZE
#define __FD_SETSIZE 65536
#define __FDSET_LONGS (__FD_SETSIZE/__NFDBITS)
并且
/sbin/sysctl fs.file-max
fs.file-max = 512000
ulimit -n
1000000
但它没有帮助。如果虚拟主机超过 350 个,我的 Apache 仍然会崩溃 :/
我在 CentOS 5.9 64 位上 - 内核 3.0.65-1.el5.elrepo
答案1
这是因为 mod_fastcgi 使用 select() 作为多路复用选项。Select 对于这种东西来说非常糟糕,手册页对 select 进行了说明;
fd_set 是固定大小的缓冲区。如果执行 FD_CLR() 或 FD_SET() 时 fd 值为负数或等于或大于 FD_SETSIZE,则会导致未定义的行为。此外,POSIX 要求 fd 是有效的文件描述符。
FD_SETSIZE 通常为 1024,因此一般不支持超过 1024 的文件描述符。您可以像之前一样调整 FD_SETSIZE 包含大小,但进行这样的更改可能会影响其他旨在符合 POSIX 标准的程序。在我看来,如果应用程序编写者建议修改系统源代码来实现这一点,那么应用程序从根本上就是有问题的。
我建议放弃 mod_fastcgi 并使用其他实现。具体如何操作取决于您启动 FastCGI 守护进程的方式。
mod_fcgid
是一个选项,或者较新的 Apachemod_proxy_fcgi
也可以使用。