Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Разгоняем RPS вопреки всему

B901ed2c8433cd33ebbc1ad2085eea51?s=47 aragozin
October 12, 2019

Разгоняем RPS вопреки всему

B901ed2c8433cd33ebbc1ad2085eea51?s=128

aragozin

October 12, 2019
Tweet

More Decks by aragozin

Other Decks in Programming

Transcript

  1. Разгоняем RPS вопреки всему Алексей Рагозин

  2. Тучи сгущаются

  3. Тучи сгущаются JBoss JSF Seam BPM Hibernate PostgreSQL

  4. Проблема с тестированием На стенде: 99% запросов < 1.5 секунд

    У пользователей: до 2 минут на “тяжёлые операции”
  5. Неожиданные симптомы 100% × 8 CPU 2% x 4 CPU

  6. Производительность – это просто 1. Находим ресурс ограничивающий производительность CPU,

    ширина шины памяти, IOPS, пропускная способность сети Критические секции ядра, скорость шифрования потока данных
  7. Производительность – это просто 1. Находим ресурс ограничивающий производительность CPU,

    ширина шины памяти, IOPS, пропускная способность сети Критические секции ядра, скорость шифрования потока данных 2. Добавляем ресурс
  8. Производительность – это просто 1. Находим ресурс ограничивающий производительность CPU,

    ширина шины памяти, IOPS, пропускная способность сети Критические секции ядра, скорость шифрования потока данных 2. Добавляем ресурс 2. Находим причину потребления дефицитного ресурса 3. Оптимизируем – уменьшаем использование дефицитного ресурса
  9. Производительность – это просто 1. Находим ресурс ограничивающий производительность CPU,

    ширина шины памяти, IOPS, пропускная способность сети Критические секции ядра, скорость шифрования потока данных 2. Добавляем ресурс 2. Находим причину потребления дефицитного ресурса 3. Оптимизируем – уменьшаем использование дефицитного ресурса Просто не значит легко!
  10. Упираемся в CPU 100% × 8 CPU 2% x 4

    CPU
  11. Ком проблем

  12. Ком проблем

  13. Ком проблем Весь стек работает в одном потоке Web server

    Вёрстка (JSF) Бизнес логика BPM Hibernate JDBC База данных Запрос Ответ
  14. Ком проблем Весь стек работает в одном потоке Web server

    Вёрстка (JSF) Бизнес логика BPM Hibernate JDBC База данных Запрос Ответ
  15. Профайлеры Java Mission Control

  16. “Горячий” код “Hot Spots” – методы с набольшей вероятностью выполняющиеся

    в момент дампа потоков
  17. “Огненный граф”

  18. От стека вызовов к … … cтеку фреймворков Web server

    Вёрстка (JSF) Бизнес логика BPM Hibernate JDBC База данных Запрос Ответ java.lang.ClassLoader.loadClass(ClassLoader.java:405) sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) java.lang.ClassLoader.loadClass(ClassLoader.java:358) org.jboss.modules.ConcurrentClassLoader.performLoadClass(ConcurrentClassLoader.java:371) org.jboss.modules.ConcurrentClassLoader.loadClass(ConcurrentClassLoader.java:119) javax.xml.parsers.FactoryFinder.getProviderClass(FactoryFinder.java:112) javax.xml.parsers.FactoryFinder.newInstance(FactoryFinder.java:178) javax.xml.parsers.FactoryFinder.newInstance(FactoryFinder.java:147) javax.xml.parsers.FactoryFinder.find(FactoryFinder.java:219) javax.xml.parsers.SAXParserFactory.newInstance(SAXParserFactory.java:126) com.sun.faces.util.Util.createSAXParserFactory(Util.java:217) com.sun.faces.facelets.compiler.SAXCompiler.createSAXParser… com.sun.faces.facelets.compiler.SAXCompiler.doCompile(SAXCompiler.java:426) com.sun.faces.facelets.compiler.SAXCompiler.doCompile(SAXCompiler.java:403) com.sun.faces.facelets.compiler.Compiler.compile(Compiler.java:124) com.sun.faces.facelets.impl.DefaultFaceletFactory.createFacelet(DefaultFaceletFactory.java:319) com.sun.faces.facelets.impl.DefaultFaceletFactory.access$100(DefaultFaceletFactory.java:92) com.sun.faces.facelets.impl.DefaultFaceletFactory$1.newInstance(DefaultFaceletFactory.java:159) com.sun.faces.facelets.impl.DefaultFaceletFactory$1.newInstance(DefaultFaceletFactory.java:157) com.sun.faces.facelets.impl.DefaultFaceletCache$1.newInstance(DefaultFaceletCache.java:79) com.sun.faces.facelets.impl.DefaultFaceletCache$1.newInstance(DefaultFaceletCache.java:74) com.sun.faces.facelets.impl.DefaultFaceletCache$NoCache.get(DefaultFaceletCache.java:233) com.sun.faces.facelets.impl.DefaultFaceletCache$NoCache.get(DefaultFaceletCache.java:226) ……
  19. От стека вызовов к … … cтеку фреймворков Web server

    Вёрстка (JSF) Бизнес логика BPM Hibernate JDBC База данных Запрос Ответ javassist.util.proxy.RuntimeSupport.find2Methods(RuntimeSupport.java:53) mycompany.cardsystem.Card_$$_javassist_122.getHibernateLazyInitializer(Card_$$_javassist_122.java) org.hibernate.Hibernate.isInitialized(Hibernate.java:89) org.hibernate.engine.internal.StatefulPersistenceContext.reassociateIfUninitializedProxy(StatefulPersist… org.hibernate.event.internal.ProxyVisitor.processEntity(ProxyVisitor.java:49) org.hibernate.event.internal.AbstractVisitor.processValue(AbstractVisitor.java:124) org.hibernate.event.internal.WrapVisitor.processValue(WrapVisitor.java:125) org.hibernate.event.internal.AbstractVisitor.processEntityPropertyValues(AbstractVisitor.java:76) org.hibernate.event.internal.DefaultFlushEntityEventListener.wrapCollections(DefaultFlushEntityEventL… org.hibernate.event.internal.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventList… org.hibernate.event.internal.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener…. org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushi… org.hibernate.event.internal.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListene… org.hibernate.internal.SessionImpl.autoFlushIfRequired(SessionImpl.java:1204) org.hibernate.internal.SessionImpl.list(SessionImpl.java:1261) org.hibernate.internal.QueryImpl.list(QueryImpl.java:101) org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:264) mycompany.bpmimpl.persistanse.CsEJB3FindUtils.findActivityVariableEntity(CsEJB3FindUtils.java:185) mycompany.bpmimpl.persistanse.CsEJB3FindUtils.findActivityVariableEntity(CsEJB3FindUtils.java:191) mycompany.bpmimpl.persistanse.CsPersistentManager.persist(CsPersistentManager.java:1006) mycompany.bpm.WfActivityImpl.persistActivityContext(Unknown Source) mycompany.bpm.WfActivityImpl.setProcessContext(Unknown Source) mycompany.bpm.WfActivityImpl.set_result(Unknown Source) mycompany.bpm.WfActivityImpl.receive_event(Unknown Source) …
  20. Виновные найдены JDBC 3500ms Hibernate Tomcat / HTTP Вёрстка

  21. Виновные найдены JDBC 3500ms Hibernate Tomcat / HTTP JSF Компилятор

    JSF Life cycle Бижекция бинов “Resource not found”
  22. Виновные найдены JDBC 3500ms Hibernate Tomcat / HTTP JSF Компилятор

    JSF Life cycle Бижекция бинов “Resource not found” Ошибка конфигурации Проверка изменений в справочниках на каждую Операцию БД
  23. А теперь вёрстка … Сколько раз бин инжекцится в контекст

    на один HTTP запрос? Какие бины инжектятся чаще?
  24. Трассировка методов Task.run() wait() process() getBody() read() parse() handle() load()

    read() Time encode() wait() process() getBody() read() parse() handle() load() read() encode() wait() process() getBody() read() parse() handle() encode() Task.run() wait() process() getBody() read() parse() handle() load() read() Time encode() process() getBody() read() parse() handle() load() read() encode() wait() process() getBody() read() parse() handle() encode() No tracing Tracing parse(), load() and encode()
  25. BTrace BTrace • Инструментирующий профайлер • CLI и плагин к

    Visual VM • Скрипты на Java https://github.com/btraceio/btrace BTrace script @Property Profiler prof = Profiling.newProfiler(); @OnMethod(clazz = "org.jboss.seam.Component“, method = "/(inject|disinject|outject)/") void entryByMethod2(@ProbeClassName String className, @ProbeMethodName String methodName, @Self Object component) { if (component != null) { Field nameField = field(classOf(component), "name", true); if (nameField != null) { String name = (String)get(nameField, component); Profiling.recordEntry(prof, concat("org.jboss.seam.Component.", concat(methodName, concat(":", name)))); } } } @OnMethod(clazz = "org.jboss.seam.Component“, method = "/(inject|disinject|outject)/", location = @Location(value = Kind.RETURN)) void exitByMthd2(@ProbeClassName String className, @ProbeMethodName String methodName, @Self Object component, @Duration long duration) { if (component != null) { Field nameField = field(classOf(component), "name", true); if (nameField != null) { String name = (String)get(nameField, component); Profiling.recordExit(prof, concat("org.jboss.seam.Component.", concat(methodName, concat(":", name))), duration); } } }
  26. Инструменты трассировки для JVM Arthas В том числе умеет собирать

    статистику по методам https://github.com/alibaba/arthas MyPerf4j Публикует статистику по вызовам методов в InfluxDB https://github.com/LinShunKang/MyPerf4J
  27. Нюансы вёрстки <h:outputStylesheet name="modern.css" rendered="#{appSettings.getSetting('theme') == 'modern'}"/> <h:outputStylesheet name="north.css" rendered="#{appSettings.getSetting('theme')

    == 'north'}"/> <h:outputStylesheet name="asia.css" rendered="#{appSettings.getSetting('theme') == 'asia'}"/> <h:outputStylesheet name="west.css" rendered="#{appSettings.getSetting('theme') == 'west'}"/> <h:outputStylesheet name="basic.css" rendered="#{appSettings.getSetting('theme') == 'basic'}"/> ... <div class="image"> <c:choose> <c:when test="#{appSettings.getSetting('theme') == 'modern' or appSettings.getSetting('theme') == 'west'}"> <img src="/img/ajax-loader-modern.gif"/> </c:when>
  28. Нюансы вёрстки <h:outputStylesheet name="modern.css" rendered="#{appSettings.getSetting('theme') == 'modern'}"/> <h:outputStylesheet name="north.css" rendered="#{appSettings.getSetting('theme')

    == 'north'}"/> <h:outputStylesheet name="asia.css" rendered="#{appSettings.getSetting('theme') == 'asia'}"/> <h:outputStylesheet name="west.css" rendered="#{appSettings.getSetting('theme') == 'west'}"/> <h:outputStylesheet name="basic.css" rendered="#{appSettings.getSetting('theme') == 'basic'}"/> ... <div class="image"> <c:choose> <c:when test="#{appSettings.getSetting('theme') == 'modern' or appSettings.getSetting('theme') == 'west'}"> <img src="/img/ajax-loader-modern.gif"/> </c:when>
  29. JDBC 1943ms Hibernate Tomcat / HTTP Вёрстка 1061ms 645ms 267ms

    Другое Зачистка проблем Исходная версия Read-only режим для Hibernate объектов Тюнинг размера бачтча ID генератора Отдельные entity manager для справочников Минимизация пустых комитов Включение кеша компиляции JSF Оптимизация вёрстки Обход бага с интернанализацией
  30. Виноват ли монолит?

  31. Спасибо! Алексей Рагозин alexey.ragozin@gmail.com https://blog.ragozin.info Вебинары и прочие мероприятия по

    теме Java Ops https://aragozin.timepad.ru/