PHP-FPM + exec() очень странное поведение первого.

xInOrK

Новичок
Проверил это поведение на FreeBSD 7.2 и на Debian Squeeze с одинаковой версией PHP.
Имеется Nginx + PHP-FPM с очень простой настройкой, особо не заметил чтобы уменьшение или увеличение параметров что либо меняло.

PHP:
PHP 5.3.23 with Suhosin-Patch (cli) (built: Mar 26 2013 14:07:09)
Copyright (c) 1997-2013 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2013 Zend Technologies
PHP:
[storage]
listen = /tmp/fpm_storage.sock
listen.owner = storage
listen.group = storage
listen.mode = 0666
user = storage
group = storage
pm = dynamic
pm.max_children = 50
pm.start_servers = 10
pm.min_spare_servers = 5
pm.max_spare_servers = 35
Очень простенький конфиг NGINX c таким блоком для php файлов:
PHP:
  location ~ \.php$ {
    fastcgi_pass                   unix:/tmp/fpm_storage.sock;
    fastcgi_index                  index.php;

    include fastcgi_params;
    fastcgi_param  DEVENV          on;
    fastcgi_intercept_errors       on;
    fastcgi_ignore_client_abort    off;
    fastcgi_connect_timeout        60;
    fastcgi_send_timeout           180;
    fastcgi_read_timeout           180;
    fastcgi_buffer_size            128k;
    fastcgi_buffers             4  256k;
    fastcgi_busy_buffers_size      256k;
    fastcgi_temp_file_write_size   256k;
  }
На этом же сервере в ~/.ssh/config прописываю вот такое:
PHP:
Host *
  ConnectTimeout 2
  TCPKeepAlive yes
  Port 22
  Identityfile ~/.ssh/server1000
  ControlMaster no
  ControlPath ~/.ssh/master-%r@%h:%p

Host server1000
  Hostname 192.168.2.2
На нём же подключаюсь из консоли к удалённому серверу по SSH:
PHP:
# ssh -o "ServerAliveInterval 15" -o "ServerAliveCountMax 1" -MN user@server1000
# ls -la ~/.ssh/
srw------- 1 storage storage    0 Mar 26 15:46 [email protected]:22
теперь могу выполнять команды не вводя пароль: ssh server1000 whoami

теперь к странному поведению, создаю простой скрипт на PHP:
PHP:
<?php
for ($i = 0; $i < 100; ++$i) {
  echo exec("ssh [email protected] ls -la");
}
?>
Захожу по HTTP на него и жду, проходит примерно 100 секунд, при этом слежу за нагрузкой на сервере она в норме скачков никаких нету, всё впорядке, но как только в браузере появляется результат, мастер процесс php-fpm сжирает почти весь CPU и так висит, как долго не знаю ждал часа два ничего не поменялось. В php-fpm.log -е в этот момент происходит такое:

PHP:
[26-Mar-2013 15:57:00] NOTICE: configuration file /etc/php5/fpm/php-fpm.conf test is successful
[26-Mar-2013 15:57:00] NOTICE: fpm is running, pid 20053
[26-Mar-2013 15:57:00] NOTICE: ready to handle connections
[26-Mar-2013 15:58:33] NOTICE: [pool storage] child 20054 exited with code 0 after 92.745193 seconds from start
[26-Mar-2013 15:58:33] NOTICE: [pool storage] child 20324 started
[26-Mar-2013 15:58:33] NOTICE: [pool storage] child 20324 exited with code 0 after 0.005245 seconds from start
[26-Mar-2013 15:58:33] NOTICE: [pool storage] child 20325 started
[26-Mar-2013 15:58:33] NOTICE: [pool storage] child 20325 exited with code 0 after 0.005121 seconds from start
[26-Mar-2013 15:58:33] NOTICE: [pool storage] child 20326 started
[26-Mar-2013 15:58:33] NOTICE: [pool storage] child 20326 exited with code 0 after 0.005202 seconds from start
[26-Mar-2013 15:58:33] NOTICE: [pool storage] child 20327 started
[26-Mar-2013 15:58:33] NOTICE: [pool storage] child 20327 exited with code 0 after 0.005543 seconds from start
[26-Mar-2013 15:58:33] NOTICE: [pool storage] child 20328 started
[26-Mar-2013 15:58:33] NOTICE: [pool storage] child 20328 exited with code 0 after 0.004935 seconds from start
[26-Mar-2013 15:58:33] NOTICE: [pool storage] child 20329 started
[26-Mar-2013 15:58:33] NOTICE: [pool storage] child 20329 exited with code 0 after 0.005255 seconds from start
[26-Mar-2013 15:58:33] NOTICE: [pool storage] child 20330 started
[26-Mar-2013 15:58:33] NOTICE: [pool storage] child 20330 exited with code 0 after 0.005239 seconds from start
[26-Mar-2013 15:58:33] NOTICE: [pool storage] child 20331 started
[26-Mar-2013 15:58:33] NOTICE: [pool storage] child 20331 exited with code 0 after 0.005134 seconds from start
[26-Mar-2013 15:58:33] NOTICE: [pool storage] child 20332 started
[26-Mar-2013 15:58:33] NOTICE: [pool storage] child 20332 exited with code 0 after 0.005162 seconds from start
[26-Mar-2013 15:58:33] NOTICE: [pool storage] child 20333 started
[26-Mar-2013 15:58:33] NOTICE: [pool storage] child 20333 exited with code 0 after 0.004950 seconds from start
[26-Mar-2013 15:58:33] NOTICE: [pool storage] child 20334 started
[26-Mar-2013 15:58:33] NOTICE: [pool storage] child 20334 exited with code 0 after 0.005066 seconds from start
[26-Mar-2013 15:58:33] NOTICE: [pool storage] child 20335 started
[26-Mar-2013 15:58:33] NOTICE: [pool storage] child 20335 exited with code 0 after 0.004850 seconds from start
[26-Mar-2013 15:58:33] NOTICE: [pool storage] child 20336 started
[26-Mar-2013 15:58:33] NOTICE: [pool storage] child 20336 exited with code 0 after 0.005501 seconds from start
[26-Mar-2013 15:58:33] NOTICE: [pool storage] child 20337 started
[26-Mar-2013 15:58:33] NOTICE: [pool storage] child 20337 exited with code 0 after 0.005534 seconds from start
[26-Mar-2013 15:58:33] NOTICE: [pool storage] child 20338 started
[26-Mar-2013 15:58:33] NOTICE: [pool storage] child 20338 exited with code 0 after 0.005527 seconds from start
[26-Mar-2013 15:58:33] NOTICE: [pool storage] child 20339 started
[26-Mar-2013 15:58:33] NOTICE: [pool storage] child 20339 exited with code 0 after 0.005508 seconds from start
[26-Mar-2013 15:58:33] NOTICE: [pool storage] child 20340 started
[26-Mar-2013 15:58:33] NOTICE: [pool storage] child 20340 exited with code 0 after 0.005976 seconds from start
[26-Mar-2013 15:58:33] NOTICE: [pool storage] child 20341 started
Строчки "exited with code 0 after" и "started" не прекращаются, тоесть лог растёт и растёт, при этом скрипт уже давно остановился и вывел результат в браузер и даже не трогая его эти строчки бегут и бегут.

