|
|
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
Типа, просто и понятно, но чем плохи сокеты Windows или чем не устраивает Indy или ICS или IPWorks! или ещё что... И - где лучше не использовать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.09.2014, 06:52 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
Вот что пишут. Предположим, мы проектируем систему и используем "чистый" tcp. Вопросы: - используем блокирующие сокеты? Или асинхроные? Блокировка => просто кодить, но считается, что приложение "плохо масштабируется". Если же используем асинхронный i/o, то запариваемся с кодингом. - как решить вопрос с изменением нагрузки? Какой компонент будет считаться сервером, какой - клиентом? Что делать, чтобы подключить сервер к серверу? Что делать, если связь часто обрывается? - что делать, когда сообщение частично? Что делать, если сообщения поступают слишком часто? Если сообщение не помещаются во входной буфер? - где и как хранить очередь сообщений? Нужна ли очередь на приеме? ... на передаче? - что делать с потерянными сообщениями? Игнорировать? , отправить запрос повторно, выбросить исключение, ...? - что делать, если нам нужно использовать другой сетевой транспорт? Скажите, мультикаст вместо уникаст TCP ? Или IPv6? - что делать, если нужно организовать связь с приложением, написанном на другом языке программирования? Или если кодировка сообщения отличается от нашей? - как обработать ошибки сети? Игнорировать, попробовать еще раз, завершить работу? - ...? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.09.2014, 07:33 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
Есть вариант использовать готовые системы, ориентированные на обмен сообщения. Они отлажены, стандартизированы, решают проблемы с балансировкой нагрузки, с обработкой ошибок, с динамической маршрутизацией, с кодировками и т.п. К сожалению, эти системы - брокер - ориентированные. То есть, обычно предполагают наличие специального вычислительного процесса, который работает на выделенном железе и обслуживается специально выделенными людьми. Следовательно, это стоит делать только для больших распределенных приложений с множеством компонентов, построенных большими командами. ... PS: мы, например, для одной распределенной задачи использовали существующую сеть jabber - серверов, "паразитируя" на них. Кодить, используя сообщения, а не tcp - поток, намного приятнее. :) Позднее мы пытались отойти от использования публичных jabber -серверов и запустили на своем железе собственный сервер, но надежность системы в итоге упала: наш админ не смог обеспечить доступ к ресурсу в обещанном режиме 24х7... ... Таким образом, небогатым разработчикам небольших и средних приложений приходится либо избегать сетевого программирования и делать "монолитны" приложения, которые плохо развиваются. Либо "нырять в сокеты" и создавать сложные в разработки и сопровождении приложения. Или использовать существующие системы обмена сообщениями и в зависеть от третьей стороны. ZeroMQ была создана для того, чтобы сделать возможной работу с сообщениями простым и дешевым образом, чтобы она могла работать в любом приложении, и была бесплатной (или со стоимостью, близкой к нулевой). Она была разработана как библиотека, которую просто можно использовать без каких-либо зависимостей. Она запускается на любой ОС и работает с любым языком программирования. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.09.2014, 07:51 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
Поехали! Сокеты. Жизнь сокетов ZeroMQ состоит из четырех частей. 1. Создание и уничтожение, которые должны идти парами: см zmq_socket (), zmq_close () . 2. Настройка сокета: установить параметры сокета: zmq_setsockopt () , проверить настройки сокета: zmq_getsockopt () . 3. Подключение сокета в топологию сети путем создания сходящего или исходящего ZeroMQ соединения: zmq_bind ( ), zmq_connect () . 4. Использование сокета для передачи данных путем записи и приема сообщений в/из них: zmq_msg_send ()/ zmq_msg_recv () . Сокеты в Delphi представлены просто указателями (Pointer). А сообщения zmq_msg_t - структурой: Код: pascal 1. 2. 3. Подключение сокетов Для создания соединения между двумя узлами на одном узле использует zmq_bind() , а на втором zmq_connect() . Принято считать, что узел, где zmq_bind() - это "сервер", который располагается в заранее известной точке сети (т.е., имеет фиксированный сетевой адрес). А узел, где используется zmq_connect() - "клиент", его сетевой адрес заранее неизвестен. Говорят "привязка" сокета ("биндинг") и подключение ("коннектинг"). То есть "привязываем" сокет к конкретной точке, и "подключаем" сокет к конкретной точке, "конкретная точка" - это известный сетевой адрес. Соединения ZeroMQ отличаются от привычных соединений TCP: Работают по разным транспортным протоколам (inproc, ipc, tcp, pgm, epgm). Один сокет может иметь много исходящих и много входящих соединений. Метода Accept() /zmq_accept()/ нет! Когда сокет привязывается к конретной точке, Accept() стартует автоматически. Сотевые соединения выполняются в фоне, а ZeroMQ автоматом реконнектится, если сеть обрывается и восстанавливается. Приложение не будет работать с соединением напрямую, только через сокет ZeroMQ. В ранее рассмотренных примерах мы запускали клиента до запуска сервера, безо всяких проблем. В обычных сетях мы бы уже получили сообщение, что сервер не готов и т.д. Но ZeroMQ позволяет запускать и останавливать разные сетевые компоненты в произвольной последовательности. Как только узел - клиент вызывает zmq_connect () , соединение уже существует, и что узел может начать писать сообщения в сокет. На определенном этапе (хорошо бы, до момента переполнения очереди сообщений ), сервер оживает, выполняет zmq_bind () , и ZeroMQ начинает доставлять сообщения. Узел-сервер может биндиться к нескольким конкретным точкам сети. И даже к разным протоколам. Код: pascal 1. 2. 3. К конкретной точке сети нельзя биндиться дважды. Если будет запущено два сервера, выполняющие такой код: Код: pascal 1. - то работать будет первый, второй будет ждать. Пишут, однако, что для ipc транспорта допускается множественный биндинг, но нас это пока не касается: ipc пока реализован только на всяких линуксах. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.09.2014, 09:34 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
Добавление: Протокол inter-thread (inproc) - это транспорт, основанный на сигналах. Очень быстрый. Но с ограничениями: сервер должен выполнить биндинг до того, как клиент попытается законнектиться. Пишут, что в будущем, возможно, это поведение будет исправлено (приведено к стандартному). А пока рекомендованная схема: главный поток создает сокет, биндит его к уникальному имени, потом создает дочерний поток, в котором так же создается сокет, который коннектится к inproc с тем же именем. В остальном с inproc точно так же: Биндинг в одном потоке: Код: pascal 1. 2. 3. 4. 5. Конектинг в другом: Код: pascal 1. 2. 3. То есть: 'имя протокола://уникальное имя коннекта' ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 23.09.2014, 09:56 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
Дальше я буду писать ZMQ вместо ZeroMQ. Или даже 0MQ. С целью экономии ресурса клавиатуры. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.09.2014, 05:57 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
Шаблоны сетевых топологий ZeroMQ. В первой части были представлены и подробно описаны приложения, реализующих два простых шаблона сетевой топологии вроде "Запрос - Ответ" и "Издатель - Подписчик. Во 2й части был представлен шаблон решения задачи методом "Разделяй и Властвуй" (когда задачу разделяем на кусочки и разадаем исполнителям). При этом использовался шаблон "Параллельный трубопровод" (Parallel Pipeline). Считается, что ZMQ "искаропки" реализует четыре шаблона: 1. Запрос-Ответ (Request-Reply), в котором соединяются множество клиентов к множеству сервисов ("серверов"). Этот шаблон предназначен для реализации удаленного выполнения каких-либо задач, вроде. 2. Издатель - Подписчик (Pub-sub), в котором соединяются множество издателей с множеством подписчиков. Это - шаблон для реализации задачи предоставления данных по подписке. 3. Трубопровод (Pipeline), в котором соединяются узлы для "проталкивания" (в т.ч. параллельного) сообщений, для задач, требующих в процессе решения множество этапов перемещения (в том числе циклического) данных. Это - шаблон для решения задач вроде разделения большого задания на несколько меньших с последующим сбором результатов. 4. Эксклюзивная пара (Exclusive pair), в которой соединяются только два сокета. Это - шаблон для решения задач вроде связи двух потоков в процессе. Четвертый шаблон ("Эксклюзивная пара") представляется слишком очевидным для того, чтобы делать под него отдельно приложение, использовать его можно так, как описано здесь: 16608271 . В каждом из представленных приложениях сокеты настраивались в соответствии с задачей. Для пар сокетов ZMQ есть следующие допустимые комбинации настроек: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. Половину из этих комбинаций мы уже знаем. :) Остальные я еще только собираюсь пощупать. Из документации: Использование пар сокетов ZMQ в других комбинациях повлечет появление недокументированных эффектов и, возможно, чудовищные разрушения оборудования. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.09.2014, 06:28 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
Поговорим о СООБЩЕНИЯХ ZMQ В рассмотренных ранее тестовых приложениях мы пользовались методами zmq_send () и zmq_recv () . В их параметрах мы указывали сокет, адрес буфера с данными и длину данных. Все незатейливо. Беда в том, что zmq_recv() нельзя использовать, если не знаешь заранее размер принимаемого сообщения: если сообщение не поместится, хвост отсечётся. Так вот, в API ZMQ есть чудесные методы для работами со структурой zmq_msg_t. Здесь уже возможностей больше (но и кодить придется больше): Инициализация сообщения: zmq_msg_init(), zmq_msg_init_size(), zmq_msg_init_data() . Отправка и получение соощения: zmq_msg_send(), zmq_msg_recv() . Освобождение (ресурсов) сообщения: zmq_msg_close() . Доступ к данным сообщения: zmq_msg_data(), zmq_msg_size(), zmq_msg_more() . Работа со свойствами сообщения: zmq_msg_get(), zmq_msg_set() . Манипуляции с сообщениями: zmq_msg_copy(), zmq_msg_move() . В памяти сообщение представляется собой структуру: Код: pascal 1. 2. 3. 4. Особенности работы с сообщениями ZMQ: - вы создаете и передаете в работу только объекты zmq_msg_t, а не блоки данных; - для чтения сообщения, сначала вызываем zmq_msg_init() (создается пустое сообщение), а затем передаем его в zmq_msg_recv() ; - для инициализации сообщения вашими данными, необходимо вызвать zmq_msg_init_size() - будет создано сообщение и выделен блок данных указанного размера. Затем вы "руками" заполняете данные и передаете сообщение в zmq_msg_send() . - для освобождения (для очистки, а не для удаления объекта zmq_msg_t), вызываем zmq_msg_close() . Это действие сбросит ссылку в ZMQ на структуру и для ZMQ соощение перестанет существовать. - для доступа к содержимому сообщения, используем zmq_msg_data() . Для получения длины блока данных в байтах используем zmq_msg_size() . Внимание! Операции zmq_msg_move(), zmq_msg_copy(), zmq_msg_init_data() опасны разрушением контекста, если вы не знаете, для чего и как их использовать. После того, как сообщение было передано в zmq_msg_send(), ZMQ очистит сообщение, то есть, например, заполнит структуру нулями. PS: ХЗ, что там делается реально - сообщение то зануляется, то нет. Ну, раз сказано, значит, так и есть. Вы не можете отправить одно и то же сообщение дважды, точно так же вы не можете получить доступ к блоку данных сообщения после его отправки. Для zmq_send() и zmq_recv(), эти правила не работают, тут вы пересылаете свой массив байт, а не структуру zmq_msg_t. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.09.2014, 07:09 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
Если все же нужно отправить одно и то же сообщение более, чем один раз, и оно довольно большое, создаем еще одно сообщение, инициализируем его с помощью zmq_msg_init() , а потом используем zmq_msg_copy() . Будет создана копия исходного сообщения. Такой способ не создает копию сообщения, а просто создает копию ссылки на сообщение. Теперь это сообщение можно отправить дважды (если нужно больше - создаем больше копий). Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. Сообщение будет полностью удалено только после того, как будет отправлена последняя копия. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.09.2014, 07:22 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
ZeroMQ также поддерживает сообщения, состоящие из нескольких частей (фрагментов, фреймов). В этом случае в одном сообщении содержится несколько кадров. Для однокадровых сообщений структура пересылаемых данных очень проста: [Длина блока данных][...блок данных ...] Составные (многокадровые) сообщения состоят из нескольких таких кадров, например Код: javascript 1. 2. 3. Составные сообщения широко используются в реальных приложениях, их применение будет рассмотрено позднее. Пока просто знаем, что такие - бывают. Фреймы представляют собой базовый для ZMQ формат, в котором данные передаются по выбранному транспорту. Длина - от нуля и дальше. PS: фреймы - это несомненная польза с т.зр. программистов, использовавших TCP, для которых всегда был актуален вопрос: "а сколько мне нужно прочитать данных из данного сокета в данных момент?". Такой покадровый обмен данными называется ZMTP протоколом . Обычно сообщения ZeroMQ состоит из одного кадра, наподобие датаграммы UDP. Для превращения сообщения в мультикадровое ZMQ просто устанавливает в кадре бит "есть ещё!" . Затем читаем следующие кадры, пока не получим последний кадр со сброшенным битом. И так. Сообщение может состоять из одного и более частей. Части сообщения называются кадры/фреймы (frames). Каждая часть есть представляется объектом zmq_msg_t . Программист принимает и отправляет каждую часть отдельно (используя API нижнего уровня). API высших уровней обеспечивают обертками для отправки составных сообщений целиком. Кроме того: Можно посылать сообщения нулевой длины. Например, для отправки сигнала из одного потока в другой. Или - как мы делали в приложении 16607836 : Код: pascal 1. ZeroMQ гарантирует доставку либо всех частей сообщения, либо ни одной части. ZeroMQ не отправляет сообщение (ни простое, ни составное) прямо сразу, а выполняет это с задержкой. То есть, нужно учитывать, что составные сообщения должны помещаться в памяти. Еще раз: сообщение (простое или составное) должно помещаться в памяти. Если вам нужно отсылать здоровенные файлы, то разбейте их на части и отправьте каждую часть в сообщении, состоящем из одной части, использование составного сообщения не позволит экономить память. После использования принятого сообщения, его нужно закрыть: zmq_msg_close() . При отправке сообщения этот метод вызывать не нужно. То есть, чисткой занимается получатель. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.09.2014, 07:54 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
Ах, да. Есть удивительный метод zmq_msg_init_data() . Этот метод позволяет инициализировать сообщение без копирования данных пользователя. Для скорости, с целью экономии памяти и т.д. Так вот, пока не используем его, если не хотим проблем (например: для использования метода нужно определить деаллокирующую данные функцию, да не простую, а thread-safe). В документации сказано то же самое. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.09.2014, 08:02 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
Работа с несколькими сокетами ZMQ. Во всех примерах, что мы рассмотрели ранее, схема работы была примерно одинаковой - в цикле повторялись одни те же действия: Код: plaintext 1. 2. 3. 4. 5. Что делать, если нам нужно читать сообщения из нескольких конечных точек одновременно? Самое простое - коннектить один сокет ко всем нужным конечным точкам и позволть, чтобы ZeroMQ втягивала нужные нам данные. Это допустимо, если все конечные точки настроены для работы по одному и тому же шаблоны, но может быть неправильным, если, например, коннектить PULL - сокеты к конечной точке типа PUB. Так вот, чтобы иметь возможность читать из множества сокетов сразу, следует использовать метод zmq_poll() . Более того, рекомендуется обернуть zmq_poll() в удобный для ситуации собственный фреймворк. Создадим простое приложение, которое покажет, как читать данные из неблокирующего сокета. Будем читать данные из двух сокетов с использованием неблокирующего чтения. Приложение будет работать и как подписчик, и как работник в системе обработки параллельных задач. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.09.2014, 08:18 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
Вот исходник ридера, читающего данные и от нашей старой задачи "Ventilator" и от сервера метеостанции: Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. Недостатком такого способа является некоторая дополнительная задержка на обработке первого сообщения (sleep(1) в конце цикла, когда нет никаких сообщений в процессе). Это было бы проблемой в приложениях, где задержка в миллисекунды имеет жизненно важное значение. Кроме того, необходимо быть уверенным, что sleep () или любая другая функция задержки не жрет процессорное время. А теперь рассмотрим такое же приложение, но уже с использованием zmq_poll() . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.09.2014, 08:43 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
Теперь: "правильный" мульиридер: Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. Видим, что появилась интересная структура: Код: pascal 1. 2. 3. 4. 5. 6. 7. Массив таких структур Код: pascal 1. инициализируется следующим образом: Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. В каждом элементе указан свой сокет и задана маска ожидаемых событий (ZMQ_POLLIN). Далее вызывается метод zmq_poll(fItems[0], Length(fItems), -1); Последний параметр - время ожидания события в ms. Если -1 - то ожидание будет выполняться бесконечно долго. Событие, произошедшее при выполнении zmq_poll(), заносится в битовую маску revents. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.09.2014, 09:32 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
чччД... Видим, что появилась интересная структура: Код: pascal 1. 2. 3. 4. 5. 6. 7. ... Честно говоря, не въехал, как использовать поле fd. Что "за стандартный сокет"? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.09.2014, 09:35 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
Составные сообщения. Процесс доставки сообщения атомарен . АтомаренТо есть, если на принимающей стороне API сообщило, что пришло сообщение, это значит, что сообщение уже полностью принято (и присутствует в памяти принимающей стороны). А если в процессе пересылки возникнут какие-то проблемы, то принимающая сторона об этом даже не догадается, до приемника сообщение просто не дойдет. Гарантированной доставки нет. О гарантированной доставке нужно заботиться программисту - с помощью нумерации сообщений, подтверждающих запросов, таймаутов и проч. Так вот, как было сказано ранее ( 16618997 ), сообщение может быть составным (состоять из нескольких кадров). В реальных приложениях это полезно - например, для реализации собственных структур и алгоритмов (например, для простых способов сериализации объектов). Так вот, насчет составных сообщений. Для каждой части (кадра) составного сообщения нужен свой экземпляр структуры zmq_msg_t. Необязательно, чтобы все части (zmq_msg_t) были объявлены одновременно, можно инициализировать очередной кадр и отправлять его с признаком ( "будет ещё!" ), используя единственный zmq_msg_t. Однако, все кадры сообщения будут накапливаться в памяти передающей стороны до момента отправки. Например, отправляем составное сообщение из 5 кадров. Можно объявить, инициализировать, заполнить данными, отправить и очистить пять разных zmq_msg_t. А можно работать с одним zmq_msg_t для всех пяти кадров последовательно. Пример (сообщение из 5 кадров), 5 экземпляров zmq_msg_t: Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. Пример приема сообщения из 5 кадров, 1 экземпляр zmq_msg_t: Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. Вещи, которые [b]важны при работе с составными сообщениями:[/b] - При отправки составного сообщения и первый, и все последующие кадры начнут отправляться "физически" только тогда, когда был отправлен финальный кадр. - Если на приме используется zmq_poll(), то следует иметь в виду, что в момент, когда вы получили первую часть сообщения, все остальные части были уже получены. - Вы физически получаете либо все части сообщения, либо ни одного. - Каждая часть сообщения есть отдельный элемент zmq_msg. - Вы получите всегда ВСЕ части сообщения, вне зависимости от того, проверяете ли вы свойство "ещё!". - На передающей стороне ZeroMQ последовательно помещает кадры сообщения в очередь, до кадра с признаком "последний" (вернее, без признака "будет ещё!" ), а только потом выполняется пересылка всех кадров сообщения. - не существует иного способа отказаться от частично отправленного сообщения, кроме как закрыть сокет: zmq_close() . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.09.2014, 22:12 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
чччД, читаю, очень интересно...Но всё равно возникает вопрос из заголовка - а для чего ? Всё равно ведь ниже ZeroMQ лежат виндовые сокеты, а их не перепрыгнуть? Можно примеры каких-нить настолько высоконагруженных приложений, в которых без стероидов ну никак ?... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.09.2014, 22:17 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
defecatorчччД, читаю, очень интересно...Но всё равно возникает вопрос из заголовка - а для чего ? Всё равно ведь ниже ZeroMQ лежат виндовые сокеты, а их не перепрыгнуть? Можно примеры каких-нить настолько высоконагруженных приложений, в которых без стероидов ну никак ?... У меня там была рекламная страничка, но Рустам её грохнул. Но я её помню наизусть: Особенности ZeroMQ: Асинхронный ввод-вывод, в фоновых потоках. Последние взаимодействуют с потоками приложения, используя неблокирующие структуры данных; таким образом, многопоточные приложения ZeroMQ не требуют блокировок, семафоров и либо других методов перевода в состояние ожидания. Сетевые компоненты могут подключаться и отключаться динамически, при этом ZeroMQ будет реконнектиться автоматически. Имеется в виду, что вы можете запускать компоненты в любой последовательности. Можно создать "сервис - ориентированную архитектуру" (SOAs), в которой сервисы могут подключаться и отключаться к сети в любой момент. Сообщения могут автоматически ставиться в очередь, по необходимости. Это делается логично, с проталкиванием сообщения как можно ближе к приемнику перед их постановкой в очередь. ZeroMQ умеет бороться с переполнением очередей (называется "high water mark"). Когда очередь полна, ZeroMQ автоматически блокирует отправителя, или отбрасывает сообщения в зависимости от режима обмена сообщениями (см. ранее о "шаблонах"). Она позволяет вашему приложению общаться в через произвольный транспорт: TCP, multicast, in-process, inter-process. Вам не нужно менять код для использования другого транспорта. Она аккуратно обрабатывает медленных и блокирующих получателей сообщений, используя различные стратегии, которые зависят от используемого "шаблона". Она позволяет использовать различную схему маршрутизации, с помощью различных шаблонов, таких как "запрос - ответ", "издатель - подписчик". Эти шаблоны позволяют построить сеть нужной вам топологии. Она позволяет создать прокси для сообщений из очереди, приходящих сообщений или выхватывая нужное сообщение одним вызовом. Прокси позволяют уменьшить связную сложность сети. Она доставляет сообщения полностью в том виде, в котором оно было отправлено, используя простую упаковку. Если вы отправили сообщение длиной 10к, вы и получите сообщение длиной 10к. Она не налагает ограничений на формат сообщений. Сообщения представляют собой блобы длиной от нуля до нескольких гигабайт. Когда вам нужно специальное представление данных, вы выберете другой продукт, типа msgpack, Google's protocol buffers, и т.д. Она разумно обрабатывает сетевые ошибки, выполняя повторные запросы когда это имеет смысл. Она уменьшает затраты на железо. С использованием ZeroMQ в центр приложения быстро перемещается цикл обработки сообщения, а ваше приложение вскоре распадается на набор задач обработки сообщений. Это элегантно и естественно. И это масштабируется: каждая из этих задач транслируется в узел сети, а узлы общаться друг с другом через произвольные транспорты. Два узла в одном процессе (узлом является поток), два узла на одном компьютере (узлом является процесс), или два узла в одной сети (узлом является компьютер)-это все прозрачно и без изменения кода приложения. Ах да, твой вопрос... имхо, проще и легковеснее, чем ZMQ, я ничего не видел. Прочие ориентированные на сообщения системы реализуются в виде службы, а ZMQ - просто библиотека. Типа, FireBird Embedded: для больший задач лучше настоящий сервер, а для приложения "на флешке" - FB Embedded - самое оно. :) ...хотя, есть примеры "больших" приложений: Веб-сайту Second Life удалось получить 13,4 микросекунды непрерывного времени ожидания и обслуживать до 4 100 000 сообщений в секунду. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.09.2014, 22:43 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
чччД, а то, что асинхронные сокеты изобрёл Мелкософт, никого уже не смущает ? 4 ляма сообщений в секунду - это железо умалчивается ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.09.2014, 22:48 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
не наезжаю, ни боже мой. Я просто пытаюсь понять, чем эта либа отличается от другой прослойки типа RealThinClient - тм тоже изначально синхронные сокеты ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.09.2014, 22:50 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
defecatorчччД, читаю, очень интересно...Но всё равно возникает вопрос из заголовка - а для чего ? Всё равно ведь ниже ZeroMQ лежат виндовые сокеты, а их не перепрыгнуть? ... Кроме того, ZMQ использует не только TCP, но и, например, inproc протокол для связи между потоками (а в UNIX-системах - между процессами). ... У меня лично от Windows сокетов послевкусие. Особенно после асинхронных. "Ах, что-то пришло в буфер, посмотрим... Заголовок уже загружен? Нет еще, ну ладно... Опять сообщение - ура, заголовок загружен, и даже часть тела... аккуратно анализируем заголовок, и снова цикл ожидания загрузки остатка сообщения..." А сообщения ZMQ - атомарны. Конечно, атомарность сообщений ZMQ - не всегда благо. Например, при получении данных большого объема: сколько тебе послали, столько ты и получишь, все сразу. А с винсокетами ты можешь послать всех, кто (например) неправильно отправил заголовок, еще "в процессе", на принимая сообщения целиком. По этой причине, если выставить ZMQ сокет "в интернет", его сразу могут завалить всяким мусором. Ну, если не принимать никаких мер. Но в локальной сети ведь злоумышленников быть не должно? :) Т.е., это - не "серебряная пуля". А такой ничего себе ножичек. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.09.2014, 22:54 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
defecatorчччД, а то, что асинхронные сокеты изобрёл Мелкософт, никого уже не смущает ? ... А они как раз и используются в ZMQ, вовсю. defecator... 4 ляма сообщений в секунду - это железо умалчивается ? Там используется распределенная архитектура, там МНОГО железа. Для организации его в сеть там как раз используется ZMQ. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.09.2014, 22:56 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
defecator... Я просто пытаюсь понять, чем эта либа отличается от другой прослойки типа RealThinClient - тм тоже изначально синхронные сокеты А в ZMQ - асинхронные... ...а про RealThinClient я вообще ничего не знаю. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.09.2014, 22:58 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
Проблема динамического обнаружения Краткое содержаниеВопрос сродни вот этому: Как получить список доступных MS SQL серверов? Одной из проблем, возникающих при проектировании крупных распределенных систем является обнаружение сервисов. Частный случай проблемы - "как клиент узнает, к какому серверу нужно коннектиться?" А в общем случае - "как элементам сети найти друг друга?" Особенно трудно в случае, когда разные элементы подключаются и отключаются, из разных узлов сети. Поэтому это называется "проблемой динамического обнаружения". Эта проблема решается везде по-разному: используется служба DNS, или широковещательные сообщения (UDP) и т.п. Есть несколько простых решений проблемы динамического обнаружения. Можно жестко закодировать адрес(ip + порт) (конечную точку). Вообще никаких проблем - и никакой гибкости. Впрочем, некоторой гибкости для tcp транспорта можно добавить с помощью службы DNS. Можно конечную току задавать с помощью конфигурационных файлов (и т.д.). Главное - не забывать их вовремя обновлять . Можно использовать специальный брокер адресации, который передаст вам нужные данные. Только вот адрес этого брокера должен быть известен... Можно построить средство, исследующее окружение, сканирующее известные диапазоны адресов и порты. Или рассылающее (получающее) udp - пакеты об адресной информации. ... ... ... ~~~~~~~~~~~~~~~~~~~~~~~~~~~ Можно при запуске нового элемента сети вручную задавать конечную точку ("адрес сервера"). То есть, при подключении вы просто знаете конфигурацию сети и сообщаете нужные данные новому элементу сети. Так часто делают, но в реальности это приводит к громоздким и хрупким топологиям. Вспомним пример "Издатель-Подписчик": 16583825 . Пусть есть один издатель и тысяча подписчиков. Каждый подписчик коннектится к одному издателю. Можно руками конфигурировать подключение каждого подписчика, это просто. Сделали, работает. Подписчик - динамичный (может подключаться из любого места, и включаться когда угодно), а издатель - статичный. Сделали, работает. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.09.2014, 23:33 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
Неожиданно набежали янычары. А вот теперь представим, что появился еще одни издатель. Нужно еще раз настроить каждого подписчика. Всех, 1000 шт. И каждый раз появление нового издателя повлечет за собой увеличение стоимости настройки. Нужно динамическое обнаружение. Добавим брокер сообщений. ZMQ не поставляется с брокерами, но позволяет его легко построить. Теперь Издатель-Подписчик схема будет выглядеть вот так: ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.09.2014, 00:00 |
|
||
|
|

start [/forum/topic.php?fid=58&startmsg=38754161&tid=2039957]: |
0ms |
get settings: |
7ms |
get forum list: |
14ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
152ms |
get topic data: |
10ms |
get forum data: |
2ms |
get page messages: |
55ms |
get tp. blocked users: |
1ms |
| others: | 204ms |
| total: | 449ms |

| 0 / 0 |
