Beanstalk/Pheanstalk не работает в фоновом режиме

У меня проблемы с настройкой Pheanstalk на сервере Ubuntu. Я относительно новичок в программировании, я сделал все шаги: - установил beanstalk с помощью sudo apt-get install beanstalk - получил pheanstalk с https://github.com/pda/pheanstalk/

И вот мой код:

require_once('pheanstalk_init.php');

$pheanstalk = new Pheanstalk_Pheanstalk('127.0.0.1');

$pheanstalk
->useTube('testtube')
->put(exec("cat ../uploads/databases/app_data/Filename.sql | sqlite3 ../uploads/databases/Filename.sqlite"));

$job = $pheanstalk
->watch('testtube')
->ignore('default')
->reserve();

echo $job->getData();

$pheanstalk->delete($job);

Проблема в том, что для запуска этого кода требуется 4-5 минут, и по какой-то причине команда exec не запускается в фоновом режиме.

Есть идеи, что я делаю не так? Спасибо заранее!

1 ответ

Это старый вопрос, и, возможно, вы уже решили его... в любом случае, вот короткий ответ и более подробное объяснение:


TL; DR: краткий ответ: проблема заключалась в том, что вы выполняли свой интенсивный (cpu/disk io) код внутри метода put(), и вам нужно было запустить его на рабочем месте после $job->getData() .

Объяснение: Beanstalk действует как очередь сообщений и позволяет вам отделять производителей информации от потребителей. Идея состоит в том, что вы просто публикуете описание работы, которую вы хотите выполнить, в очередь, а создание и публикация этого описания в очереди происходит очень быстро. Фактический ресурс (процессор / оперативная память / дисковый ввод-вывод / сеть), потребляющий обработку, происходит у потребителя (-ов), когда есть доступные, в то время как производитель свободен делать другие вещи. Если нет доступных рабочих, то рабочие места просто накапливаются в очереди.

Так, в вашем случае, например, разделите вашего производителя и потребителей на chief.php и worker.php:

chief.php

<?php
require_once('pheanstalk_init.php');
$pheanstalk = new Pheanstalk_Pheanstalk('127.0.0.1');
$pheanstalk
->useTube('testtube')
->put("cat ../uploads/databases/app_data/Filename.sql | sqlite3 ../uploads/databases/Filename.sqlite");
?>

worker.php:

<?php
require_once('pheanstalk_init.php');
$pheanstalk = new Pheanstalk_Pheanstalk('127.0.0.1');

while(true){
  $job = $pheanstalk->watch('testtube')->ignore('default')->reserve();
  $cmd = $job->getData();
  exec($cmd);
  $pheanstalk->delete($job);
}

?>

Поэтому, когда вы запускаете работника, он подключается к серверу beanstalkd и ожидает, пока задание будет опубликовано в очереди / пробирке 'testtube'. Затем он выполнит описанную работу, удалит ее из очереди и выполнит цикл, готовый обработать другую работу, когда она прибудет. Вы также можете запустить несколько рабочих параллельно, если хотите.

NB. Сервер beanstalkd НЕ запускает ваших работников; он только распределяет рабочие места от производителей к потребителям. Поэтому вам нужно самостоятельно управлять запущенными рабочими процессами. Лично я предпочитаю запускать рабочие как службы runit, чтобы при возникновении каких-либо проблем с ними они были перезапущены runit, и их выходные данные были зарегистрированы. Конечно, вы можете использовать любой инструмент мониторинга процессов, который вам нравится: runit, systemd, monit и т. Д.

Также неплохо запустить сам beanstalkd под своим любимым монитором процессов, на случай, если он выйдет из строя, что маловероятно, но может случиться (это случилось со мной год назад).

Другие вопросы по тегам