Gearman и PHP - асинхронные задачи

Gearman - это сервер организации и распределения задач, или проще говоря сервер очереди сообщений. Gearman включает множество функциональных особенностей - балансировка, асинхронное/синхронное выполнение, приоритеты и т.п. В этой статье, на примере с PHP, реализуем простой механизм отложенной отправки почты.
Суть
Зачем вообще нужны такие решения, как Gearman, читайте в статье “Очередь сообщений - что это и зачем?“. Наша задача реализовать отложенную отправку почты, т.к. это довольно ресурсоемкая операция и может сильно влиять на скорость ответа приложения клиенту.
Установка
Установка происходит в два этапа. Сначала ставим сам сервер (исходники качаем тут):
tar -xvzf gearmand-version.tar.gz cd gearmand ./configure make; make install
Теперь устанавливаем php расширение:
pecl download gearman-0.7.0 tar -xvf gearman-0.7.0.tgz cd gearman-0.7.0 phpize ./configure make make install
Не забываем добавить “extension=gearman.so” в php.ini. Если все хорошо, то phpinfo() покажет нам:

Клиент
В нашем клиенте (основное приложение) отправка email сообщений будет осуществляться путем регистрации новых задач на сервере Gearman:
...
$mail = array(
'to' => 'test@gmail.com',
'subject' => 'Привет',
'body' => 'Это тестовое сообщение',
);
...
# Подключаемся к серверу
$client= new GearmanClient();
$client->addServer();
# Регистрируем задачу для фонового выполнения
# "sendmail" - это тип задачи
# $mail - это данные письма
$result = $client->doBackground("sendmail", serialize($mail));
Обратите внимание, что PHP клиент принимает только строку в качестве данных о задаче, поэтому необходимо любой другой тип объектов сериализовать. Мы использовали асинхронное выполнение задач (метод doBackground), поэтому реальное время отправки почты не повлияет на скорость выполнения нашего приложения.
Обработчик задачи
Обработчик - это отдельное приложение (скрипт), который “слушает” сервер на предмет появления новых задач. Как только задача приходит - он выполняет связанную с ней логику (в нашем случае это будет отправка письма с помощью почтового сервера).
# Создаем "воркера" и подключаемся к серверу задач
$worker= new GearmanWorker();
$worker->addServer();
# Регистрируем обработчик события "sendmail"
# "send_mail" - это имя функции, объявленной ниже
$worker->addFunction("sendmail", "send_mail");
while (1)
{
echo "Ждем работы...\n";
$ret= $worker->work();
if ($worker->returnCode() != GEARMAN_SUCCESS) break;
}
# Функция реальной отправки почты
# В аргумент ей передается объект задачи
function send_mail($job)
{
$workload= $job->workload();
$data = unserialize($workload);
mail($data['to'], $data['subject'], $data['body']);
}


Как я понимаю для таких же целей можно просто использовать key-value хранилище?
Написать просто бекгроунд воркер, что проверяет ключи и удаляет при выполнении
@<fb:name linked=”false” useyou=”false” uid=”642249544″>Leo Pard</fb:name>
Да, можно. А еще можно обычные текстовые файлы использовать и скрипт на баше. Но лучше использовать специально разработанные для этого инструменты - намного быстрее, легче и удобнее
$worker->work(); висит пока не появится задача? Если нет, то надо добавлять sleep хотя бы в пару миллисекунд в цикл. А вообще интересен пример с приоритетами, а также понять механизм каким образом задача может выполниться синхронно
@<fb:name linked=”false” useyou=”false” uid=”501712046″>Stanislav V. Starcha</fb:name>
1. Не уверен, нужно проверить, но по логике должен ждать ответа, пока он не придет, иначе слишком много ресурсов этот цикл будет кушать
2. Есть режим синхронного выполнения. В этом случае в приложении, когда происходит вызов, клиент ожидает результат от сервера задач (а сервер задач от воркера), и возвращает управление программе только после получения ответа. Вот пример: http://ua2.php.net/manual/en/gearman.examples-reverse.php
Т.е. синхронный режим это по сути тоже, что и обычный PHP скрипт. Выполнение ведь зависнет до момента получения ответа, а значит и пользователь будет ждать результата.
В чем тогда плюс синхронного режима и когда его используют?
Да, совершенно верно. Синхронный режим нужен в том случае, если у Вас разные части логики реализованы на разных платформах. Например, интерфейсная часть на PHP, а ядро на C++.
Подскажите кто знает, есть ли в природе менеджер очередей которому можно задавать время, только по истечении которого сообщение может выйти из очереди. В основном используется для проверки таймаутов. Кинул сообщение проверить через 3 минуты пришел ответ от клиента али нет. (применений на самом деле много) PS. я в кусе о SQL. хочется такую фишку именно в виде очереди
Немного не понятно где gearman хранит все задачи в очереди? Если в memcacheq понятно, то в данном случае не особо )
если не в оперативной памяти, то тогда memcacheq было бы рациональнее использовать
Не подскажите, установил у себя gearman, сервер + pecl extension, в php info все есть, подключено.
Сервер запущен на localhost’е, порт стандартный
Ошибок не вылезает, но при запуске скрипта в worker’ами все просто намертво виснет(т.е. никакие echo не проходят).
Не знаете, в чем может быть проблема?