Поток котировок - антипод обычного API: данные летят непрерывно, подписчиков тысячи, и каждому нужна не история, а текущее состояние. Раздача такого потока - отдельная инженерия, и на собеседованиях в трейдинг её спрашивают как систему из трёх решений: транспорт, восстановление, защита от медленных.
Транспорт: по границе сети
Внутри дата-центра и между близкими узлами - мультикаст поверх UDP: источник отправляет один поток, а сеть сама размножает пакеты подписчикам. Никакого дублирования на сервере, никакой отдельной отдачи каждому - это единственно масштабируемо на тысячи получателей.
Наружу, через публичный интернет, мультикаст не проходит: провайдеры его не маршрутизируют. Внешним клиентам поток отдают по WebSocket поверх TCP - с последствиями этого выбора (надёжность есть, но и голова очереди может расти), поэтому в паре с ним всегда живёт conflation.
Восстановление: снапшот плюс инкременты
UDP теряет пакеты - поток строят так, чтобы потеря была восстановима:
- Подписчик получает снапшот текущего состояния по инструменту - точку отсчёта.
- Дальше летят только инкременты - изменения с монотонными номерами последовательности.
- Обнаружив пропуск номера, подписчик понимает: состояние могло разъехаться - и перезапрашивает снапшот заново.
Схема «снапшот + инкременты» - базовая для любого потока состояния, не только биржевого: так работают и live-обновления в веб-приложениях, и синхронизация документов.
Медленный подписчик: conflation
Один клиент читает медленнее, чем летит поток. Его исходящая очередь растёт - память кончается, и один медленный способен положить раздачу всем. Лечение - conflation (coalescing): медленному клиенту отправляют не всю пропущенную историю, а только последнее актуальное состояние по каждому инструменту. Ему важна текущая цена, а не каждый промежуточный тик.
В связке работают backpressure и лимиты на клиента: очередь превысила порог - старые обновления по тому же ключу сворачиваются, а не копятся; клиент совсем не справляется - отдаются только снапшоты с пониженной частотой или отключается с явным кодом.
Что запомнить
- Внутри периметра - мультикаст UDP, наружу - WebSocket с conflation.
- Поток = снапшот + инкременты с номерами; пропуск - повод перезаказать снапшот.
- Conflation сворачивает отставание до последнего состояния по ключу: медленному нужна цена, а не история тиков.
- Лимиты и backpressure защищают раздачу от одного медленного клиента.