Pull to refresh

Comments 51

Это у вас теперь ESB для php? Ничего себе, ынтырпрайз-технологии добрались до стартапов :)

А вот я чего не понял:
— каковы его преимущества у него по сравнению с Zend_Queue?
— есть ли смысл использовать out-of-process MQ? планируете ли вы использовать передачу сообщений между нодами?
Не совсем ESB но похоже, в принципе.

По поводу первого — возможность рассылки массовой сообщений, другая система адресаций очередей, использование хранилища Redis в качестве бекенда. Zend_Queue это также обертка над несколькими очередями, я пытаюсь сделать выделенный сервер MQ, а не просто интерфейс.

По поводу второго — да, только такое, а зачем внутри скрипта очереди? Максимум — там хватит Zend_Queue_Array.

Первоначально наверное попробую просто один выделенный сервер с очередью, ноды — это репликация или разнесение бекенда на два Redis-сервера (но тогда есть сложности с коммандами, которые использую паттерны), позже попробуем и что-то типа кластеризации, когда поднимаются два демона и работают в паре.
Так если вам не нужны все прелести out-of-process ESB, зачем такой оверинжиниринг — внепроцессные мессаги, отдельный сервер для них? У вас будет несколько отдельных воркеров?
не воркеров — получателей сообщений. Пример — онлайн игра или что-то подобное, тот же чат.
А, понял. Не обратил внимание, что это abrdev.com/ — вы, извините :)
Вопрос снимается, но появляется другое — вы упомянули «множество получателей» в описании. Кто имеется в виду под получателями?
любой скрипт, который получает и как-то обрабатывает сообщения из очереди.
Спасибо за начинание! И спасибо за предыдущие статьи — я их читал с удовольствием. Интересуюсь темой очередей в PHP.
Вы совершенно правы — с очередями в пхп плохо. Тоже исследовал этот вопрос и положительного нашел мало :)
И почитать об этом будет несомненно интересно.
Но… Вероятно я не достаточно внимательно прочитал статью, но в начале вы хотели сделать что-то простое, а в итоге изобрели энтерпрайз сервер сообщений :) Чисто с практической точки зрения, я бы на вашем месте поставил бы RabitMQ и допилил бы code.google.com/p/php-amqplib/. Потому что все описанное выше там уже есть. А так вам придется чертовски много реализовывать руками.
спасибо!

Так нет же, я и хотел сделать простой и быстрый сервер сообщений с минимальным внешним кодом — получилось, что необходим только Redis. RabbitMQ требует еще и ерланга, потом доставлять какие-то бинндинги чтобы работало, к тому же он после установки просто не запустился. Мне никак не надо всего, что есть в AMQP и раббите — просто рассылать сообщения в JSON формате по очередях и забирать оттуда. Максимально просто и быстро. Это все поместилось в несколько методов, не более. Ну если добавить обвязку серверную, то будет больше, но всеравно — это остается та же платформа (РНР). RabbitMQ (но мне больше нравиться Apache Qpid) все же гораздо более высокоуровневое и ентерпрайзное решение. Да и с самим протоколом AMQP много сложностей (много версий, плохая совместимость, мало серверов, костыли при работе с РНР)
у меня Раббит работает и ОЫЩТ не рассыпается, что-то ты не до инсталлировал.
допиливать не надо, советую code.google.com/p/php-rabbit/
по поиску на Хабре, или через мой профиль можно найти всю информацию
вообще у меня была и остается идея написать сервер очередей, заточенный под РНР.
эээ, поясните пожалуйста Signal Slot это же тоже самое что и события, если так то в этом случае не совсем понятно почему это в противовес MVC? или возможно я чтото не так понимаю?
Немного не так. Не столько о архитектуре, сколько о подходе к реализации веб-приложения. Очень скоро напишу большую статью об этом, там подробнее расскажу. Вкратце — URL порождает поток сигналов, которые обрабатываются слотами, в свою очередь, слоты могут генерировать другие сигналы (это по сути, метод вызова функций внутренний такой).
понял, в моем велисопеде есть события и их обработчики, которые подписаны на эти самые события, причем обработчики событий это экшины контроллеров, модели это работа с данными, вью — шаблоны. Причем не только урл а вообще хттп запрос имеет свой eventId на который подписаны обработчики которые отработав и собрав данные передают это все во вью.
собственно поэтому я и спросил, про мвц и сигнал слот, в моей голове эти вещи могут жить вместе
вопрос — зачем? Ну то есть — вся эта надстройка достаточно непонятная — контроллеры, модели виды и прочие, когда реально можно строить достаточно сложную логику гораздо проще (не всегда, конечно). Просто по опыту чтения рассылки того же ZF, куча вопросов и проблем с совсем странными вещами, когда то же самое делается легче.
ну как зачем — разделяй и властвуй, мухи отдельно котлеты отдельно
да это понятно. Но разделять и властвовать можно совершенно по разному :)
ну я касательно MVC говорил, мне кажется что это немного разные срезы архитектуры, взаимодействие посредством событий отвязывает компоненты друг от друга ограничив их взаимодействие протоколом событий а MVC отделяет логику от получения данных и от представления
А в REDIS есть возможность получить все ключи (имена очередей) или же вы их где-то храните?
да, есть (получить все ключи по паттерну). Хранение у себя (по сути, кеширование) неализовано в Rediska_Queue, у меня же при попытке получить все очереди происходит запрос к редису на выборку ключей, это означает, что результат будет всегда актуальный (хоть учтите, что его сложность O(n), к тому же играет роль длина ключей).
хотел посмотреть, как делается count. наугад ткнул svn/trunk/lib/Rediska/Zend/Queue/Adapter/Redis.php. по-моему, тут что-то не так.

