Оптимизация производительности нагруженных веб-систем на Java Личный опыт и не только Давайте познакомимся • • • • alexander.chistyakov@dataart.com Разрабатываю с 1998-го Разрабатываю на Java с осени 2000-го Кроме разработки, занимаюсь консультированием команд, разрабатывающих веб-приложения • Читаю доклады по оптимизации производительности Вы? • • • • • Разработчики на Java Разработчики веб-приложений на Java? Архитекторы приложений? IT operations engineers? Performance engineers? Почему вебприложения? • У веб-приложений много пользователей • В интернете при решении даже простых бизнес-задач легко столкнуться с большими нагрузками • Интернет большой, и уменьшения числа пользователей не предвидится – в будущем любое успешное веб-приложение будет высоконагруженным Постановка задачи • Что такое «высокая нагрузка»? • Все относительно • Метрики: время обработки запроса и процент успешно обработанных запросов • У приложения нет периодов простоя, вас не будят по ночам – эта презентация не для вас • Метрики неудовлетворительны – надо искать выход Где же выход? • http://ru.wikipedia.org/wiki/Шаманизм • Шаманизм и оптимизация • http://ru.wikipedia.org/wiki/Карго-культ • «Сделаем, как у больших (как у Google)» • «Сделаем, как делал архитектор Вася в прошлом проекте» • «Сделаем, как написано в этом блоге» • Shotgun programming: «Сделаем как-нибудь и посмотрим» – может быть хорошим подходом для начала Если это был не выход... • • • • Путь 1: Наймите консультанта Путь 2: Измеряйте, потом оптимизируйте! Что измерять? Все, до чего можете дотянуться, в первую очередь: • Параметры системы в целом • Параметры вашего приложения Параметры системы • Состояние HDD – IOPS, latency • Состояние оперативной памяти – размер памяти приложений, размер файлового кэша • Состояние CPU – user time, system time • Состояние очереди планировщика – LA • Состояние сетевой подсистемы – количество подключений, объем трафика • Состояние JVM – количество major/minor garbage collections Сбор параметров системы • Java-based: OpenNMS, … - жизнь слишком коротка, других ресурсов тоже мало • Zabbix – если вы работаете в Yandex, или у вас есть время переписать код работы со стат. данными • Munin – требует мало ресурсов и не требует первичной настройки • Cacti – если используете DBMS MySQL • Collectd – требует минимальное количество ресурсов, агент написан на pure C. Параметры приложения • Длительность выполнения разных участков кода приложения • Потребление памяти структурами данных • Частота выделения памяти под новые структуры данных • Можно использовать профайлер • Профайлеры: YourKit, JProfiler, … • Можно использовать другие средства профилирования Недостатки профайлера • Профайлер знает о вашем приложении гораздо меньше, чем вы • Профайлер профилирует каждый вызов • Профайлер может вносить сильную погрешность и даже менять картину в целом • Использование профайлера предполагает предварительное знакомство с ним Другие средства • Отладочная печать – служит разработчикам ПО с 60-х годов прошлого века • Thread stack sampling (kill -QUIT PID) • BTrace – аналог DTrace для JVM • Самостоятельная расстановка вызовов профилирования в коде (вызовы JAMon, запись данных во внешнее хранилище для постобработки, статистическая предобработка) Выбор средств профилирования • • • • Используйте универсальные средства Серебряной пули нет А, поэтому, используйте любые средства Подумайте об интеграции ваших средств профилирования со средствами мониторинга системы • Подумайте о возможности профилирования системы в продакшн режиме Нагрузочное тестирование • Средства создания тестовой нагрузки – ab, siege, JMeter, Tsung • ab и siege – недостаточно настроек • JMeter – кому-нибудь удавалось создать с его помощью нагрузку хотя бы в 400 rps с одного хоста? • Tsung – может работать в распределенном режиме, но довольно капризен Случай из жизни 1 • Tomcat, Spring, MySQL, многонодовая конфигурация в Amazon Cloud • Куплен профайлер • Проблемы под тестовой нагрузкой • Профайлер ничего не показывает Брейндамп решения 1 • Попытка подключить VisualVM (практически провалилась – RMI плохо работает через SSH туннель) • Thread stack sampling в консоли при помощи стандартной утилиты jstack, сброс сэмплов в файл и ручной анализ файла Брейндамп 1 – анализ тред стеков • Много записи на диск (ведутся логи) – изменили уровень логгинга • Потоки стоят на блокировке при обращении к БД – долго выполняются некоторые из SQL-запросов (сами запросы написаны неоптимально) • Проблема вообще не в Java! • (зря покупали профайлер) Случай из жизни 2 • Приложение, написанное в 2002-м году • Weblogic, сервлеты подключенные без использования web.xml, Solaris 8, Oracle, JVM 1.2, часть бизнес-логики в хранимых процедурах и другие радости жизни • Исходного кода приложения нет • Первоначально задачи оптимизации производительности не было, но мне начали звонить по ночам... Брейндамп решения 2 • Сложный путь апдейта JVM до версии 1.5 • Сбор данных о потреблении памяти, сбор данных о поведении GC • Тюнинг Oracle, чтобы он не мешал Javaприложению • Попытка тюнинга GC (ни к чему не привела) • Разные опции запуска JVM, разные версии JVM • Непонятна корреляция между падениями системы и внешними событиями Брейндамп решения 2 - продолжение • Включение access log на время в момент проблемы с доступностью • Корень проблемы – брут-форс подбор логинов и паролей • Внедрение ehcache и временной блокировки по IP на час после 10 неудачных попыток логина в течение 5 минут • Нагрузка исчезла • Бывают такие легаси-системы, в которых все непривычно Случай из жизни 3 • Веб-сайт в Рунете с довольно большой нагрузкой • Resin, JSP, servlets, три физических сервера • RDBMS Firebird • Apache 1.3 как reverse proxy • В моменты пиковой нагрузки проблемы с производительностью вплоть до недоступности серверов, необходим рестарт Брейндамп 3 • Команда консультантов поделилась на две части • Одна часть – «сисадмины» зачем-то настраивала mod_accel • Вторая часть пыталась разбираться с Java и Firebird • Анализ Firebird показал, что с ним все в порядке и улучшить что-либо существенно нельзя Брейндамп 3 продолжение • Попытка построить тестовое окружение и профилировать приложение под YourKit • Профайлер не показал узких мест на том шаблоне нагрузки, который был применен для тестирования • Добавление в код приложения печати отладочной информации в лог • Несколько падений системы на глазах команды, время восстановления после рестарта по 3.5 часа – разогрев кэшей Брейндамп 3 приложение • Анализ отладочной информации из лога показал узкое место • Анализ кода выявил доступ к базе в synchronized блоке • Сужение области действия synchronized блока (разбили на два блока) привело к уменьшению времени разогрева кэша до нескольких минут • Используйте lock-free структуры данных • Не используйте Firebird! Выводы • Невозможное возможно • Накапливайте и используйте факты и знания о вашей системе, не пользуйтесь религиозными представлениями примитивных сообществ • Сложные и дорогие инструменты часто ничем не лучше простых и бесплатных Вопросы? • • • • Спасибо за внимание! • • • • • Alexander Chistyakov, DataArt alexander.chistyakov@dataart.com http://alexclear.livejournal.com https://github.com/alexclear Enjoy IT!