CentOS VPS 上的 PHP exec“无法分叉”间歇性错误

CentOS VPS 上的 PHP exec“无法分叉”间歇性错误

使用:

PHP 5.5.10
nginx 1.5.10
Centos 6.5

a xen-based 4GB VPS

我的网站使用加密的 PayPal 按钮。此加密由以下代码完成:

$openssl_cmd = "($OPENSSL smime -sign -signer $MY_CERT_FILE -inkey $MY_KEY_FILE " .
               "-outform der -nodetach -binary <<_EOF_\n$data\n_EOF_\n) | " .
               "$OPENSSL smime -encrypt -des3 -binary -outform pem $PAYPAL_CERT_FILE";

exec($openssl_cmd, $output, $error);

现在已经好几次(相隔几天)按钮开始无法编码。如果我运行“service php-fpm restart”,一切又恢复正常了。

这是给出的错误:

PHP Warning:  exec(): Unable to fork [(/usr/bin/openssl smime -sign 
    -signer /var/www/my-pubcert.pem -inkey /var/www/my-prvkey.pem -outform der 
    -nodetach -binary <datasnipped>) | /usr/bin/openssl smime -encrypt -des3 
    -binary -outform pem /var/www/paypal_cert.pem]

一旦发生这种情况,它似乎会不断发生,直到我重新启动 php-fpm。

有什么想法我应该采取什么路线来调试/修复这个问题?

谢谢

答案1

最有可能的是,PHP 进程在某个时候开始使用大量内存(您可以在 top 中检查,按 M 按内存对进程进行排序)。尝试设置“pm.max_requests = 100”,或者无论如何,设置比现在低得多的值(或者,如果是 0,则设置为 100 左右,这意味着无限)。

顺便说一句,加密的更好方法是使用 PHP OpenSSL 库,而不是执行 OpenSSL 的命令行界面。

编辑:

根据您的要求(即使部分内容与主题无关),您可以找到 PHP 中 2 个 OpenSSL 函数的文档和示例代码这里这里。您可能需要重新编译 PHP 以支持 OpenSSL 或安装所需的模块(通常它应该已内置)。

答案2

我会查看您打开了多少个文件句柄,以及将最大值设置为多少。sysctl fs.file-nr是一个很好的起点。如果第一个数字接近最后一个数字,则说明文件句柄用完了!您可以通过在 systcl.conf 中设置它来增加它们,或者通过sysctl -w fs.file-max=100000。如果是这种情况,我会在您的代码中的其他地方查找文件句柄无法关闭的原因。

答案3

我在 CentOS 6.3 上使用 PHP 5.3.3 时遇到了这个错误,因为 Web 服务器用户没有有效的 shell。将 .bashrc 添加到 nginx 用户的主目录可以解决这个问题。

请参阅此重复问题的答案:https://stackoverflow.com/questions/20648949/php-warning-exec-unable-to-fork/24517481#24517481

相关内容