Комментарии 16
Спасибо. Было интересно
Иду пробовать VT
А разница большая vt от обычных tomcat'овских потоков?
P.s. не все полностью прочел, возможно об этом написано выше)
Я не сравнивал конфигурацию на Tomcat + VT и Tomcat на обычных потоках. Могу сделать пару прогонов, если интересно.
Сделал прогон POST /v1/menu-orders на Spring MVC без Virtual Threads. В качестве ClientHttpRequestFactory была HttpComponentsClientHttpRequestFactory с параметрами maxConnectionsPerRoute = 200 и maxConnectionsTotal = 200.
Показатели по временам сравнимы с VT и чуть похуже, чем WebFlux p95=49ms p99=141ms
По CPU заметно лучше чем VT или WebFlux 64% CPU.
По памяти также чуть лучше VT или WebFlux 267 MiB heap.
А вот прогон GET /v1/menu-aggregate не удался - примерно на 1700rps GC перестает справляться, heap уходит в полку и приклад перестает отвечать. Пробовал несколько раз, симптомы повторяются. Снижать нагрузку еще больше не стал. В качестве ClientHttpRequestFactory была HttpComponentsClientHttpRequestFactory с параметрами maxConnectionsPerRoute = 200 и maxConnectionsTotal = 200. Попробовал также снизить количество коннектов maxConnectionsPerRoute = 100 и maxConnectionsTotal = 100 - картина та же. Сегодня разбираться уже нет времени, но надо подумать, с чем это связано.
Сравнениюе на самом деле не совсем корректное. Применимость, сложность разработки/поддержки, входа разная у синхронного и асинхронного кода. Поэтому может и нет смысла их сравнивать. Синхронный уместно применять в сложных сервисах, где есть бизнес логика. Если бизнес логики практически нет, но есть потребность выжать максимум из железа, то логично будет применить асинхронный подход. Но тут опять же стоит несколько раз подумать будет ли эта экономия на ресурсах оправдана при возросшей сложности.
А так в целом и так понятно что event loop в лоб всегда будет быстрее работать чем vt.
Бесспорно, сложность разработки и поддержки WebFlux гораздо выше WebMVC, и WebFlux выбирают осознанно. Также я не раз слышал утверждения о том, что WebFlux будет лучше по перформансу, чем виртуальные потоки. Но я придерживаюсь позиции, что лучше проверить, чем просто поверить, тем более, есть над чем ставить эксперименты. И также хотелось понять на сколько VT проиграют WebFlux и в чем, чтобы понимать, есть ли смысл менять сложную парадигму программирования на более привычную с учетом некоторого проигрыша по latency. Ну, и также важно учесть, что WebFlux в некоторых случаях при одинаковой нагрузке потребляет гораздо больше CPU, то есть потребуется горизонтальное масштабирование, а это дополнительные деньги. В общем, как всегда - поиск компромисса, но в этом поиске хочется основываться на цифрах, а не на слухах и ощущениях)
Может тогда прям в статье это отразить? Просто видел проект на работе на webflux на 10 rps. Весь в граблях и костылях. Смотреть на это просто больно. И я кажется знаю почему там взяли webflux, приложение ходило в 3 сервиса по http параллельно.
Но в целом статья хорошая, спасибо!
у меня есть опыт написания подобного сервиса с небольшой нагрузкой, но необходимостью быстро отдать ответ, собранный из нескольких источников. тогда это было оправдано и неплохо работало.
а грабли и костыли в вашем случае говорят скорее о неопытности разработчиков.
Так а в чем проблема просто на тред пулах это сделать было? Каждый запрос на "отдельный поток" отдаёте и получаете тоже самое. На небольшом кол-ве запросов кол-во тредов будет небольшим. Там даже vt не требуются. Если нагрузки нет какой смысл использовать webflux?
спасибо за статью! интересно было бы посмотреть исходный код микросервисов.
ещё вопрос - пробовали ли добавлять трассировку (MDC)? какой это даст оверхед для WebFlux?
вы под linux тестировали? И можете ради интереса прогнать самые тяжелые тесты под Jetty вместо tomcat?
Да, базовый образ контейнеров был на Ubuntu. В целом, думаю, что можно и с Jetty тесты прогнать. Не уверен, что получится оперативно это сделать, но, как сделаю, отпишусь в комменте.
интересно, потому что говорят что Jetty лучше обрабатывает большое количество соединений чем томкат и в этот момент имеет лучшую latency. А netty с версии 4.2 умеет в io_uring под linux, это самый эффективный способ обмена данными с минимальным количеством обращений к ядру. У томката есть какой-то apr native, но это как я понимаю скорее небольшой допинг.

WebFlux vs Virtual Threads: что происходит при 2000 RPS