Назад | Перейти на главную страницу

Периодическая ошибка PHP exec «не удается выполнить вилку» на CentOS VPS

С помощью:

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.

Есть идеи, по какому маршруту я должен пойти, чтобы отладить / исправить это?

Спасибо

Я бы посмотрел, сколько файловых дескрипторов у вас открыто и какой максимальный размер установлен. sysctl fs.file-nr это хорошее место для начала. Если первое число близко к последнему, у вас заканчиваются дескрипторы файлов! вы можете настроить их, установив его в systcl.conf, или sysctl -w fs.file-max=100000. Если это так, я бы посмотрел в другом месте вашего кода, почему файл обрабатывает закрытие.

Скорее всего, процессы PHP в какой-то момент начнут использовать много памяти (вы можете проверить это вверху, нажмите M, чтобы отсортировать процессы по памяти). Попробуйте установить pm.max_requests = 100 или, в любом случае, гораздо меньшее значение того, что у вас есть сейчас (или около 100, если оно равно 0, что означает бесконечность).

Кстати, гораздо лучшим подходом к шифрованию было бы использование библиотеки PHP OpenSSL, а не выполнение интерфейса командной строки OpenSSL.

Редактировать:

По вашему запросу (даже если он частично не по теме) вы можете найти документацию и пример кода для 2 функций OpenSSL в PHP. Вот и Вот. Возможно, вам потребуется перекомпилировать PHP с поддержкой OpenSSL или установить необходимый модуль (обычно он должен быть встроен).

В PHP 5.3.3 на CentOS 6.3 я столкнулся с этой ошибкой, потому что у пользователя веб-сервера не было действующей оболочки. Добавление .bashrc в домашний каталог пользователя nginx исправило это для нас.

См. Ответ как этот обманчивый вопрос: https://stackoverflow.com/questions/20648949/php-warning-exec-unable-to-fork/24517481#24517481