pheanstalk useTube()->put() функция, не ждите ответа

В настоящее время у меня есть следующее:

try {
    $pheanstalk->useTube($tube)->put($data);
} catch (\Exception $e) {
    $logger = $this->container->get('logger');
    $logger->info('Could not reach beanstalk: ' . $e);
}

Это отлично работает, но я хочу иметь его где $pheanstalk->useTube($tube)->put($data) не ждет ответа соединения от сервера, а просто попытается поместить данные в очередь, а затем продолжить свой веселый путь. Данные, которые хранит этот сервис, приятно иметь, но не критичны. Таким образом, в периоды большой нагрузки мне не нужно ждать периода ожидания, чтобы продолжить работу с остальной частью программы. Как устранить ожидание ответа от серверной части pheanstalk?

1 ответ

Чтобы предотвратить блокировку, вы должны раскошелиться.

$pid = pcntl_fork();
if ($pid == -1) {
     die('could not fork');
} else if ($pid) {
     // we are the parent
     // proceed with whatever
} else {
     // we are the child
     $exitStatus = -1;
     try {
         $pheanstalk->useTube($tube)->put($data);
         $exitStatus = 1;
     } catch (\Exception $e) {
         $logger = $this->container->get('logger');
         $logger->info('Could not reach beanstalk: ' . $e);
         $exitStatus = 0;
     }

     exit($exitStatus); 
}

То, что это делает, это разветвляет ваш процесс и позволяет дочернему процессу подождать, пока pheanstalk вернется. Обратите внимание, что есть и другие проблемы:

  • Что если pheanstalk никогда не вернется? Ваш дочерний процесс становится зомби.
  • Формирование процесса включает в себя копирование множества переменных процесса. Это не без накладных расходов, и, следовательно, не обязательно может снизить вашу нагрузку. Это может стоить того, если то, что вы делаете потом, является настоящей работой.

Теоретически вы могли бы передать сообщение в локальную систему очередей в том же окне, задачей которого является размещение сообщений в удаленной системе. Это даст вам довольно быстрый ответ, но может потребовать гораздо большего кодирования с вашей стороны. Если у вас уже есть локальный экземпляр beanstalk, тогда это не поможет. (Я подозреваю, что вы этого не делаете; локальные вызовы beanstalk выполняются быстро. Если у вас есть локальный вызов, проблема, вероятно, на стороне работника / потребителя.)

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