Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Очередь задач и многопоточность с помощью Gearman и ZF

fwdays
November 24, 2012

Очередь задач и многопоточность с помощью Gearman и ZF

— Возможности Gearman, сервер, клиент, очередь задач, схема работы.
— Запуск и работа Zend Framework приложений в качестве обработчиков (workers)
— Проблемы при работе Zend Framework приложений в качестве обработчиков, их решения (память, перехват ошибок, общий доступ к данным)
— Работа с очередью: приоритет задач, уникальность задач в очереди, сохранение, очистка.
— Мониторинг системы, получение информации о количестве задач в очереди, количестве обработчиков на задачу на каждом сервере.
— Анализ информации об очереди и обработчиках, управление обработчиками, поддержание работы системы, балансировка.

fwdays

November 24, 2012
Tweet

More Decks by fwdays

Other Decks in Programming

Transcript

  1. Развитие проекта => увеличение нагрузки Решение проблемы: 1. Обработка в

    несколько потоков 2. Использовать очередь задач
  2. • Когда один поток уже не справляется… • Есть возможность

    прироста производительности • Нужно запустить некую обработку отдельно от основного процесса Зачем нам многопоточность?
  3. • Запуск еще одного скрипта (wget, curl) • Использование pcntl,

    fork() • Использование libevent, например PhpDaemon PHP, эмулируем)
  4. • Балансировать нагрузку • Избавиться от единой точки отказа •

    Выполнять бизнес-логику приложения асинхронно Зачем нам очередь?
  5. Что же выбрать? • Налаженное взаимодействие очереди и потоков •

    Достаточная документация • Контроль за процессом
  6. Возможности • Распределение нагрузки • Очередь задач • Мониторинг системы

    • Синхронная/асинхронная обработка • Приоритет задач
  7. Gearman • Open Source - Свободно распространяемый, с открытым кодом

    и вменяемым сообществом. • Мультиязычный - Интерфейсы для многих языков, может служить мостом • Гибкий - подходит любая архитектура типа Map/Reduce.
  8. Gearman • Быстрый - простой протокол, оптимизированный сервер • Легко

    внедряемый - легковесный, подходит как для существующих, так и новых приложений • Нет единой точки отказа – поможет не только масштабировать приложения, но и повысить отказоустойчивость
  9. Что нам остается? • Предоставить менеджеру работников, которые подпишутся на

    выполнение задания • Как клиент, общаться с ним и ставить ему задачи
  10. Организуем рассылку (например) 1. Создать worker’ы для отправки email, sms…

    2. Запустить их и подключить к серверу 3. Подключиться клиентом, отправить задания в очередь
  11. Требования к обработчикам • Использование бизнес-логики приложения • Наследование общих

    частей кода • Избегать процедурного стиля • Удобный запуск
  12. Интегрируем с ZF 1. Создаем точку входа – front controller

    2. Подключаем в bootstrap необходимые ресурсы 3. Используем Zend Gearman (mwGearman для ZF2) 4. В новый обработчик добавляем только логику Спасибо Mike Willbanks: http://blog.digitalstruct.com/2010/10/17/integrating-gearman-into-zend-framework/ https://github.com/mwillbanks/Zend_Gearman https://github.com/mwillbanks/mwGearman
  13. Новый обработчик class Sender extends Zend_Gearman_Worker { protected function _work()

    { //some logic } } Запуск: exec('php worker.php Sender > /dev/null &');
  14. Отправляем задачи в очередь • В качестве задания - только

    string • Задачи с одинаковыми id не попадают в очередь • Задачи убираются из очереди только после успешной обработки • Во время выполнения задача остается в очереди $gearmanClient->doBackground('sendEmail', serialize($params), $id)
  15. Мониторинг вручную Выполняем подключение через telnet на порт 4730 Доступные

    команды: • status – информация об очереди • workers – запущенные обработчики
  16. Мониторинг в приложении • Реализован через сокеты в NetGearman •

    Если использовать pecl - есть несколько решений на github, тоже работают через сокеты https://github.com/yugene/Gearman-Monitor https://github.com/brianlmoon/GearmanManager
  17. Что может пойти не так? • Ошибки – важно отлавливать

    и не допускать падения обработчиков, возвращать корректный результат • Общий доступ к данным – полезно использовать uniqueId для каждой задачи, транзакции, select->forUpdate() • Память – следить за утечками памяти, вызывать garbage_collector, перезапускать обработчики, которые используют много памяти
  18. Поддержка работоспособности $status = $monitor->getTasksStatus(); foreach ($status as $taskname =>

    $states) { $workers = (int) $states['workers']; if ($workers < $neededAmount) { for($i = 1; $i <= $neededAmount - $workers; $i++) { exec('php worker.php '. $taskname .' > /dev/null &'); } } } 1. Получаем информацию о запущенных обработчиках 2. Запускаем недостающие
  19. Если есть срочная задача • Подходит логика обработчика • Запущено

    много задач, обработчики заняты Используем приоритеты: $gearmanClient->doHighBackground(); $gearmanClient->doLowBackground();
  20. Нужен результат • Если подходит логика обработчика • Но нам

    нужно подождать ответ Используем синхронную обработку: $gearmanClient->setCompleteCallback(‘callback’); $gearmanClient->do();
  21. Советы • Делайте проверку соединения с бд • Используйте транзакции

    и select->forUpdate() • Записывайте processId • Оставляйте возможность остановки процесса обработчика по условию • Следите за размером лога gearmand