Pull to refresh

Comments 36

Vert.x сейчас находится в зачаточном состоянии и позиционируется как фреймворк для построения реактивных приложений и микросервисов. Естественно он чуть более чем полностью обёртка поверх Netty, а HA класстерные решения строятся поверх Hazelcast'a. Нужно обратить внимание на наличие автоматической кодогенерации, которая генерит Ruby / Groovy / JS API на основе существующих аннотаций Java API, т.е. в первую очередь это мультиязычное решение.

По поводу «Direct-буферов» — Netty имеет свой Arena-аллокатор на подобие того что используется в jemalloc, и самостоятельно производит менеджмент offheap'a.

А я сижу, пишу асинхронный PostgreSQL коннектор на vert.x'e :3 который можно было бы использовать в более-менее продакшенах.
Netty смотрится хорошо на тестах. Мне не приходилось с ней работать но как я понел вам было не совсем просто написать на этом проложения которое берет сообщения с одного сокета и ложет в другой. Есть другие асинхроные более простые решения. Это и Node.js не очень быстрый но дешевый в плане разработки. Есть GO у которого все IO асинхроные и код простой синхронный. Язык быстрый и нет всяких заморочек. Я сам переписывал решение одно с Node.js на GO. Там логики по больше и редис и монго но сейчас это обрабытывает 1350 HTTP в секунду 3 сервера(меньше двух не ставим и так) по 4 ядра. Думаю с TCP это бы работало не хужею чем Netty. Вопрос стоило ли заморачиватся с Netty?
Думаю с TCP это бы работало не хужею чем Netty.
Перечитывал несколько раз, так и не понял что подразумевалось. Всё остальное golang/node.js успешно дохнет на 15-20К запросов, «на всех ядрах».

Вопрос стоило ли заморачиватся с Netty?
Стоит, в первую очередь из-за производительности. Если вы не строите приложений критических к скорости обработки запросов, и вам 5ms погоды не сделают — понятное дело можно использовать что-то проще. C Netty, при правильной допилке, можно выжать под 150-200K запросов на ядро с задержками в 2-3ms. Естественно для большей части простых обывателей подобные вещи бесполезны.

А вообще, сетевых библиотек с нормальным offheap'ом в природе больше замечено не было.
C Netty, при правильной допилке, можно выжать под 150-200K запросов на ядро


Может поделитесь опытом, о какой допилке речь? У меня больше 20к рек-сек на ядро никак не полуачалось и это было без SSL.
мне тоже интересно как получить 200K на ядро с 2-3ms. Как машина справляется с таким количеством сокетов?
Цифры с в студию тесты и так далее а то я тоже могу писать 200K
Перво-наперво нужно подтюнинговать JVM.
По хорошему — желательно вообще вырубить GC и использовать Disruptor, но я до такого сам не доходил, хотя были примеры из жизни и довольно позитивные отзывы. Я обычно выставляю выставляю низкий размер новых генераций для GC и максимальное переиспользование существующих. Как минимум, нужно поменять дефолтную реализацию hashcode что бы не было зависимости от размера пула энтропии — это уже даст довольно большой прирост производительности. Всё остальное — тюнинг ядрышка, нужно тюнинговать виртуальную память, что бы можно было запить больше файловых дескрипторов, ну там увеличить размер mmap/munmap'a посредством увеличения vm.max_map_count, после чего уже можно увеличивать всё остальное. Ещё можно увеличить количество ipv4 сокетов net.ipv4.ip_local_port_range, что иногда может приводить к довольно странным последствиям, и fs.epoll.max_user_watches для увеличения количества событий в epoll'e. Для обхода ограничения по количеству сокетов можно ещё маркировать пакеты, только «руками» без netfilter'a, и рассылать их по нескольким процессам — это позволит дублировать дескрипторы. Может чего и забыл, но я сейчас не особо то и слежу за текущим состоянием VM'a и сетевых плюшек в линуксе — переехал на более приземлённые задачи.

