Эта страница переведена с английского языковой моделью. При любом расхождении верен английский оригинал.
Очереди
Клиент zeromq не держит очереди сообщений: отправка пишет кадры в соединение узла, а то, что ещё
в пути, хранят буферы сокетов ядра.
Схема текстом
- PUSH/PULL: Отправка PUSH берёт следующий по очереди узел; Пишет кадры в соединение этого узла; Буферы сокетов ядра на обоих концах; Приём PULL читает соединения узлов по очереди
- PUB/SUB: Отправка PUB каждому подписчику с совпавшим фильтром; Пишет в соединение каждого из них, одно за другим; Буферы сокетов ядра на обоих концах; Приём SUB читает то, что пропустили фильтры
- Отправка PUSH берёт следующий по очереди узел → Пишет кадры в соединение этого узла: по очереди
- Пишет кадры в соединение этого узла → Буферы сокетов ядра на обоих концах
- Буферы сокетов ядра на обоих концах → Приём PULL читает соединения узлов по очереди
- Отправка PUB каждому подписчику с совпавшим фильтром → Пишет в соединение каждого из них, одно за другим
- Пишет в соединение каждого из них, одно за другим → Буферы сокетов ядра на обоих концах
- Буферы сокетов ядра на обоих концах → Приём SUB читает то, что пропустили фильтры
- Клиент zeromq не держит очереди сообщений: отправка заканчивается, когда кадры записаны
- 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.