thinkjavakharkiv#1 Шеф, все пропало. Проблемы с production
TRANSCRIPT
ШЕФ, ВСЕ ПРОПАЛОПроблемы с Production
Антон СеманикВладимир Малинин
О докладчиках
Антон СеманикNix Solutions Ltd.
Java Developer, Group LeadLegacy code fan =)))
Владимир МалининNix Solutions Ltd.
Java Developer, Group Lead
С чего всё начинается?
Рано или поздно разрабатываемое нами приложение попадает на Production…
И именно в этот момент начинается всё самое интересное:
Другая среда…
Другие нагрузки…
Реальные пользователи…
Проблема:• Приложение регулярно падает• Заказчики бьют тревогу• Сроки поджимают• В чем проблема не понятно• Все пропало!
Что мы имеем на входе?Обычно не очень детальное описание проблемы от заказчиков, но с требованием поправить и поскорее.
…надцати мегабайтный файл с логами за последний месяц (если повезёт, то за день).
Мысль о том, что это происходит явно не по нашей вине.
Что же делать в таком случае?Существует как минимум два варианта:
• Поддаться общей панике и идти искать решение в Google, надеясь на удачу;
• Провести детальный анализ приложения в поисках проблемы.
Следуя по пути анализа, нужно:
• Попытаться воспроизвести поведение локально;• Проанализировать логи приложения;• Поискать проблемы в коде;• Посмотреть на работающее приложение изнутри
используя профилировщик;• Собрать статистику потоков / памяти / соединений к
базе.
Какие инструменты нам могут помочь?Профилировщики:• jconsole •VisualVM• Jprofiler•YourKit
Более продвинутые средства:• JavaMelody
Ограничения профилировщиков• Невозможно держать его открытым 24
часа в сутки 7 дней в неделю, не всегда доступны требуемые порты на сервере
• Невозможно предсказать когда в приложении возникнет проблема
• Для сбора статистики нужно изобретать дополнительные грабли
Рассмотрим проблему на примере реального проекта:С регулярностью ~2 недели с приложением начинались проблемы:
• Статические страницы отдавались сервером без проблем• Все страницы запрашивающие информацию из базы
отдавались сервером как 504 Gateway Timeout
Конфигурация приложения:
Spring 3Hibernate 3.5BoneCP 0.8
СУБД MySQL
Apache tomcat 6 + Nginx proxy
Что нам было нужно:
Мощный но легковесный инструмент для мониторинга и сбора статистики, которым можно использовать на Production
К чему мы пришли:
В результате поисков был найден инструмент полностью
удовлетворяющий всем требованиям - JavaMelody
Преимущества JavaMelody• Может работать на QA и Production• Легко встраивается в готовое приложение• Позволяет анализировать:
1. Использование памяти2. JDBC соединения и SQL запросы3. HTTP4. MBeans
• Представляет информацию наглядно, в виде графиков
Недостатки JavaMelody• Если приложение упало, то JavaMelody тоже будет недоступен• Графики не всегда информативны• Нельзя указать интервал просмотра статистики менее 1-го дня
Настройка JavaMelodyДобавляем зависимость в pom.xml <dependency> <groupId>net.bull.javamelody</groupId> <artifactId>javamelody-core</artifactId> <version>1.50.0</version> </dependency>
Добавляем фильтр в web.xml <filter> <filter-name>monitoring</filter-name> <filter-class>net.bull.javamelody.MonitoringFilter</filter-class> </filter> <filter-mapping> <filter-name>monitoring</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <listener> <listener-class>net.bull.javamelody.SessionListener</listener-class> </listener>
Добавляем дополнительный конфиг для поддержки Spring: <context-param> <param-name>contextConfigLocation</param-name> <param-value> classpath:net/bull/javamelody/monitoring-spring.xml /WEB-INF/applicationContext.xml </param-value> </context-param>
На что стоит обратить внимание:
Использование памяти (хорошо):
Использование памяти (плохо):
Открытые JDBC соединения (хорошо):
Открытые JDBC соединения (плохо):
BoneCP через MBeans:Соединения берутся из pool’a но не возвращаются назад.
Открытые JDBC соединения:На протяжение длительного времени соединения остаются открытыми.
Наблюдается утечка JDBC соединений.
Класс-источник проблемы:
Источник проблемы:Отсутствующая @Transactional аннотация. После её добавления проблема утечки JDBC соединений исчезла.
Проект 2
Конфигурация приложения:
Spring 3Hibernate 3.5BoneCP 0.8
СУБД Postgres
Apache tomcat 6 + Nginx proxy
Проект2
Статистика из JavaMelody
Статистика используемой памяти
Статистика http сессий
Что же делать дальше?
Пофикси приложение!
JMeter parameters:
Воспроизвести проблему локально
ConnectionWatcher
Проблема 1: Незакрытые соединения
Проблема 1: Незакрытые соединения
Проблема1: Незакрытые соединения
Результат работы анализатора логов
Проблема1: Незакрытые соединения
Победа?!
Что, опять?
Статистика используемой памяти
Проблема2: “Тяжелые” запросы
Проблема2: “Тяжелые” запросы
Проблема2: “Тяжелые” запросы
Проблема2: “Тяжелые” запросы
Проанализировать модель данных- на предмет Eager/Lazy fetchType- разбить сложные тяжеловесные запросы на более мелкие/быстрые
- класть в модель только необходимые данные
Пофиксили!
Если беда:
1. Hе паниковать
2. Собрать и проанализировать статистику
3. Проанализировать логи на предмет ошибок.
4. Воспроизвести проблему локально
5. Локализовать и пофиксить проблему
6. Пофиксить попутные баги
Спасибо за внимание!Вопросы?