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

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

aragozin
October 12, 2019

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

aragozin

October 12, 2019
Tweet

More Decks by aragozin

Other Decks in Programming

Transcript

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

    У пользователей: до 2 минут на “тяжёлые операции”
  2. Производительность – это просто 1. Находим ресурс ограничивающий производительность CPU,

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

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

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

    ширина шины памяти, IOPS, пропускная способность сети Критические секции ядра, скорость шифрования потока данных 2. Добавляем ресурс 2. Находим причину потребления дефицитного ресурса 3. Оптимизируем – уменьшаем использование дефицитного ресурса Просто не значит легко!
  6. Ком проблем Весь стек работает в одном потоке Web server

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

    Вёрстка (JSF) Бизнес логика BPM Hibernate JDBC База данных Запрос Ответ
  8. От стека вызовов к … … 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) ……
  9. От стека вызовов к … … 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) …
  10. Виновные найдены JDBC 3500ms Hibernate Tomcat / HTTP JSF Компилятор

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

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

    на один HTTP запрос? Какие бины инжектятся чаще?
  13. Трассировка методов 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()
  14. 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); } } }
  15. Инструменты трассировки для JVM Arthas В том числе умеет собирать

    статистику по методам https://github.com/alibaba/arthas MyPerf4j Публикует статистику по вызовам методов в InfluxDB https://github.com/LinShunKang/MyPerf4J
  16. Нюансы вёрстки <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>
  17. Нюансы вёрстки <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>
  18. JDBC 1943ms Hibernate Tomcat / HTTP Вёрстка 1061ms 645ms 267ms

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