Как стать автором
Обновить

Комментарии 12

Команда НТ у вас отличная
+ детальные метрики и логи)
Использование метрик Reactor Netty вместе с профилированием показали, что на криптографию уходила уйма времени, поэтому мы перешли с JDK SSL на Open SSL. Это в 2 раза ускорило приклад.


можно, пожалуйста, поподробнее вот этот момент описать?
VPS со всеми сервисами по всем протоколам взаимодействует с TLS/mTLS. В момент профилирования заметили, что JDK SSL генерит много объектов byte[]. Перешли на OpenSSL(BoringSSL если быть точным, форк). В первом случае на массивы (а они были в топе) аллоцировалось суммарно 9.82 Gb, во втором — 2.74Gb, да и по процу нагрузка снизилась процентов на 30. По метрике handshake time Netty сервера тоже было заметно улучшение. В нее только включена как блокирующая часть (криптография на твоей стороне), так и ожидание ответа от второй.

Netty сам увидит имплементацию и будет использовать вместо JDK-шной:
api "io.netty:netty-tcnative-boringssl-static"
а почему бы не оставить TLS Ingress/NGINX'у, а внутри гонять незашифрованный трафик?
В данном случае накладывается специфика банковской деятельности и обеспечения безопасности.
— трудности с незакрытыми соединениями, приведшими аж к анализу трафика через WireShark и в результате оказалось, что Reactor Netty по умолчанию не умеет в таймауты
— своя подпорка для обхода работы с пулами соединений по умолчанию
— удобное программирование реактивности через fluent цепочек настолько дорого, что приходится заталкивать всё в один обработчик
— .groupBy и .flatMap в WebFlux написаны так, что течёт память и останавливается обработка сообщений
— ...


И при этом в качестве итогов вы пишете, что «Reactor Netty – удобен, гибок и быстр. », а в Spring WebFlux можно обрабатывать события с «витиеватой логикой с нелинейной обработкой и ветвлениями».

В статье перечислено довольно много проблем возникших в процессе реализации и не самых лёгких для решения проблем. Честно говоря, увидев обещание трудностей с fluent цепочками и «оригинальными» решениями WebFlux столь базовых вещей как groupBy, я бы три раза задумался перед тем, как брать его в работу — совсем не интересно терять удобство и строить патчи вокруг WebFlux, если только это не компенсируется ну очень большими плюсами.

pprriisstt, после всех этих приключений, вы всё ещё считаете Netty + WebFlux хорошим выбором или сожалеете, что не было времени/желания изучить возможные альтернативы подробнее? Или есть какие-то гигансткие плюсы у этого решения? Например, может быть производительность рвёт конкурентов настолько сильно, что вы готовы мириться с трудностями?
On a small scale, it does not matter what you use: everything works.
On a large scale, it does not matter what you use: nothing works.
The devil is in the middle.

Доброе пожаловать в мир высоких нагрузок. Чтобы получить соразмерную прозводительность без реактивного фреймворка, придётся либо городить сложную инфраструктуру, либо писать относительно низкоуровневый код. В обоих случаях горя придётся хлебнуть не меньше.
Желание реактивности понятно, если клиенты приходят многими тысячами, но ведь не одним же WebFlux живы. Лично я не работал ни с RxJava, ни с Akka, ни с Vert.x, но ТС наверняка ведь выбрал WebFlux не просто подкидыванием монетки, вот и интересно пришёл ли бы он снова к WebFlux, если бы пришлось выбирать заново.

Да и реактивность ради возможности тысяч и десятков тысяч соединений ценой сложности отладки несинхронного кода выглядит весьма интересным вопросом, которым скорее всего задавался ТС.
> придётся либо городить сложную инфраструктуру
Подозреваю, что ТС тоже о таком задумывался и было бы очень интересно узнать результаты размышлений (или даже экспериментов)?

Скажем, если реактивность в случае ТС даёт выигрыш не в двадцать раз по количеству быстро обслуживаемых соединений, а в два-три раза, то не дешевле было бы просто поднять две-три копии сервиса (возможно на той же физической коробочке) а нагрузку выравнивать лоад балансером и парой сервисов очередей?

Инфраструктура была бы сложнее, но ничего запредельно сложного + возможность жить при части упавших инстансов как приятный побочный эффект, а отлаживать синхронный код было бы заметно проще. Конечно же это всё — спекуляции без погружения в подробности проекта — вот и интересно было бы узнать мысли pprriisstt об этом.
У нас Akka. Первая версия нашего сервиса была написана на Python и вопрос масштабируемости решался как раз запуском большего количества экземпляров. Но куча внешних интеграций и некоторые относительно требовательные к ресурсам задачи привели к сложной и дорогой инфраструктуре. Сначала мы перешли к написанию асинхронного кода на Scala Java, потом подключили Akka и продолжаем наращивать её применение в проектах. Да, это требует большей квалификации от разработчиков, но повысило производительность, снизило зависимость от инфраструктуры, снизило расходы и самое главное — увеличило гибкость системы. Теперь любые изменения, будь то хоть изменения API Банка или ФНС, хоть изменения требований бизнеса, хоть что ещё, больше не вызывают желания удавиться.

Относительно же выбора Spring WebFlux в SberDevices наш опыт тоже подсказывает причину — нанять спрингового разработчика на мнооого проще, чем для любого другого реактивного фреймворка.
у меня по этому поводу мнение простое: если ваши задачи на 100% выражаются в терминах операторов Reactor/RxJava/etc, то соответствующий фреймворк использовать намного удобнее, чем городить свой огород. Reactor в этом смысле впереди всех, т.к. несколько лет назад с подачи Pivotal наимплементили очень много этих операторов. Да, далеко не все из них реализованы оптимально, но проект очень даже живой и найденные ошибки быстро исправляются (если вы не исправите их раньше сами). С т.з. среднего разработчика лучше заплатить небольшую цену за неоптимальность работающей реализации, чем собирать все грабли (которых в реактивщине очень много), пытаясь написать какое-то подобие нужного оператора самостоятельно.
Научиться тестировать свои конструкции из существующих операторов куда проще, чем научиться писать их самостоятельно.

Спасибо за статью!
Вопрос по "Reactor Netty: а жив ли клиент?"
Как пришли к именно этому решению? Сами изучив API или где-то искали решение? Может тикет в спринг завели? Есть ощущение, что проблема может быть актуальна не только для вас

Зарегистрируйтесь на Хабре, чтобы оставить комментарий