Очень желательно использовать netmap или dpdk для мапинга памяти.
Я писал как-то dpdk маппер для одного проекта, но заопенсорсить я его не могу по понятным причинам.

p.s. 200K на ядро это я ещё помелочился :3 — можно гораздо больше.
Для того, чтобы отрубить GC придется очень постараться, да и disruptor не серебряная пуля. Не совсем понял как поможет низкий размер new generation, да и с hashcode не понятно. Уточните пожалуйста как они помогают?

P.S. главное тут все же по моему мнению это тюнинг ядра
1. Есть много примеров контор которые действительно гоняли OpenJDK без сборки мусора — патчили System.gc(), хотя я не приветствую такой способ и считаю его большим костылём с ещё большими рисками. Как и почему нужно тюнинговать GC можно глянуть в презентации Рогозина, так же у него был хороший CheatSheet.
2. Disruptor помогает в реализации стратегии «Share Memory By Communicating» — не нужно заморачиваться с пулами объектов и multiton'ами, размерами очередей сообщений в разнообразных вариациях модели актёров.
3. Hashcode по умолчанию использует псевдослучайную генерацию хешей, которая быстро истощает пул энтропии в системе. По этому такие вещи как Haveged могут увеличить производительность виртуальной машины, но делают её random предсказуемым. Даже банальное Android приложение в 4.4 при замене дефолтного hashcode работает в 1.5-2 раза шустрее, по моим личным наблюдениям.

Тюнинг ядра сводится к увеличению размера mmap'a что влияет на максимальное количество дескрипторов (сокетов) в системе в целом, всё остальное — это увеличение epoll пула и обоюдный тюнинг TCP стэка, влияние на производительность которого не сравнимо ни в каких рамках с overhead'ом виртуальной машины.

dpdk / netmap нужны для того чтобы обойти netfilter и лишние memcpy для сетевых буферов.

Понятное дело что тут есть много «но», и большую часть «кусков» приложения нужно правильно профилировать под нагрузкой — подобные рассуждения и скептицизм не очень то и конструктивны.
1. О таких конторах мы наслышаны. Проще сделать для serial gc большой хип и делать перезапуски приложения, когда его никто не использует. Для выпиливания gc нужны адские средства, на мой взгляд проще тогда переписать на c++
2. Ну disruptor вроде как не представляет api для работы с пулами(этоже просто кольце кольцевой буфер). Замарочится скорее всего придётся.
3. Если есть пул объектов наверное и не проблема вообще, ибо hashcode вычислить нужно один раз при создании объекта.

P.S. А сколько сетевых интерфейсов на вашем сервере была если не секрет?
1. Приложение обновить/перезапустить можно только в горячую, и то не всегда. Задержка на перезапуск обычно не может быть больше 7-10ms. Обычно использую 1G. Для выпиливания GC нужен патч в 300 строчек С++.
2. Если в этом самом кольцевом буфере выделять статические объекты для работы с различными сущностями — отпадает потребность в реализации пулов и мультитонов, но это требует специфического подхода в разработке, и позволяет один раз выделить память «под всё» и полностью остановить сборку мусора.
3. На самом деле время вычисления hashcode может быть в 2-3 раза более ресурсоёмко нежели создание самого объекта и выполнения нужного кода, и для абстрактных Netty в вакууме его реализация без псевдо-случайностей часто бывает на много шустрее.

4 канала по 40ГБит на 4ёх Virtex7 картах :|
Половина оптимизаций не имеет отношение к Netty. Все оптимизация ядра помогут любой платформы. Работать без GC продакшине не hello world как то не очень.
Я и не предлагаю всем вподряд вырубать GC.
Эм, ну бэнчмарк малость неактуален и «туговат».
Нету ничего странного что при upstream'e на TCP'шном сокете производительно в 1.5-2 раза падает, но подобные бэнчмарки непосредственно к производительности самого golang'a отношения не имеют, хотя бы из-за «100 потоков по 500 соединений» и радости от 17-120ms задержек на древнем 1.2 runtime. А сабж вообще о нецелесообразности использования nginx балансера поврех golang'a, что вообщем-то должно быть совсем «как бы кэп» очевидно.

