Используем Gearman(менеджер очередей) в Kohana 3 или любом другом PHP сайте

test
Gearman stack

Что такое Gearman?

Введение весьма неплохо описано тут
Если вкратце то Gearman это менеджер очередей состоящий из трех компонентов:
  • сервер задач — является центральной частью Gearman, именно сюда будут приходить задачи и результаты от клиентов и исполнителей, и именно отсюда будут высылаться задания и результаты, исполнителям и клиентам соответственно.
  • исполнитель — является основной частью, где необходима реализация какой-либо функциональности. Исполнитель принимает и пытается выполнить задание от сервера.
  • клиент — также имплементируется отдельно, создаёт и отсылает задачу на сервер и, в некоторых случаях (о них — позже), получает результат.
Картинка в топе поста показывает алгоритм работы с Gearman-ом.

Кратко от авторов Gearman

  • Open Source и BSD лицензия.
  • Мультиязычность - Большой список поддерживаемых языков.
  • Гибкость - Вы не ограничены какими-либо паттернами проектирования.
  • Скорость - Gearman работает на простом протоколе и с оптимизированным интерфейсом, потоками. Сервер написан на C/C++ для минимизации оверхедов.
  • Встраеваемый - быстры и легкий, удобен для любых масштабов приложений. Так же легко внедряется в существующие приложения с минимальным оверхедом.
  • Нет единой точки отказа - Gearman помогает не только в масштабировании систем, но и в повышении отказоустойчивости.
  • Нет ограничений на размер сообщения - Gearman поддерживает размер каждого сообщения до 4Гб в размере. Нужно больше? Не проблема, Gearman может делить сообщения на части.
  • Обеспокоены масштабированием? - Не стоит. Craig’s List, Tumblr, Yelp, Etsy,… откройте для себя то о чем они уже знают годами.
Пример, прекрасно иллюстрирующий для чего он нужен так же описан был на хабре весьма точно:
Пользователь закачал фотографию на сайт, и хочет показать её всем своим друзьям. Необходимо быстро подготовить различные размеры данной фотографии, для использования по всему сайту. Да, до определённого момента все работы по генерации графики можно проводить в основном коде системы, а потом придёт хабраэффект, и вся система рухнет под наплывом желающих. Теперь рассмотрим как эту задачу можно решить с использованием Gearman — при получении фотографии, мы создаём задачу для gearman сервера, в которую входит необходимая информация о фотографии (в принципе возможно включить в задачу даже саму фотографию, но, мне кажется, это будет накладно, лучше использовать адрес) и отправляем её на выполнение. Сервер задач выбирает (round robin) свободного исполнителя (как Вы наверное уже догадались, исполнителей может быть несколько) и отсылает задачу на выполнение. Исполнитель получает всю необходимую информацию, обрабатывает её как нам бы этого и хотелось — и отправляет ответ об успешно выполненной задаче и, если задача была синхронная, результат работы.
Врапперов к языкам для работы с Gearman достаточно много, так что все основные языки будут иметь возможность взаимодействовать с ним, среди них perl, php, python, java, C и другие. Сервер имеет возможность сохранять очередь задач в какое-либо хранилище, чтобы при рестарте была возможность восстановить весь процесс без потери данных. Хранилищем может выступать MySQL/drizzle, memcached, PostgreSQL или sqllite. Основной обьект над которым происходит вся работа в системе - Задача(Task), имеющая параметры. Идентифицируются задачи по ключу Название/Параметры. При полном совпадении ключей двух задач, будет выполнена только одна, остальные идентичные ей будут отброшены.

Установка

apt-get install gearman gearman-server gearman-job-server gearman-tools  php5-gearman
Чтобы PHP имел возможность работы с Gearman, в php.ini должна быть строка:
extension=gearman.so
Подключен ли модуль можно увидеть выведя команду phpinfo() или из консоли:
php -m | grep gearman
Проверить выполнение и постановку в очередь задач можно командой из консоли:
#gearadmin --status
sendmail        1       0       0
Первая колонка - тип задачи, мы его сами задаем при создании задачи.
Вторая колонка - количество задач в очереди
Третья - количество выполняемых задач
Четвертая - количество зарегистрированных воркеров

HTML Формы:

У нас проверочные формы, первая форма при отправке будет создавать Сервер и добавлять задачу на выполнение, вторая будет запускать Клиента который будет получать задачу от Gearman и выполнять ее.
<!-- Форма запуска сервера с постановкой задачи в очередь -->
<form method="POST">
    <input type="hidden" name="action" value="taskadd">
    <input type="text" name="email" placeholder="email">
    <input type="text" name="subject" placeholder="subject">
    <textarea name="body" placeholder="body message"></textarea>
    <input type="submit" value="send">
</form>
<br>

<!-- Форма запуска обработчика -->
<form method="POST">
    <input type="submit" value="set worker">
</form>

Создаем сервер Задач

Кусок кода из Kohana action. Суть в том, когда поступает POST запрос с формы отправки мы ставим задачу
public function action_gearman(){
        if ($this->request->method() == Request::POST){
                    $mail = array(
                        'to' => $this->request->post('email'),
                        'subject' => $this->request->post('subject'),
                        'body' => $this->request->post('body'),
                    );

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

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

        }
    }

Создаем Клиента(Worker-а)

По отправке формы мы запускаем клиента(Worker-а) который и выполняет наши задачи.
public function action_gearmanworker(){
        if ($this->request->method() == Request::POST){

                    // Создаем "воркера" и подключаемся к серверу задач
                    $worker= new GearmanWorker();
                    $worker->addServer();

                    // Регистрируем обработчик события "sendmail"
                    // "send_mail" - это имя функции, объявленной ниже
                    $worker->addFunction("sendmail", array($this,"send_mail"));
                    $ret = $worker->work();
                    if ($worker->returnCode() != GEARMAN_SUCCESS) echo "GEARMAN RETURN CODE: False";
                    // Функция реальной отправки почты
                    // В аргумент ей передается объект задачи
        }
    }

    function send_mail($job)
    {
        $workload= $job->workload();
        $data = unserialize($workload);
        mail($data['to'], $data['subject'], $data['body']);
        echo "<br>send mail to: ". $data['to']." with subject:<br>".$data['subject'];
    }
Пример с которого я лепил этот пример. После запуска первой формы можем посмотреть статистику сервера:
gearadmin --status               
sendmail        1       0       0
Видно что у нас появилась задача на выполнение. После выполнения формы воркера:
gearadmin --status
sendmail        0       0       1
Задача была выполнена воркером. Таким образом первой формой мы можем ставить задачи на выполнение, а второй их выполнять. Вот так просто работать с Gearman по сравнению с тем же Celery.
Категория: 
Share/Save

Делитесь с друзьями в социальных сетях! Оставляйте комментарии!

Share/Save

Это Вам так же может быть интересно!