Амперсанд в команде "ssh [email protected] ls -la &" для того чтобы он выполнил её на фоне меняет всю ситуацию такого глюка не наблюдается но мне хотелось бы получить результат выполнения команды в некоторых случаях.

А да на FreeBSD наблюдается при этом появление процессов <defunct>
 

fixxxer

К.О.
Партнер клуба
- Доктор, мне больно когда я так делаю!
- Ну не делайте так!
 

xInOrK

Новичок
Не делать это хорошо, но как делать тогда ?
Переписывать конечно желания нету учитывая что это работает всё на mod_php
 

xInOrK

Новичок
https://bugs.php.net/bug.php?id=61558

Нашёл что некоторые получают такое же поведение php-fpm только не могут понять в каком случае, а я в своём смог воспроизвести на двух разных ОС
 

cDLEON

Онанист РНРСlub
ну так и сиди на mod_php. Всё равно тебе с такой архитектурой fpm не поможет.
 

xInOrK

Новичок
Так подскажите как реализовать архитектуру правильно чтобы в будущем не было проблем.
Написать своего демона и ставить его на удалённый сервер и общаться с ним по tcp/ip? Или может уже есть что то готовое?
Использовать какую либо библиотеку для работы с SSH?
 

cDLEON

Онанист РНРСlub
xInOrK
Правильно это избегать без контрольного порождения процессов (у тебя на каждое соединение нужно 1 воркер FPMa и создаётся процесс для работы SSH) и долгих операций для демона, который работает на prefork-e (в данном случае это FPM)
А уже реализация зависит от конкретной задачи. Из твоего объяснения её не видно.
 

xInOrK

Новичок
Ну задача по событию из веба получать данные с удалённых серверов или просто выполнять команду на удалённом сервере, предпочтительно используя уже существующий протокол, SSH полностью удовлетворяет, да и при этом уже имеются туннели которые я использую для быстрой отправки команд не подключаясь каждый раз снова.

Долгих операций у меня нету, да и поведение такое для меня пока не понятно почему он после удачного выполнения команды и уже получения результата, начинает просто флудить в лог сообщениями до бесконечности и грузить CPU.
А как правильнее всего выполнять долгие операции в том же потоке? fastcgi_finish_request?
 

xInOrK

Новичок
Ок задача управление группой серверов на linux из веб морды. Выполнение linux команд, запуск приложений на сервере, сбор каких либо данных, чтение файлов и т.д
 

xInOrK

Новичок
На сколько я помню нету возможности у webmin управлять удалёнными серверами, а на каждый сервер лепить запутаешься.
Нужно что то вроде ansible, puppet, jenkins или как его там только в более простом виде и с возможностью легко управлять из PHP используя там API библиотеку или ещё что-то.
Ну или PHP для этого очень плохой выбор ?
 

С.

Продвинутый новичок
Если тебе с локального места управлять удаленными серверами, то РНР -- наименее подходящая среда из того, что может прийти в голову.
 

xInOrK

Новичок
А что более подходящее ? По Вашему мнению ? Меня же всётаки интерисует не только мнение о том что это плоха и так не нужно, но как нужно и что лучше.
 

С.

Продвинутый новичок
Да что угодно, только не то, когда рабочий процесс происходит где-то в глубенях вебсервера и ты не видишь, что там происходит и никак не можешь вмешаться. Какой-нибудь простенький макрос и то будет эффективней.
 

xInOrK

Новичок
А как можно взаимодействовать с системными утилитами и т.д из PHP чтобы это было достаточно прозрачно и правильно? И что Вы имеете ввиду под макросом ?
 
Сверху