metaclass: (Default)
metaclass ([personal profile] metaclass) wrote2016-08-03 03:33 pm

"Асинхронный" http api

Вчера был на тусовке junolab, где их главные гуру рассказывали, как у них бекенд устроен.
В частности, на входе у них стоят гейтвеи с обычным http протоколом и минимальным набором фич - валидация, проверка авторизации по токенам и прочее такое, которые перекидывают запрос в MQ (nats.io).

При этом, насколько я понял, асинхронность там реализована поверх обычного http, без всяких http2, веб-сокетов и прочих не везде работающих протоколов - т.е. клиент api сначала делает запрос к гейтвею, ему сразу говорят - 200 ок, а потом он должен, по идее, дальше опрашивать гейтвей, пока для него из MQ придет ответ от микросервисов. Или у них там ответы от сервера бесконечно идут, я сходу не понял (т.е. ответ без content-length и соединение просто ждет пока придет что-нибудь, не помню, как эта техника называется).

В принципе, если keep-alive и соединение не обрывается - то реализация дуплексного протокола поверх синхронного http вроде приемлемая. Единственное, что в случае бесконечного ответа - если сервер и клиент долго ничего друг другу не говорят - промежуточные NAT и прочая сетевая муть могут соединение забыть, причем пока TCP keep-alive не проснется (а это два часа по умолчанию, вроде) - это обнаружено той стороной, которая молчит и ждет, не будет. Но теоретически это какие-то heart-beat слать можно со стороны сервера и запросы со стороны клиента.

[identity profile] falcrum.livejournal.com 2016-08-03 12:42 pm (UTC)(link)
Гм, "200 ок" - это "сообщение принято"? А в случае битого сообщения, которое не разобрать - что должен клиент дожидаться в ответе?

[identity profile] http://users.livejournal.com/_slw/ 2016-08-03 12:45 pm (UTC)(link)
это можно сделать двумя коннектами на тупом http/1.0:

по одному урлу получаем ответы, там клиент делает запрос "дай штонибудь, я такой-то!" и ждет до усрачки, у сервера тймаут минут в 15. если ничего нет -- он скажет через 15 минут "нет ничего", клиент переспросит.

кажется это называется long poll mode

по второму урлу клиент срет запросами, сервер сразу отдает queue id, по которому с первого урла будет получен результат.
тут все обычно.

даже кипалив нигде не нужен.

[identity profile] filonov.livejournal.com 2016-08-03 01:09 pm (UTC)(link)
Chunked Encoding вполне позволяет отдать 200 ok и потом кормить данными потихоньку.

не совсем так

[identity profile] wildman.livejournal.com 2016-08-03 01:37 pm (UTC)(link)
> т.е. клиент api сначала делает запрос к гейтвею, ему сразу говорят - 200 ок, а потом он должен, по идее, дальше опрашивать гейтвей, пока для него из MQ придет ответ от микросервисов.

в общем случае:
- между клиентом и сервером постоянно (до траблов в сети, обрыва, окончания авторизированной сессии) висит HTTP persistent connections (HTTP keep-alive) == stream
- клиент api сначала делает запрос к гейтвею, ему сразу (после минимальных телодвижений по обеспечению персистента если оно нужно) говорят - 200 ок
- через некоторое время в stream прилетает ответ по запросу (json c `\n` терминаторами)

по этому каналу у нас для надежности раз в секунду летает `\n` (сделано и на уровне gateway и на уровне клиента в зависимости от направления стрима)

в сумме - у нас и клиенты и сервер считают что работают по асинхронному дуплекс каналу. транспортные проблемы изолированы по коду до состояния что переход на любой другой вариант (http2, websockets, raw tcp socket, etc.) затронет до сотни строк в фреймворке на бэкенде и по такому же кусочку в клиентах
Edited 2016-08-03 14:48 (UTC)

[identity profile] juan-gandhi.livejournal.com 2016-08-03 03:20 pm (UTC)(link)
Два часа как-то не звучит реалистично для человеческого интерефейса.

Идейка так-то хороша, но ведь по жизни уже все так делают. Никто не ждет "списка всех юзеров".

[identity profile] vp.livejournal.com 2016-08-03 06:41 pm (UTC)(link)
Меня больше интересует, есть ли сегодня какие-то реальные препятствия для работы веб-сокетов, с учетом, что сервер у нас всегда сервер, а клиенты у нас мобильные. Т.е. не строят ли операторы какие-то козни по противодействию этому.
Потому что все-таки это лучше делать веб-сокетами.

[identity profile] sergiej.livejournal.com 2016-08-08 07:55 pm (UTC)(link)
Мне казалось это стандарт давно. Два коннекшна, на одном запрашиваем чего нужно, на втором всё время читаем поток ответов. Регулярно "передёргиваем" если долго ничего не просили или не получали. Масса мессенджеров и нотификаторов всяких так работает.