public function count(Zend_Queue $queue=null)
{
return count($this->_queues);
}

я для очереди сообщений использовал SystemV Message Queues ( ru.php.net/manual/en/function.msg-get-queue.php )
правда, не совсем persistent. возможностей гораздо меньше. и ограничено одной машиной. но по скорости — летает.
на виртуальной coLinux-машине у меня получалось где-то 20..30 тыс сообщений (т.е. это 10-15 тыс сообщений с ожиданием ответа), причём время уходило в переключение задач. т.е. если у вас вдруг нормальная двухъядерная машина, а не виртуалка, то скорость должна быть в разы выше.
угу, также смотрел на это дело. Но смутило, что это странная фича системы, о которой мало что известно, только скудная дока. Ну и это да, никак не распределённо и персистентно, в границах одного скрипта вполне ОК, но требует дополнительных модулей, тогда уж лучше использовать Zend_Queue_Array
ну, не то, чтобы совсем не персистентно. живёт до перезагрузки системы. т.е. для организации background-обработки, или демонов какой-нибудь статистики это прекрасно подходит.
да, согласен! а как с размером сообщений, их количеством и количеством очередей? То есть, несколько тысяч очередей с сотнями сообщений в каждой?
Да, я об этом говорил — редиска кеширует у себя очереди. у меня count делается путем запроса к серверу Redis-а — вообще все операции так делаются. Потому пришлось делать свой вариант очередей на базе редиски :)
я не об этом, просто тут передаётся параметр, который не используется. т.е. если эта функция общее число очередей возвращает, то она без параметра должна быть. а если число сообщений в очереди, то тогда непонятно, почему внутри этот параметр не используется.

ну, по-моему, так было бы логично.
немного не понял. Я тут немного дописал библиотеку:
— count($name) — возвращает количество сообщений в указанной очереди.
— getQueue($pattern) — возвращает массив с очередями (если без параметра — все очереди), а если с параметром — то это маска, чтобы вернуть только часть очередей.

Да, если вы об адаптере от редиски — да, там это не реализовано, возвращается количество очередей, а не сообщений. Там еще много вопросов, но это скорее к реализации интерфейса от Zend_Queue
Адаптер в Редиске реализует интерфейс Zend_Queue и не более того. Поэтому все архитектурные кляузы принадлежат к кривоватому по моему мнению Zend_Queue.
UFO just landed and posted this here
Вы заблуждаетесь. Редиска не кеширует в себе очереди.
Все тут так. Ознакомьтесь с интерфейсом Countable.
глубокоуважаемый Shumkov! несколько хамоватый тон вашего комментария вынуждает меня сказать вам, что у вас, вероятно, проблемы с восприятием, поскольку в треде выше я подробно раскрывал тему, что же именно там не так.

