Java — Это Не Только Кровавое Предприятие, Но И Быстрые, Чувствительные К Задержкам Приложения.

Я занимаюсь алгоритмической торговлей в Райффайзенбанке.

Это довольно специфическая область банковской сферы.

Мы создаем торговую платформу, которая работает с низкой и предсказуемой задержкой.

Успех приложения зависит, в том числе, от скорости работы приложения, поэтому нам приходится иметь дело со всем стеком, участвующим в трейдинге: каналы частной сети, специальное оборудование, настройки ОС и специальная JVM, и, конечно же, само приложение.

Мы не можем остановиться на оптимизации самого приложения; Настройки ОС или сети не менее важны.

Это требует технических знаний и эрудиции, чтобы понять, как данные проходят через весь стек и где могут возникнуть задержки.



Java — это не только кровавое предприятие, но и быстрые, чувствительные к задержкам приложения.
</p><p>

Не каждая организация/банк может позволить себе разработку такого класса программного обеспечения.

Но мне повезло, что такой проект был запущен в стенах Райффайзенбанка, и у меня была подходящая специализация — я специализировался на производительности кода в Московской компиляторной лаборатории Intel. Мы сделали компиляторы для C, C++ и Fortran. В Райффайзенбанке я перешел на Java. Если раньше я делал какой-то инструмент, которым потом пользовались многие люди, то теперь я перешёл на другую сторону баррикад и занимаюсь прикладным анализом производительности не только кода, но и всего стека приложений.

Обычно путь к исследованию проблемы производительности лежит далеко за пределами кода, например, в настройках ядра или сети.



Java не для хайлоада?

Распространено мнение, что Java не очень подходит для разработки высоконагруженных систем.

С этим можно согласиться лишь частично.

Java великолепна во многих отношениях.

По сравнению с таким языком, как C++, он потенциально может иметь более высокие накладные расходы, но иногда функционально аналогичные решения на C++ могут работать медленнее.

Существуют оптимизации, которые автоматически работают в Java, но не работают в C++, и наоборот. Глядя на качество кода, который выходит из JIT-компилятора Java, хочется верить, что производительность будет не более чем в несколько раз хуже той, которую я мог бы достичь на пике.

Но при этом я получаю очень быструю разработку, отличные инструменты и широкий выбор готовых компонентов.

Давайте посмотрим правде в глаза: в мире C++ среды разработки (IDE) значительно отстают от IntelliJ и Eclipse. Если разработчик использует любую из этих сред, то скорость отладки, поиска ошибок и написания сложной логики на порядок выше.

В результате оказывается, что проще подправить Java в нужных местах, чтобы она работала достаточно быстро, чем делать все с нуля и очень долго на C++.

Самое интересное, что при написании параллельного кода подходы к синхронизации и в Java, и в C++ очень похожи: это либо примитивы уровня ОС (например, синхронизировано/std::мьютекс ) или железные примитивы ( Атомный*/std::атомный<*> ).

И очень важно увидеть это сходство.

И вообще, мы не разрабатываем высоконагруженное приложение))

В чем разница между приложением с высокой нагрузкой и приложением с низкой задержкой?

Термин highload не полностью отражает специфику нашей работы – мы занимаемся именно чувствительные к задержке системы .

Какая разница? Для высоконагруженных систем важно в среднем работать достаточно быстро, полностью используя аппаратные ресурсы.

На практике это означает, что каждый сотый/тысячный/.

/миллионный запрос к системе потенциально может работать очень медленно, поскольку мы ориентируемся на средние значения и не всегда учитываем, что наши пользователи существенно страдают от замедлений.

Мы работаем на системах, для которых уровень задержки имеет решающее значение.

Наша задача — сделать так, чтобы система всегда имела предсказуемый ответ. Потенциально чувствительные к задержке системы может быть не сильно загружен, если события происходят достаточно редко, но требуется гарантированное время отклика.

И это не облегчает их развитие.

Наоборот! Опасности подстерегают повсюду.

Подавляющее большинство современных аппаратных и программных компонентов рассчитано на хорошую работу «в среднем», т.е.

пропускная способность .

Возьмем, к примеру, структуры данных.

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

Или JIT-компилятор — оптимизирует наиболее часто исполняемый паттерн кода, пессимизируя редко исполняемый паттерн кода.

Но скорость в этом конкретном редком случае может быть для нас очень важна! Может быть, этот код обрабатывает редкий тип заказов? Или какая-то необычная рыночная ситуация, требующая быстрого реагирования? Мы стараемся, чтобы реакция нашей системы на эти потенциально редкие события занимала какое-то предсказуемое и, желательно, очень короткое время.



Как добиться предсказуемого времени ответа?

На этот вопрос невозможно ответить в двух предложениях.

В первом приближении важно понять, есть ли синхронизация — синхронизированный, повторный вход или любой из java.util.concurrent .

Часто приходится использовать синхронизацию на занятых вращениях.

