我转移到使用 fcgid 的非托管服务器(之前我一直在使用 mod_php),在错误日志中我看到大量这样的错误:
[2012 年 4 月 23 日星期一 21:17:12] [警告] [客户端 66.249.68.233] mod_fcgid:读取数据超时 31 秒 [2012 年 4 月 23 日星期一 21:17:12] [错误] [客户端 66.249.68.233] 脚本标头过早结束:index.php
[2012 年 4 月 23 日星期一 17:59:51] [警告] [客户端 74.117.180.58] mod_fcgid:读取数据超时 31 秒 [2012 年 4 月 23 日星期一 17:59:51] [警告] [客户端 74.117.180.58] (110)连接超时:mod_fcgid:ap_pass_brigade 在 handle_request_ipc 函数中失败
在备份期间负载较高 (2-3) 时,似乎会出现更多此类情况,我甚至在备份期间运行 tar / mysqldump 时,在负载为 3 时成功复制了此情况(用户在 30 秒后看到 500 错误消息)。服务器可能超载了吗?这个问题似乎与如果下载中断,PHP + Fcgid 将挂起但不一样。
这是一台顶级服务器,我很惊讶这太过分了。以下是一些规格:6-7 个使用 Webmin 的 Drupal 站点
- Intel® Core™ i7-2600 四核处理器,包含超线程技术
- 内存 16 GB DDR3 内存
- 硬盘2 x 3 TB SATA 6 Gb/s HDD 7200 rpm(软件 RAID 1)
- NIC1 Gbit OnBoard 以 100 Mbit 连接
答案1
这些错误意味着脚本运行时间超过 31 秒,因此被终止,正如您的 fcgid.conf 所述。顺便说一下,标准超时时间为 40 秒。
您可以通过编写 test.php 轻松检查此行为:
<?php sleep(32); ?>
这应该会给您一个错误 500,并将此错误放入您的日志中。
有两种方法可以解决这个问题:
- 重新制作你的index.php(或背后的应用程序)并解决潜在的循环问题(脚本永远运行并在 31 秒后终止)。
将超时时间设置得更长。这必须针对每个虚拟主机执行(不要忘记 SSL!),因为每次加载另一个虚拟主机时此设置都会更改,并且会一直保留到生成的进程终止。
最简单的方法是编辑/etc/apache2/mods-available/fcgid.conf
。这就是我们正在使用的:IdleTimeout 3600
ProcessLifeTime 7200
IPCConnectTimeout 8
IPCCommTimeout 600
BusyTimeout 300
编辑:哦,第二个错误与 URL 中的查询字符串过长有关。要允许更长的查询字符串,还需要编辑fcgid.conf
并插入
MaxRequestLen 15728640
不要忘记重新启动 apache 来终止所有正在运行的进程,这样它们才能获得新的配置。
答案2
mysqldump 默认在运行时写入锁定数据库,这样数据在备份期间就不会被更改,否则会导致损坏。Drupal 每次请求时都会写入数据库,因此 mysqldump 运行时请求会挂起,并最终超时。
如果你正在使用 InnoDB(或可以转换为它),那么你可以使用Percona XtraBackup进行热备份。除此之外,不要将 mysqldump 传输到 tar 或 gzip;转储 .sql 文件,然后在 mysqldump 完成(并释放锁)后对其运行 tar/gzip。
还要注意,在某些版本的 fcgid 中,有一个错误会导致它仅应用 VirtualHost 块中的设置,并全局应用最后读取的块中的设置。