|
|
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
Таким образом, со статичным борокером сообщений задача решена. Можно даже запустить общий брокер для всех типов сообщений, и строить сетевую архитектуру вокруг него. Т.е., топология "Звезда" работает. Какое-то время. ...пока не возникнут вопросы вроде пропускной способности и расширения/усложнения логики брокера. АДЪ неминуем. ZMQ придет, порядок наведет! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.09.2014, 00:12 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
Куда лучше реализовать брокер не в качестве транспорта сообщений, а в качестве поставщика адресной информации. Для этого следует использовать сокеты ZMQ типа XPUB и XSUB, так как с ними ZMQ не пересылает сообщения от издателя к подписчику напрямую. Сокеты XSUB и XPUB - точно такие же, как и сокеты типа SUB и PUB, за исключением того, что они обрабатывают подписки в форме специальных сообщений. А при подключении SUB и PUB сокетов к XPUB и XSUB сокетам первые связываются друг с другом уже по известным адресам. То есть, основной поток данных идет, минуя брокер: ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.09.2014, 00:27 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
чччД... То есть, основной поток данных идет, минуя брокер: ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.09.2014, 00:27 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
А ты еще спрашиваешь defecator...а для чего ? ... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.09.2014, 00:30 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
чччДс винсокетами ты можешь послать всех, кто (например) неправильно отправил заголовок, еще "в процессе", на принимая сообщения целиком"послать" ты можешь только закрыв сокет. а так пока тебе в него будут вваливать придется читать ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.09.2014, 09:08 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
vavanчччДс винсокетами ты можешь послать всех, кто (например) неправильно отправил заголовок, еще "в процессе", на принимая сообщения целиком"послать" ты можешь только закрыв сокет. а так пока тебе в него будут вваливать придется читать Вот именно - c WinSockets ты можешь закрыть сокет в процессе чтения, не дочитав... А в ZMQ - ты начинаешь читать, когда "все уже здеcь". ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.09.2014, 09:40 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
чччДв ZMQ - ты начинаешь читать, когда "все уже здеcь"при условии что оно поместилось ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.09.2014, 09:48 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
vavanчччДв ZMQ - ты начинаешь читать, когда "все уже здеcь"при условии что оно поместилось При всех условиях. Если ты начал читать, значит - сообщение здесь. Они либо приходит, либо нет. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.09.2014, 11:36 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
Шаблон "Разделяемая очередь". Потихоньку перейдем к сокетам DEALER и ROUTER . ... В реальности может потребоваться, чтобы множество клиентов могли подключаться к разным сервисам (например, для распределения нагрузки по сервисам). Для реализации коннектов "много:много" есть два пути: - каждый клиентский сокет может коннектиться ко множеству сервисных конечных точек. То есть, один клиентский сокет типа (REQ) коннектится к сервисным сокетам с известными адресами. После этого запросы будут распределяться между сервисами. Например, коннектим клинтский сокет к трем конечным точкам ("сервисам") :A, B, и C. Вспомним этот ( 16562041 ) пример, поясняющий схему "Запрос - Ответ" (REQ - REP). Чтобы клиент ( 16562066 ) подключился к трем сервисам (например, по tpc на localhost, на трех разных портах), нужно Код: pascal 1. 2. 3. Клиент последовательно выполняет запросы R1, R2, R3, R4. В результате запросы R1 и R4 отправляются к сервису A, R2 - к B, R3 - к C. Циклически распределяя запросы (наш любимый roud-robin). Такая конструкция позволяет добавлять без проблем добавлять сколько угодно клиентов. Как показано выше, с помощью zmq_connect() можно добавлять сколько угодно сервисов. Беда в том, что клиент должен знать, где находится новый сервис. Если клиентов - 100, и в течении скажем, суток, добавляется всего три новых сервиса, то нужно в итоге триста раз переконфигурировать всех клиентов. Что грустно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.09.2014, 03:15 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
В идеале, мы должны быть в состоянии добавлять и удалять сервисы или клиентов в любое время, не касаясь любой другой части топологии. ... авторДля реализации коннектов "много:много" есть два пути: - каждый клиентский сокет может коннектиться ко множеству сервисных конечных точек. То есть, один клиентский сокет типа (REQ) коннектится к сервисным сокетам с известными адресами. После этого запросы будут распределяться между сервисами. - второй путь - использование брокера запросов как промежуточного слоя. ... Напишем крошечный брокер запросов, реализующий желаемую гибкость топологии. Брокер соединит две конечные точки - фронтенд (сокет стороны клиентов) и бэкэнд (сокет стороны сервисов). Затем брокер, используя zmq_poll(), будет отслеживать активность этих сокетов, и перебрасывать сообщения от одного сокета к другому. При чем, в ручном управлении очередности использования сервисов нет необходимости, т.к. ZeroMQ делает это автоматически для каждого сокета. Когда мы построили приложение ( 16562041 ) по схеме "Запрос - Ответ (Req_Rep)", система получилась с синхронным диалогом обмена. Клиент шлет запрос. Сервис читает запрос и шлет ответ. Клиент читает ответ. Если клиент или сервис будут выполнять что-то другое (например, клиент пошлет два запроса подряд без ожидания ответа), система просто перестанет работать. ... Конечно, раз теперь мы умеем пользоваться zmq_poll() ( 16619247 ), сделаем можно сделать брокер неблокирующим. Но мы пойдем другим путем, и не станем использовать сокеты типа REP и REQ. Так вот, есть схема использования пар сокетов, которые реализуют схему "Посредник - Маршрутизатор" , режимы сокетов соответственно называются DEALER и ROUTER . Они позволяют получить неблокирующий режим для схемы "Запрос - Ответ". В нашей схеме "Запрос - Ответ" сокет REQ будет "говорить" с сокетом ROUTER, а сокет DEALER - с сокетом REP. Сокеты DEALER ROUTER будет как раз размещаться на нашем брокере, передачу сообщений между ними мы обеспечим с помощью кода. Будем извлекать сообщение из одного и передавать его другому сокету. Наш брокер схемы "Запрос - Ответ" привязывается к двум конечным точкам: одна для коннектов к ней клиентов(фронтэнд сокет), вторая - для коннектов сервисов(бэкэнд сокет). Задача та же, что и в первом примере: возведение в квадрат целых чисел. Клиент отсылает запросы, сервис (сервер) - выполняет. Запрос - беззнаковое x32 целое число (UInt32) , ответ - квадрат беззнаковое x64 целого (UInt64). Вот что у нас было: Клиент Код: 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. Сервис (сервер) Код: 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. Пока ничего нового не видим: продублирована функциональность схемы "Вопрос - Ответ". Клиент - коннектится к конечной точке - к сервису, сервис находится в этой конечной точке и ждет запросов клиентов. "Конечная точка" - это известный адрес (Например, "tcp://localhost:5560"). То есть, реализована вот эта схема: 16630265 . Будем улучшать мир. Воткнем между ними брокер. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.09.2014, 05:04 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
Брокер. Что-то новенькое: сокеты DIALER и ROUTER. Брокер Код: 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. 65. 66. 67. 68. 69. 70. 71. 72. Чтобы все заработало, нужно у сервиса из 16630300 заменить биндинг на коннект: Код: pascal 1. 2. Брокер в асинхронном режиме слушает пул из сокетов с помощью zmq_poll(), затем читает (возможно, по частям) сообщение и транслирует его в выходной сокет. В обе стороны. Чтение по частям реализовано "для общности". Чтобы работало с любыми сообщениями. Интересно, что наши крошечные сообщения Код: pascal 1. 2. 3. и Код: pascal 1. 2. 3. порождают на стороне брокера каскад из нескольких составных сообщений из структур zmq_msg_t, что хорошо видно в отладчике. Теперь можно запускать сколько хочешь сервисов и сколько хочешь клиентов - все они будут общаться через брокер. Такой брокер для схемы "Запрос- Ответ" существенно облегчает обслуживание сети , так как клиентам нет нужды знать, где размещены сервисы, а сервисам нет нужны знать, где размещены клиенты. Единственной статической точкой является брокер. Жизнь налаживается. :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.09.2014, 07:08 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
чччД... Теперь можно запускать сколько хочешь сервисов и сколько хочешь клиентов - все они будут общаться через брокер. Такой брокер для схемы "Запрос- Ответ" существенно облегчает обслуживание сети , так как клиентам нет нужды знать, где размещены сервисы, а сервисам нет нужны знать, где размещены клиенты. Единственной статической точкой является брокер. ... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.09.2014, 07:09 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
Приведенный выше код трансляции сообщений представляется очень полезным для многих случаев для схемы "Запрос - Ответ". Так вот, ZeroMQ есть даже специальный метод, реализующий все, что мы нако'дли в брокере. См. ниже: "Та-да-мммм!" Код: pascal 1. frontend - сокет фронтэнд backend - сокет бэкэнд capture - сокет для перехвата сообщений (nil, если не используется) Технически нет никакой разницы между фронтэнд и бэкэнд сокетами. Та-да-мммм! Код: 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. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.09.2014, 07:26 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
Важно. Видов сокетов, которые практически можно использовать в брокере: Код: plaintext 1. 2. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.09.2014, 07:32 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
Мосты. Вопрос: "как передать сообщения из одной подсети в другую?" Или даже - из сети с протоколом tcp в сеть pgm . Вариант решения - с помощью моста . В качестве моста используем только что рассмотренный прокси (брокер сообщений). То есть, "мост" - это маленькое приложение, которое общается одним сокетом по одному протоколу, а другим - по другому. Ну и преобразовывает сообщения в подходящий для протокола вид, если нужно. В качестве примера напишем крошечный прокси, который, находясь между издателем и множеством подписчиков, соединяет две разные сети. Вернемся к примеру с метеостанцией. 16583825 Предположим, что сервер-издатель (которые измеряет температуру, давление и проч) работает во внутренней сети, часть подписчиков - тоже во внутренней. А еще часть - во внешней. Создаем прокси, в которой фронтэнд сокет (SUB) будет общаться с внутренней сетью, а бэкэнд сокет (PUB) - с внешней. Прокси будет подписываться фронтэнд-сокетом на события сервиса погоды и пере-публиковывать их на бэкэнд-сокете. Прокси для метео: "мост в интернет" Код: 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. Очень похоже на код предыдущего прокси, но используется для трансляции сообщений из одной подсети в другую. Точно так же подобный прокси - мост можно использовать, например, для подключения подписчиков в мультикаст PGM сети с издателем в TCP. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.09.2014, 20:33 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
чччД...прокси, который, находясь между издателем и множеством подписчиков, соединяет две разные сети... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.09.2014, 20:34 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
Кино нашел, на русском: http://wiki.4intra.net/0MQ_—_Сокеты_на_стероидах_(Сергей_Гулько,_OSDN-UA-2012) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.09.2014, 20:46 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
чччДКино нашел, на русском: http://wiki.4intra.net/0MQ_—_Сокеты_на_стероидах_(Сергей_Гулько,_OSDN-UA-2012) ...У ZeroMQ пропускная способность выше, чем у TCP/IP, хотя ZeroMQ работает over TCP/IP... Поискал - "каким же образом?" Нашел кое-какое описание, вроде специальной упаковки сообщений ZMQ в пакеты tcp. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 28.09.2014, 20:57 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
Обработка ошибок. ETERM. Обработка ошибок ZeroMQ основана на двух положениях: - считается, что процессы уязвимы от внутренних ошибок - считается, что внешние ошибки (и атаки) можно обработать (отразить атаки). В качестве примера приводится функционирование живой клетки, которая самоуничтожается при внутреннем сбое и максимально долго борется с внешними угрозами. Надежность кода должна обеспечиваться использованием Assert(). Срабатывание Assert() вызывает либо завершение приложения, либо исключительную ситуацию. Когда ZeroMQ обнаруживает внешнюю проблему, она возвращает соответствующий код завершения. В редких случаях, ZMQ показывает сообщения "молча", если нет очевидной стратегии, позволяющей восстановиться после ошибки. В рассмотренных ранее примерах обработки ошибок не было. В реальном коде необходимо анализировать код завершения вызова каждого метода ZMQ. Существует несколько простых правил, ноги которых растут еще с соглашений POSIX: - Методы, которые создают объекты, в случае ошибки возвращают nil; - Методы, которые обрабатывают данные, могут вернуть число обработанных байт, или -1 в случае ошибки; - Другие методы возвращают 0, когда все ОК, и, в случае ошибки - ненулевой код ошибке; - Код ошибки доступен через errno (для ОС POSIX) или через метод zmq_errno(); - Описание ошибки (например, для логирования) можно получить с помощью метода zmq_strerror(). Пример: Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. Есть две исключительные ситуации, которые могут обрабатываться как некритические: - когда ваш код принимает сообщение с ZMQ_NOWAIT ("асинхронно"), но данных не ожидается. ZMQ вернет -1 и установит код ошибка равным EAGAIN ; - когда один поток вызывает zmq_ctx_destroy() , а второй все еще выполняет работу в блокирующем режиме, то вызов zmq_ctx_destroy() вызывает закрытие контекста и всех блокирующих вызовов с кодом завершения -1, а код ошибки устанавливается равным ETERM . После того, как код будет отлажен и "вылизан", Asserts() могут быть отключены опциями компиляции. Однако, не стоит компилировать саму библиотеку ZMQ с отключенными assert() - запросто можно прозевать проблему в самом неожиданном месте. Рассмотрим способы "чистого" завершения процессов. В качестве примера возьмем параллельный трубопровод из примера: 16607833 . Мы возьмем пример параллельного газопровода из предыдущего раздела. Если мы в фоне стартовали множество рабочих процессов "Worker", то теперь мы хотим уничтожить их всех, когда все пакетное задание будет выполнено. Будем делать это, отправляя рабочим процессам сообщение "умри!". Этим будет заниматься процесс - сборщик "Synk" (так как он знает, когда завершается пакетное задание). Каким же образом подключить сборщик "Synk" к рабочим процессам? Сокеты PUSH/PULL допускают передачу только в одну сторону. Можно использовать сокеты другого типа, или смешать несколько потоков. Попробуем следующее: используем схему "Издатель-Подписчик" (pub-sub) для отправки рабочим процессам сообщения "умри!". Описание: Сборщик ("Sink") создает сокет - издатель (PUB) в новой конечной точке. Рабочие процессы ("Worker") связывают свои входные сокеты с этой конечной точкой. Когда сборщик ("Sink") определяет, что задание выполнено, он посылает сигнал "умри!" в свой сокет - издатель (PUB). Когда рабочий процесс ("Worker") обнаруживает сообщение "умри!", он завершается. Сборщик почти не меняется, добавится еще один сокет и отправка сообщения "умри!": Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. Вот полный код сборщика: Сборщик "Sink" Код: 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. Естественно, рабочий процесс "Worker" тоже придется переделать. Теперь "Worker" управляется двумя сокетами: PULL - для получения задачи, и SUB - для получения команд управления. Не забываем, что SUB сокет должен быть настроен: Код: pascal 1. Используем технику с zmq_poll (), которую уже применяли ранее. Код рабочего процесса "Worker" Код: 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. 65. Теперь запускаем: процесс "Sink", один или несколько процессов "Worker", процесс "Ventilator". В консоли процесса "Ventilator" жмем Enter и наблюдаем примерно такую картину: 16607848 За исключением того, что процессы "Worker" по завершению пакетного задания будут завершены: по завершению работы процесс "Sink" посылает сигнал "умри!" всем подписчикам (процессам "Worker"). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.09.2014, 07:53 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
Топология только что описанной сетевой задачи: ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 29.09.2014, 07:54 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
Обработка Crtl+C для консольных приложений Windows. Казалось бы, нажали и хрясь - приложение убито. Если бы. Как было сказано выше - можно получить зависон, особенно если приложение многопоточное. В общем, надо бы пройтись по всем тредам, сообщить им о своих намерениях, чтобы те завершили работу с соетами В общем, "все не так однозначно". Все, что написано в документации - касается всяческих Linux. Нам, дельфистам, придется использовать специальные обрабочики: подключаем в uses модуль Windows и настраиваем: Код: pascal 1. 2. 3. 4. 5. 6. Шаблон для CtrlCHandler: Код: pascal 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. Как выполнить "мягкое" завершение - зависит от текущей задачи. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.09.2014, 00:27 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
Мультипоточность с ZeroMQ. ZeroMQ предоставляет простой способ создания многопоточных приложений. При этом не потребуются ни мьютексы, ни блокировки, ни прочие дела для организации межпоточного взаимодействия, кроме сообщений, отправляемых через сокеты ZMQ. Есть одно железное правило для успешного многопоточного кодинга - "не разделять между потоками изменяющиеся данные". Обычно, когда два потока в приложении пытаются между собой разделять данные, то это выглядит как будто два алкаша пытаются разделить пиво. И чем больше алкашей собирается за столом, тем хуже ситуация. Большинство многопоточных приложений похоже сборище пьяных алоголиков, учинивших драку в баре. Одна известная фирма, производящая то ли рамки, то ли форточки, даже опубликовала статью " Решение 11 вероятных проблем вашего многопоточного кода ", в которой упомянуты всяческие ужастики вроде забытой синхронизации, незаблокированной модификации общих данных, и проч. Для беспроблемного написания многопоточного кода с помощью ZeroMQ следует руководствоваться следующими правилами: - Изолируйте данные внутри потока и никогда не разделяйте их между потоками. Единственным исключением являются контексты ZeroMQ, которые являются threadsafe. - Держитесь подальше от классических механизмов параллелизма, таких как мьютексы, критические секции, семафоры и т.д. Это анти-паттерны в приложениях ZeroMQ. - Создайте один ZeroMQ контекст в начале вашего процесса и передавайте его всем создаваемым потокам, с которыми будете взаимодействовать через InProc сокеты ZMQ. - Для создания структуры вашего приложения используйте подключаемые (attach) потоки, и соедините их с их родительскими потоками через сокеты PAIR по протоколу InProc. Порядок работы: привязываем (zmq_bind()) сокет, а затем создаем дочерний поток, который коннектится к сокету родительского потока. - Используйте отключаемые (detach) для имитации работы самостоятельных задач, с учетом своих условий. Подключите их по протоколу TCP. Позже вы можете переместить их в автономные процессы без значительного изменения кода. - Все взаимодействия между потоками происходит как ZeroMQ сообщения, которые вы можете определить более или менее формально. - Не разделять сокеты ZeroMQ между потоками. Сокеты ZeroMQ не потокобезопасны. Технически есть возможность передачи сокета от одного потока к другому, но это требует навыка. Единственное место, где разумно и оправдано разделение сокетов между потоками - это удаление сокетов в деструкторах ваших классовых оберток над ZMQ. Например. Предположим, в вашем приложении нужно более одного прокси, и вы хотите, чтобы каждый из них выполнятся в своем потоке. Очень легко допустить ошибку, создав фронтэнд и бэкэнд сокеты такого прокси в одном потоке, а затем передавая сокеты в прокси (который живет в другом потоке). Возможно, на первый раз все заработает, но глюки - неминуемы, причем в совершенно произвольные моменты времени. Запоминаем: не используем (и не закрываем) сокеты нигде, кроме как потоках, их создавших. Если следовать перечисленным правилам, можно легко создавать надежные многопоточные приложения. Логика приложения может размещаться потоках, процессах, или узлах сети, в соответствии с текущими планами по захвату мира. ZeroMQ использует нативные потоки ОС (Windows), а не виртуальные "зеленые" потоки. Для отладки можно использовать стандартные средства, вроде ThreadChecker от Intel, чтобы увидеть, что ваше приложение делает. К недостаткам использования нативных потоков можно отнести, что API-интерфейсы "родной" многопоточности конкретной ОС не всегда портируются, и, к примеру, если вы используете огромное количество потоков (тысячи), то некоторые ОС просто не потянут такой нагрузки. ... Перейдем к практике. Превратим наш старый сервер 16562041 , в нечто более работоспособное. Старый сервер был однопоточным. Если обслуживание каждого запроса было легким, то это нормально: один ZMQ поток может работать на полной скорости ядра процессора без ожидания и выполнять очень много работы. Но серверы из реальной жизни на каждый запрос делают более сложную работу. Одноядерного сервера может оказаться недостаточно, когда по серверу жахнет сразу 10000 клиентов. Сервер из реальной жизни будет запускать несколько рабочих потоков. После чего он будет принимать запросы так быстро, как это возможно и раздавать их своим своих рабочим потокам. Рабочие потоки будут "перемалывать цифирь" и отправлять результаты обратно. Конечно, это можно сделать с помощью прокси-брокера и внешних рабочих процессов, но часто легче начать один процесс, который займет все шестнадцать ядер, чем шестнадцать процессов, каждый из которых жрет одно ядро. Кроме того, рабочие процессы будут занимать линии связи и поглощать сетевой трафик и просто тормозить. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.09.2014, 03:25 |
|
||
|
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. Клиент - все тот же: Клиент Код: 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. Прежде всего интересен сервис ("сервер"). Основной поток приложения поочередно транслирует запросы от сокета fSocketClients (сокет типа ZMQ_ROUTER) к сокету fSocketWorkers (сокет типа ZMQ_DEALER) и обратно, используя знакомый метод zmq_proxy(). То есть, основной поток является брокером ("прокси") сообщений. Для обработки данных запущено три потока. Процедура потока - Worker_Routine(). В процедуре потока создается сокет fSocketReceiver типа (ZMQ_REP). Сокет fSocketReceiver рабочего потока связан с сокетом fSocketWorkers основного потока по inproc протоколу. Сокет рабочего потока: Код: pascal 1. 2. 3. Сокет основного потока: Код: pascal 1. 2. Естественно, вместо inproc - протокола можно было бы использовать tcp, но пришлось бы занять порт и, кроме того, inproc гораздо быстрее. Еще раз: работа сервиса. Сервис запускает несколько рабочих потоков. Каждый рабочих поток создает сокет типа REP и затем в цикле обрабатывает запросы к сокету. Рабочие потоки представляют собой обычные однопоточные сервисы, разница - в транспорте (inproc вместо tcp), и в направлении операции "привязать - подключить" (bind-connect). Сервер создает сокет типа ROUTER, чтобы общаться с клиентами и связывает его (сокет) с внешним интерфейсом по tcp. Сервис создает сокет типа DEALER, чтобы общаться с рабочими процессами и связывает этот сокет с внутренним интерфейсом (с помощью inproc). Сервер зарускает прокси, который соединяет оба сокета. Прокси получает входящие запросы от всех клиентов и распределяет эти запросы между рабочими потоками. При этом он правильно выполняет маршрутизацию ответов так, чтобы они вернулись туда, откуда приходили запросы. То есть, цепочка запрос - ответ выглядит так: REQ-ROUTER-очередь-DEALER-REP. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.09.2014, 06:03 |
|
||
|
ZeroMQ - сокеты на стероидах, часть 3 (а для чего?).
|
|||
|---|---|---|---|
|
#18+
Получилась вот такая структура: ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 30.09.2014, 07:54 |
|
||
|
|

start [/forum/topic.php?fid=58&msg=38759698&tid=2039957]: |
0ms |
get settings: |
8ms |
get forum list: |
11ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
153ms |
get topic data: |
10ms |
get forum data: |
3ms |
get page messages: |
80ms |
get tp. blocked users: |
2ms |
| others: | 222ms |
| total: | 493ms |

| 0 / 0 |
