Gearman: распределяем задачи

Sakila_sandbox_479x396_gearman

Один из способов оптимизации приложений — это распределения задач.

Как правило, во многих проектах делают ставку на встроенный планировщик типа — CRON, который методично выполняет определенный набор скриптов. В годами данный планировщик обрастает такими «костылями», что переписать все с нуля оказывается гораздо проще, чем разобраться как же «это все» работает. Дополнительные проблемы создают распределенные системы.

Решение простое — уход в сторону систем распределения задач, одной из которых является Gearman.

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

Gearman в своей работе, работает с тремя компонентами:

  • сервер задач — сюда будут приходить задачи и результаты от клиентов и исполнителей, отсюда же будут высылаться задания и результаты, исполнителям и клиентам соответственно.
  • исполнитель — основная часть, где необходима реализация какой-либо функциональности. Исполнитель принимает и пытается выполнить задание от сервера.
  • клиент —  создаёт и отсылает задачу на сервер и получает результат.

stack

В своей работе я использую связку Gearman+php, задания хранятся в mysql, для того чтобы исключить возможные проблемы при пропадании электричества, а также для отслеживания очереди задач.

Установка на клиенте:

Для того, чтобы избежать ругани со стороны системы 
"configure: error: Please install libgearman" и подобные, ставим необходимые компоненты:

#yum install php-pear re2c libgearman libgearman-devel php-devel gcc

Обновляем pecl и ставим gearman:

#pecl channel-update pecl.php.net
#pecl install gearman

В случае успеха получаем сообщение вида:

Build process completed successfully
Installing '/usr/lib64/php/modules/gearman.so'
install ok: channel://pecl.php.net/gearman-1.1.2
configuration option "php_ini" is not set to php.ini location
You should add "extension=gearman.so" to php.ini

Выполняем, что от нас требуют

echo "extension=gearman.so" > /etc/php.d/gearman.ini

И делаем проверку:

# php -i| grep gear
/etc/php.d/gearman.ini,
gearman
gearman support => enabled
libgearman version => 1.1.8

Установка серверной части:

Делаем примерно тоже самое, что описано выше, кроме того нам понадобиться непосредственно демон:

yum install gearman*

После установки, систему можно сразу опробовать, клиент ставит задачу, сервер её выполняет, для примера ниже php код:

Код клиента:


$mail = array(
  'to' => 'test@gmail.com',
  'subject' => 'Привет',
  'body' => 'Это тестовое сообщение',
);


# Подключаемся к серверу
$client= new GearmanClient();
$client->addServer();

# Регистрируем задачу для фонового выполнения
# "sendmail" - это тип задачи
# $mail - это данные письма
$result = $client->doBackground("sendmail", serialize($mail));

?>

Код исполнителя:

<?php 

// Сохранение в $lock_file обязательно, иначе handle помрёт и файл автоматом закроется
if(!flock($lock_file = fopen("robot.lock", 'w'), LOCK_EX | LOCK_NB))
  die("Already runninng\n");

# Создаем "воркера" и подключаемся к серверу задач 

$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']);
echo $data['to']." ".$data['subject']." ".$data['body'];

}

Как правило, данных настроек достаточно, однако мне необходимо хранить события в базе, для этого необходимо создать базу gearman и в «/etc/sysconfig/gearmand» прописать следующий код, необходимая таблица создастся самостоятельно, при первом старте демона:

[root@sigma sysconfig]# cat /etc/sysconfig/gearmand
### Settings for gearmand
# OPTIONS=""
OPTIONS="--queue-type=MySQL \
  --mysql-host=127.0.0.1 \
  --mysql-user=gearman \
  --mysql-password=gearman_password \
  --mysql-db=gearman \
  --mysql-table=gearman_queue \
  --mysql-port=3306"

Более подробные сведения по настройке данного демона, в частности например для посылки заданий посредством http, можно получить из документации: http://gearman.org/manual/job_server/

Вы можете оставить комментарий ниже.