Использование любого примитива синхронизации всегда является компромиссом.

И важно понимать, как работают эти примитивы синхронизации и какие компромиссы они приносят. Также важно оценить, сколько мусора генерирует конкретный фрагмент кода.

Лучший способ справиться со сборщиком мусора — не запускать его.

Чем меньше мусора мы создаём, тем реже мы будем запускать сборщик мусора и тем дольше система будет работать без его вмешательства.

Также мы используем широкий спектр различных инструментов, которые позволяют нам анализировать не только средние показатели.

Нам приходится очень тщательно анализировать, насколько медленна система, каждый сотый, каждый тысячный раз.

Очевидно, что эти показатели будут хуже медианного или среднего значения.

Но нам очень важно знать, насколько.

И такие инструменты, как, например, помогают это показать Графана , Прометей , HDR-гистограммы И ДМХ .



Можно ли удалить Unsafe?

Часто приходится использовать то, что апологеты называют недокументированным API. Я говорю о знаменитом Unsafe. Я считаю, что unsafe стал де-факто частью общедоступного API-интерфейса Java-машины.

Нет смысла это отрицать.

Unsafe используется во многих проектах, которыми мы все активно пользуемся.

А если мы откажемся, то что будет с этими проектами? Либо они останутся на старой версии Java, либо им придется снова потратить немало усилий, чтобы все это переписать.

Готово ли к этому сообщество? Готов ли он потенциально потерять десятки процентов производительности? И самое главное, в обмен на что? Косвенно подтверждает мое мнение очень аккуратное удаление методы из Unsafe — в Java11 были удалены самые бесполезные методы из Unsafe. Я думаю, пока хотя бы половина всех проектов, использующих Unsafe, не перейдут на что-то другое, Unsafe будет доступен в той или иной форме.



Бытует мнение: Банк + Ява = кровавое закостеневшее предприятие?

В нашей команде таких ужасов нет. На Spring мы, наверное, написали десять строчек, да и я)) Стараемся не использовать большие технологии.

Мы предпочитаем делать что-то маленькое, аккуратное и быстрое, чтобы иметь возможность его распознать, контролировать и при необходимости модифицировать.

Последнее очень важно для систем (таких как наша), имеющих нестандартные требования, которые могут отличаться от требований 90% пользователей фреймворка.

И если мы будем использовать большой фреймворк, мы не сможем донести свои потребности до сообщества или самостоятельно скорректировать поведение.

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

Я пришел в мир Java из C++ и меня очень поразило разделение сообщества на тех, кто занимается разработкой.

время выполнения виртуальная машина/компилятор или сама виртуальная машина и разработчики приложений.

Это хорошо видно в коде стандартных классов JDK. Часто авторы JDK используют другой API. Потенциально это означает, что мы не сможем достичь максимальной производительности.

В целом я считаю, что использование одного и того же API для написания как стандартной библиотеки, так и кода приложения — отличный показатель зрелости платформы.



Что-то другое

Я думаю, всем разработчикам очень важно знать, как работает если не весь стек, то хотя бы его половина: Java-код, байт-код, внутренности среды выполнения и ассемблера виртуальной машины, аппаратное обеспечение, ОС, сеть.

Это позволяет взглянуть на проблемы шире.

Стоит также упомянуть производительность.

Очень важно не сосредотачиваться на средних значениях и всегда смотреть на медиану и высокие процентили (худшее из 10/100/1000/… измерений).

Обо всем этом я расскажу на Встреча группы пользователей Java 30 мая.

В Санкт-Петербурге.

Встреча с Сергеем Мельниковым, это я)) Зарегистрироваться можно на сайте связь .

О чем мы будем говорить?

  1. О профилировании и использовании стандартного профилировщика Linux и perf: как с ними жить, что они измеряют и как интерпретировать их результаты.

    Это будет введение в общее профилирование с советами и лайфхаками о том, как максимально эффективно использовать возможности профайлеров, чтобы они профилировали с максимальной точностью и частотой.

  2. Об особенностях оборудования для получения еще более детального профиля и просмотра профиля редких событий.

    Например, когда ваш код каждый сотый раз работает в 10 раз медленнее.

    Ни один профайлер вам об этом не скажет. Мы напишем свой небольшой профилировщик, используя стандартный механизм ядра Linux, и попробуем посмотреть профиль какого-нибудь редкого события.

Приходите на встречу, это будет отличный вечер, будет много интересных историй о нашей платформе и нашем любимом языке.

Увидимся ;) Теги: #Высокая производительность #java #производительность #raiffeisenbank #raiffeisenit

Вместе с данным постом часто просматривают:

Автор Статьи


Зарегистрирован: 2019-12-10 15:07:06
Баллов опыта: 0
Всего постов на сайте: 0
Всего комментарий на сайте: 0
Dima Manisha

Dima Manisha

Эксперт Wmlog. Профессиональный веб-мастер, SEO-специалист, дизайнер, маркетолог и интернет-предприниматель.