с интерфейсом Countable я знаком, но, тем не менее, пошёл и ознакомился ещё раз.
abstract public int count ( void )
обращаю ваше внимание: void.
как я уже писал, мне показалось странным, что в функцию count передаётся параметр, который никак не используется.
предыдущее предложение тезисно: параметр, передаётся, не используется.
ничего личного, so long and thanks for all the fish.
Вы правы, у меня точно проблемы с восприятием. Исправил.
Ошибка в том что он зачем-то считал количество очередей, а не сообщений, как это требует интерфейс адаптера.
Рекомендую еще посмотреть рубишный Resque, который люди в GitHub сделали. Правда, это не только сервер очередей вокруг Redis, но еще и инструмент исполнения background job'ов сразу.

Вопрос, сам сервер очередей планируете тоже делать на PHP? Если PHP будет как демон запущен, то как будете решать проблему утечек памяти?
а какая в php проблема с утечкой памяти?
Просто PHP течет :) В обычном режиме PHP все используют как скрипты с коротким сроком жизни, потому с проблемой утечек памяти не сталкиваются, если же делать демона на PHP — утечки всплывают.

Если интересно, можете погуглить на эту тему, вот сходу несколько ссылок:

www.reddit.com/r/programming/comments/acrfl/writing_a_daemon_in_php/
kevin.vanzonneveld.net/techblog/article/create_daemons_in_php/ (тут в комментариях еще пишут об утечках)
дело в том, что я использую php-демоны, в т.ч. в production. и никаких утечек не заметил. аптайм больше месяца.

до 5.3 память текла из-за циклических ссылок, для борьбы с этим приходилось их самостоятельно подчищать.
ещё может казаться, что память течёт, если использовать паттерн Registry (или аналог), или если не закрывать mysql result'ы, но это не память течёт, а программист небрежен.
Да, согласен. А подробнее про утечки из-за регистра можно? а то я его активно использую…
ну, в регистри обычно кладётся всё, что забирается из базы — т.е. забрали из базы строку, сделали объект, положили в регистри. если регистри никак не ограничивать в размере и не очищать, то там быстро накапливается очень много объектов.
гм, честно — никогда о таком не слышал! Registry используется как замена (умная, если можно так сказать), глобальным переменным.
да, дальше также буду доделывать и job-сервер вокруг очередей (вернее — это специализированная очередь просто)
К слову, в библиотеке Rediska есть специальный адаптер для того, чтобы работать с очередями поверх Redis, но промучившись неделю и так и не заставив работать даже тестовый пример, я окончательно решил — все, пишу свою систему!

Очень странно мы успешно используем! Что у вас не работает?
Еще одним замечанием об архитектуре и отличиях от Rediska_Queue будет то, что насколько я понял из исходников, в угоду быстродействию, они положили ценное свойство распределённости. Например, команда getQueues, которая возвращает массив всех хранимых очередей (не сообщений, а только имена очередей), работает с локальной копией списка очередей. Поэтому, если другой клиент создаст новую очередь во время работы первого, он об этом не узнает.

Вы заблуждаетесь. Советую заглянуть глубже, перед тем как делать какие-то выводы.
Безусловно, Rediska — очень хорошая библиотека, пока мне нравиться больше всех остальных (и даже больше моего первого вариант РНР библиотеки для доступа к редису).

Но вот пример кода, что я делаю не так? Вполне возможно, что кривые руки, тогда посыплю голову пеплом.

$queue = new Zend_Queue('Redis', array('adapterNamespace' => 'Rediska_Zend_Queue_Adapter'));

упс, не дописал.

var_dump($queue->debugInfo()); — выводит инфу отладочную, все ок

далее:

$queue->isExists('test7'); постоянно выдает:

Fatal error: Call to undefined method Zend_Queue::isExists() in /var/www/sigserv/test2.php on line 67
Все верно, адапетр Редиски тут не причем, дело в том что действительно в Zend_Queue такого метода нету, он есть только у адапетров: $queue->getAdapter()->isExists('test7');

Zend_Queue — далека до совершенства :)
кстатити на счет Редиски, там много багов и в частности утечек памяти (очевидно писали идиоты)
так что с их сайта на продакшене не рекомендую использовать.

Фиксер переписал модуль полностью, а я допиливал то, что не успел он написать. На утечке проверил — фиксер сделал все качественно, за что ему наше с кисточкой! Так что, просите исходники у Фиксера, кто с ним знаком.

К сожалению, у нас организована безопастность таким образом, что мне исходники из внутренней сети не вытянуть, но будет надобность — смогу написать и самостоятельно. Протокол Редиски — чуть посложнеее мемкеша :).
Sign up to leave a comment.

Articles

Change theme settings