Перейти к основному содержимому
Нормативная версия документации - английская

Эта страница переведена с английского языковой моделью. При любом расхождении верен английский оригинал.

Очереди

Клиент zeromq не держит очереди сообщений: отправка пишет кадры в соединение узла, а то, что ещё в пути, хранят буферы сокетов ядра.

Где ждёт сообщение между двумя сокетами zeromq, для PUSH/PULL и для PUB/SUBPUSH/PULLPUB/SUBОтправка PUSHберёт следующийпо очереди узелПишет кадрыв соединениеэтого узлаБуферы сокетовядрана обоих концахПриём PULLчитает соединенияузлов по очередиОтправка PUBкаждому подписчикус совпавшим фильтромПишет в соединениекаждого из них,одно за другимБуферы сокетовядрана обоих концахПриём SUBчитает то, чтопропустили фильтрыКлиент zeromq не держит очереди сообщений:отправка заканчивается, когда кадры записаныlibzmq держит 1000 сообщений на каждое соединение(SNDHWM, RCVHWM): на пределе PUB отбрасывает, PUSH блокирует
Схема текстом
  1. PUSH/PULL: Отправка PUSH берёт следующий по очереди узел; Пишет кадры в соединение этого узла; Буферы сокетов ядра на обоих концах; Приём PULL читает соединения узлов по очереди
  2. PUB/SUB: Отправка PUB каждому подписчику с совпавшим фильтром; Пишет в соединение каждого из них, одно за другим; Буферы сокетов ядра на обоих концах; Приём SUB читает то, что пропустили фильтры
  3. Отправка PUSH берёт следующий по очереди узел → Пишет кадры в соединение этого узла: по очереди
  4. Пишет кадры в соединение этого узла → Буферы сокетов ядра на обоих концах
  5. Буферы сокетов ядра на обоих концах → Приём PULL читает соединения узлов по очереди
  6. Отправка PUB каждому подписчику с совпавшим фильтром → Пишет в соединение каждого из них, одно за другим
  7. Пишет в соединение каждого из них, одно за другим → Буферы сокетов ядра на обоих концах
  8. Буферы сокетов ядра на обоих концах → Приём SUB читает то, что пропустили фильтры
  9. Клиент zeromq не держит очереди сообщений: отправка заканчивается, когда кадры записаны
  10. libzmq держит 1000 сообщений на каждое соединение (SNDHWM, RCVHWM): на пределе PUB отбрасывает, PUSH блокирует

Отправка PUSH берёт следующий по очереди узел и пишет кадры в соединение этого узла. Отправка заканчивается, когда кадры записаны, поэтому узел, который читает медленно, заставляет отправку ждать.

Сокет PULL, когда у него запрашивают сообщение, читает по одному сообщению от каждого подключённого узла по очереди. До тех пор кадры остаются в буферах ядра, на этой стороне и на стороне отправителя.

Отправка PUB пишет сообщение в соединение каждого подписчика с совпавшим фильтром, одно за другим. Поэтому самый медленный из этих подписчиков задерживает издателя, и из-за медленного подписчика ничего не теряется. Сообщение, которому не подошёл ни один фильтр, отбрасывается без ошибки.

libzmq, библиотека на C, которой пользуется большинство других языков, работает иначе. Там у каждого соединения своя очередь, по умолчанию на 1000 сообщений (предельный размер очереди, SNDHWM и RCVHWM). Когда очередь заполнена, PUB отбрасывает сообщение, а PUSH блокирует отправку. Клиент zeromq пишет отправку прямо в соединение, а параметры сокета - это идентичность узла и таймаут подключения.

Насколько далеко вперёд читает подписка этого крейта, ограничивает собственный канал крейта глубиной read_ahead. Его показывает страница Обратное давление.

Числа libzmq взяты из zguide (раздел «High-Water Marks»). Поведение клиента описано по исходному коду zeromq 0.6.