В общем я и не думаю что мне стоит здесь так распинаться по поводу производительности, которая в 99% случаев никому не нужна.
Буду в очередной раз оскорблять чувства «верующих» и читать разнообразные бесполезности.

Попробуйте аргументировать свой скептицизм и разобраться в личных целях подобных комментариев.
Фраза по поводу «серебряной пули» мной расценена как психологическая проекция.
Ну если уж выбирать решение вне ява мира, то для этой задачи идеально подойдет Erlang =). Но так как весь мой опыт — это java, я не рискнул идти другими путями. Да и на том этапе важно было сделать хоть какое-то решение и как можно быстрее.
Если сравнивать высокую доступность — тут у Erlang'a есть преимущество, так как в нём почти всё в Beam машине написано с использованием wait-free (но не lock-free) алгоритмов. Если сравнивать по производительности — она ниже плинтуса, так что для задач посложнее memcpy он не очень то и подходит. А в «дикой природе» получается так что гораздо проще прикрутить ту же Akka и, при правильной допилке, получить ту же производительность — это касается любых проектов которые отправляют что-то сложнее HelloWorld по Http.

Жду когда допилят порт erlang'a под llvm.
но ниже я расскажу, как этого максимально избежать.

Так все-таки расскажете? :)
Да, конечно. Чуть позднее. Сейчас как раз имплементирую это для нашего продакшена =).
Ого!
Этот проект явно тянет на отдельную статью, а то и не одну.
Хмм…
Хотелось-бы почитать статью, однако РКН блочит этот домен.
Есть-ли у вас статья на альтернативном ресурсе?

P.S. Про VPN знаю, умею, но сейчас в командировке с чужим планшетом.
Cначало я написал сюда. Но тут меня забанили =). Так что я теперь не рискую публиковать информацию о проекте.
Смотрел. Я прогуглил все популярные решения на тот момент. Но если MQTT используется очень часто, то CoAP я вообще не встречал. Даже теперь. Спустя 6 мес. после запуска. Вообще как показала наша практика — людям всеравно, что вы реализуете на низком уровне и какие протоколы используете, если работает хорошо и проект решает реальную проблему. Даже не смотря на тот факт, что наш продукт исключительно для железячников.
Спасибо, меня интересовала как раз критика и основную причину я уловил. Но может еще что-то? Интерес не праздный, я пишу систему, использующую CoAP для зарубежного клиента (телеметрия/управление). Мне довольно таки понравился сам протокол и его реализация — Californium (не идеал, но вполне годно). Правда, до внедрения еще не дошли, так что основные грабли наверняка еще впереди)
Тут не подскажу. Я лишь поверхностно ознакомился с ним. Могу по MQTT только рассказать. Несмотря на то, что это довольно популярный протокол, многие железячники его недолюбливают (по крайней мере сложилось такое впечетление при общении с американцами, когда мы презентовали Блинк). Основная причина — туда заложили всего и вся на все случаи жизни, хотя в реалных кейсах надо лишь 20%.
UFO just landed and posted this here
Альтернативу чему? У нас решения для мобильных устройств. Облако — это побочный продукт =).
Похвально, в нужном направлении работаете! Раз уж тема java, поделюсь ссылкой на kura и iot.eclipse.org, может кому окажется полезно
UFO just landed and posted this here
Кстати, книга уже устарела. В нетти много чего поменялось с тех пор. Ну и на некоторые вопросы там всеравно нету ответов =). Хотя судя по всему это пофиксят в следующей книге.
В своё время тестировал Grizzly. Очень понравилась штука. Используется насколько я понимаю в GlassFish. По сравнению с нетти более понятный API.
Sign up to leave a comment.

Articles