Размазываем PHP

imageНастанет день, и ты поймешь, что одного потока в PHP тебе мало.Сначала ты оптимизируешь код, потом пытаешься изменить сознание на асинхронный реакт, но весь PHP мир не хочет понимать такое стремление. Смотришь на phthreads, но после java concurrency чувствуешь, что тебя где-то «обманули». А когда ты задумаешь покинуть процесс и начнешь захлебываться в форках exec«ах и сигналах, ты поймешь, что дальше погружаться нельзя. И, наконец, всплыв из всего этого, ты поплывешь к острову MOM (message-oriented middleware).

Оооо, а каких тут продавцов кирби только нет: RabbitMQ, ActiveMQ, Kafka, Kestrel и даже Redis pub/sub«ом подбарыживает. И у всех все хорошо: все самое лучшее, быстрое, безотказное. Но есть небольшая беда — шаг в сторону и, привет, теперь ты в числе толпы нытиков на stackoverflow в поисках воркэраундов и странных схем. И это будет продолжаться пока ты не найдешь ZeroMQ.

А что это? ZeroMQ — высокопроизводительная асинхронная месседж-ориентированная библиотека направленная на использование в масштабируемых распределенных или параллельных приложениях. Но в отличии от других месседж-ориентированных мидлваре она безброкерная и работает без сервера, как такового.

ba1a557a663446e4ac6ab2f832a1c521.jpg

И что же тут предлагают тогда? А предлагают эти ребята набор сокетов на стероидах оптимизированных под основные месседж паттерны и использовать мы их можем как хотим. С их помощью можем построить сеть с любой топологией и сложностью.

Еще у них есть своя сектанская дока http://zguide.zeromq.org/page: all. Хорошо вправляет мозги в нужном направлении независимо от того, будешь использовать 0mq или нет, правда, если можешь в многопоточное программирование, можно частично пролистывать.

В сухом остатке: Набор стероидных сокетов Чертовски быстрые Работа через IPC, TCP, multicast, inproc Асинхронные Легкий старт Байндинги для овер 40 языков программирования Звучит все это очень круто! Хватит теорий идем на www.gliffy.com и яростно архитектурим систему. А хотим мы следующее:

image

Auth + task generatorОтвечает за авторизацию на сервере и раздает нон-стоп задачи на парсинг. Parse workerПолучает ключ авторизации и задачу для парсинга после завершение возвращает результат генератору. Parsed data publisherПолучив результат от воркера, паблишит его всем сабскрайберам. Alert system subscriberПолучает данные и рассылает алерты, если нужно. Upload system subscriberПолучает данные и заливает их на сервер. Data upload workerЕнкодит, зипует и аплодит данные на сервер. System monitorСобирает статистику системы в рейалтайме. Архитектура получилась несложная, все компоненты были написаны отдельно от бизнес-логики, оформлены в пакет для композера и запаблишены на гитхаб:

https://github.com/limitium/zmq

Чтоб поковырять, нужно (на примере дебиан): 1. Установить ZeroMQ sudo apt-get update -qq sudo apt-get install -y libzmq3-dev 2. Установить байндинг php-zmq git clone https://github.com/mkoppanen/php-zmq.git sh -c «cd php-zmq && phpize && ./configure && make --silent && sudo make install» echo «extension=zmq.so» >> `php --ini | grep «Loaded Configuration» | sed -e «s|.*:\s*||»` 3. Установить либу через composer composer require limitium/zmq Дальше берем, например, psr-3 логгер и смотрим, как он работает: Логгер

$logger = new ZLogger ('my_service_1', 'tcp://127.0.0.1:5555'); $logger→info («core is stable»); $logger→emergency («we’re all going to die!»); Сборщик логов (new Concentrator ('tcp://127.0.0.1:5555')) →setReceiver (function ($logMsg) { $serviceName = $logMsg[0]; $time = $logMsg[1]; $logLevel = $logMsg[2]; $logMsg = $logMsg[3]; }) →listen (); Все просто, при этом логгер благодаря плюшкам ZeroMQ может работать как в рамках одного процесса, так и собирать информацию со 100500 серваков.Пример генератора задач и воркераGenerator

(new Ventilator ('tcp://127.0.0.1:5555')) →setGenerator (function () { sleep (1); return rand (); }) →setResponder (function ($msg) { echo $msg; }) →listen (); Worker (new Worker ('tcp://127.0.0.1:5555')) →setExecutor (function ($msg) { return $msg + $msg; }) →work (); И под конец банальный pub/subPublisher

$pub = new Publisher ('tcp://127.0.0.1:5555'); $pub→send ('azaza'); Subscriber (new Subscriber ('tcp://127.0.0.1:5555')) →setListener (function ($msg){ echo $msg; }) →listen (); Единственный минус ZeroMQ, который стоит отметить — чем больше интерпрзайности хочется от системы, тем больше придется писать кода. Но кого это волнует, когда запускается все в 2 строчки кода?

© Habrahabr.ru