SlideShare a Scribd company logo
1 of 137
© Netcracker 2016 1
Производительность
open source решений
Владимир Ситников
JPoint 2016
© Netcracker 2016 2
•Владимир Ситников
•Инженер по производительности в Netcracker,
10 лет
•sitnikov@netcracker.com
•@VladimirSitnikv
Кто я
© Netcracker 2016 3
•Spring
•Cglib
•Pgjdbc
•HornetQ
•Wildfly
•Jenkins
План
© Netcracker 2016 4
План
Наш любимый
enterprise
продукт
© Netcracker 2016 5
Внедряем Spring в сжатые сроки
Монолит
spring
© Netcracker 2016 6
Внедряем Spring в сжатые сроки
Монолит
spring
© Netcracker 2016 7
Внедряем Spring в сжатые сроки
Core
Security
UI
© Netcracker 2016 8
Внедряем Spring в сжатые сроки
Core
Security
UI
© Netcracker 2016 9
Внедряем Spring в сжатые сроки
Core
Security
UI
© Netcracker 2016 10
•Когда нужен бин, то выполняем
beanFactory.getBean(Security.class)
В UI spring пока не наступил
© Netcracker 2016 11
•Когда нужен бин, то выполняем
beanFactory.getBean(Security.class)
•Но где взять beanFactory?
В UI spring пока не наступил
© Netcracker 2016 12
•Когда нужен бин, то выполняем
beanFactory.getBean(Security.class)
•Но где взять beanFactory?
•Правильно, Паблик Морозов поможет нам
В UI spring пока не наступил
© Netcracker 2016 13
public class AppContext implements BeanFactoryAware
{
static public BeanFactory beanFactory;
...
Получаем бин
© Netcracker 2016 14
public class AppContext implements BeanFactoryAware
{
static public BeanFactory beanFactory;
...
AppContext.beanFactory.getBean(Security.class)
Получаем бин
© Netcracker 2016 15
•Работает
Spring.getBean
© Netcracker 2016 16
•Работает
•Но медленно-медленно
Spring.getBean
© Netcracker 2016 17
•Работает
•Но медленно-медленно
•На getBean и 50% времени может уходить
Spring.getBean
© Netcracker 2016 18
•Java Flight Recorder
Подходящие для анализа инструменты
© Netcracker 2016 19
•Java Flight Recorder
•kill -3 profiler (poormansprofiler.org)
Подходящие для анализа инструменты
© Netcracker 2016 20
•Java Flight Recorder
•kill -3 profiler (poormansprofiler.org)
•Инструментирующий профилировщик.
Например самописный, настроенный на
getBean
Подходящие для анализа инструменты
© Netcracker 2016 21
160 секунд на getBean. Здорово?
© Netcracker 2016 22
160 секунд на getBean. Здорово?
•Java 8 / Spring 4.1.7
© Netcracker 2016 23
•SPR-6870 Cache by-type lookups in
DefaultListableBeanFactory
Проверяем известные проблемы
© Netcracker 2016 24
•SPR-6870 Cache by-type lookups in
DefaultListableBeanFactory
Проверяем известные проблемы
ЯЗЬ!!!
© Netcracker 2016 25
•SPR-6870 Cache by-type lookups in
DefaultListableBeanFactory
•Fix version: 3.2 M1, а у нас 4.1+ 
Проверяем известные проблемы
© Netcracker 2016 26
Flight Recorder, allocations in new TLAB
© Netcracker 2016 27
protected Object getCacheKey(
Class<?> beanClass, String beanName) {
return beanClass.getName() + "_" + beanName;
}
AbstractAutoProxyCreator
© Netcracker 2016 28
protected Object getCacheKey(
Class<?> beanClass, String beanName) {
return beanClass.getName() + "_" + beanName;
}
AbstractAutoProxyCreator
© Netcracker 2016 29
protected Object getCacheKey(
Class<?> beanClass, String beanName) {
return beanName == null ? beanClass : ...;
}
github.com/spring-projects/spring-
framework/pull/913
AbstractAutoProxyCreator
© Netcracker 2016 30
public class SharedSecrets {
@Inject
public Security security;
@PostConstruct
public void init() { INSTANCE = this; }
public static volatile SharedSecrets INSTANCE;
Как выжить без обновления Spring?
© Netcracker 2016 31
•Не стоит злоупотреблять prototype
bean’ами. Если singleton, то singleton
Prototype vs singleton
© Netcracker 2016 32
•Не стоит злоупотреблять prototype
bean’ами. Если singleton, то singleton
•Замена getBean на
javax.inject.Provider<...> лишь
ухудшает время работы
•
Prototype vs singleton
© Netcracker 2016 33
@Pointcut(
"execution(
public* my.service.*ServiceImpl.*(..))”
)
Spring AOP
© Netcracker 2016 34
•OutOfMemory: perm gen
Spring AOP
© Netcracker 2016 35
•OutOfMemory: perm gen
•В хипдампе куча java.lang.reflect.Method
Spring AOP
© Netcracker 2016 36
•OutOfMemory: perm gen
•В хипдампе куча java.lang.reflect.Method
•Method’ы занимают 100-500MiB
Spring AOP
© Netcracker 2016 37
•OutOfMemory: perm gen
•В хипдампе куча java.lang.reflect.Method
•Method’ы занимают 100-500MiB
•Все они лежат в AspectJExpressionPointcut
Spring AOP
© Netcracker 2016 38
@Pointcut(
"execution(
public* my.service.*ServiceImpl.*(..))”
)
Spring AOP
© Netcracker 2016 39
•Решение: добавлять
within(my.package.service.business..*)
Spring AOP vs AspectJ
© Netcracker 2016 40
•Решение: добавлять
within(my.package.service.business..*)
•Разумеется, AspectJ рекомендуют
использовать within всегда:
http://dev.eclipse.org/mhonarc/lists/aspectj-
users/msg10969.html
•
Spring AOP vs AspectJ
© Netcracker 2016 41
•Cglib используется много где: рукотворный
код, тот же Spring
Cglib
© Netcracker 2016 42
•Cglib используется много где: рукотворный
код, тот же Spring
•Наверняка уже всё исправлено давным-
давно
Cglib
© Netcracker 2016 43
•Cglib используется много где: рукотворный
код, тот же Spring
•Наверняка уже всё исправлено давным-
давно
•Наверняка туда давно никто не заглядывал
Cglib
© Netcracker 2016 44
@Benchmark
public Object newProxy() {
return Beans.newProxy(Beans.class);
}
Cglib: замеряем
© Netcracker 2016 45
0
2
4
6
8
10
12
14
16
18
Cglib 3.1
1 поток 2 потока 4 потока 8 потоков
Замеры Cglib, μs/opБыстрее
© Netcracker 2016 46
0
2
4
6
8
10
12
14
16
18
Cglib 3.1 Cglib 3.2.2
1 поток 2 потока 4 потока 8 потоков
Замеры Cglib, μs/opБыстрее
© Netcracker 2016 47
Benchmark Score
newProxy 2.1 ± 0.3 μs/op
newProxy.alloc.rate 1240 B/op
Стало
newProxy 0.14 ± 0.02 μs/op
newProxy.alloc.rate 256 B/op
Cglib 3.2.2: ждём в очередном Spring
© Netcracker 2016 48
•Skip finalize while building proxy
https://github.com/cglib/cglib/pull/51
•Concurrent cache of generated classes
https://github.com/cglib/cglib/pull/53
План захвата Cglib
© Netcracker 2016 49
•А, может, ну его этот cglib, есть же быстрый
ByteBuddy?
Но есть же ByteBuddy
© Netcracker 2016 50
•А, может, ну его этот cglib, есть же быстрый
ByteBuddy?
@Benchmark
public ExampleClass benchmarkCglib() {
Enhancer enhancer = new Enhancer();
enhancer.setUseCache(false);
ByteBuddy, jmh тест
© Netcracker 2016 51
•А, может, ну его этот cglib, есть же быстрый
ByteBuddy?
@Benchmark
public ExampleClass benchmarkCglib() {
Enhancer enhancer = new Enhancer();
enhancer.setUseCache(false);
ByteBuddy, jmh тест
© Netcracker 2016 52
•JMH тесты в ByteBuddy показывают
скорость создания классов
•Постоянно создавать классы нехорошо
•Значит, нужно измерять скорость
кэшированного обращения
ByteBuddy, jmh тест
© Netcracker 2016 53
•КО: «Бери pgjdbc»
Подключаемся к PostgreSQL
© Netcracker 2016 54
•КО: «Бери pgjdbc»
•КО: «Используй batch statements»
Подключаемся к PostgreSQL
© Netcracker 2016 55
•КО: «Бери pgjdbc»
•КО: «Используй batch statements»
•Что может пойти не так?
Подключаемся к PostgreSQL
© Netcracker 2016 56
Connection con = ...;
PreparedStatement ps =
con.prepareStatement("SELECT...");
...
ps.close();
PreparedStatement
© Netcracker 2016 57
Connection con = ...;
PreparedStatement ps =
con.prepareStatement("SELECT...");
...
ps.close();
PreparedStatement
© Netcracker 2016 58
PARSE S_1 as ...; // con.prepareStmt
BIND/EXEC
DEALLOCATE // ps.close()
PARSE S_2 as ...;
BIND/EXEC
DEALLOCATE // ps.close()
Работа с PostgreSQL курильщика
© Netcracker 2016 59
PARSE S_1 as ...; 
BIND/EXEC
BIND/EXEC
BIND/EXEC 
BIND/EXEC
BIND/EXEC
...
DEALLOCATE
Работа с PostgreSQL здорового человека
© Netcracker 2016 60
PARSE S_1 as ...;  1 раз в жизни
BIND/EXEC  обработка REST
BIND/EXEC
BIND/EXEC  ещё REST
BIND/EXEC
BIND/EXEC
...
DEALLOCATE  желательно «никогда»
DEALLOCATE
Работа с PostgreSQL здорового человека
© Netcracker 2016 61
Вывод: чтобы работало быстрее,
закрывать statement’ы не нужно
ps = con.prepareStatement(...)
ps.execueQuery();
ps = con.prepareStatement(...)
ps.execueQuery();
...
Счастливые statement’ов не закрывают
© Netcracker 2016 62
Вывод: чтобы работало быстрее,
закрывать statement’ы не нужно
ps = con.prepare...
ps.execueQuery();
ps = con.prepare...
ps.execueQuery();
...
Счастливые statement’ов не закрывают
© Netcracker 2016 63
@Benchmark
public Statement leakStatement() {
return con.createStatement();
}
pgjdbc < 9.4.1202, -Xmx128m, OracleJDK 1.8u40
# Warmup Iteration 1: 1147,070 ns/op
# Warmup Iteration 2: 12101,537 ns/op
# Warmup Iteration 3: 90825,971 ns/op
# Warmup Iteration 4: <failure>
java.lang.OutOfMemoryError: GC overhead limit exceeded
OpenJDK: не все JRE одинаково полезны
© Netcracker 2016 64
@Benchmark
public Statement leakStatement() {
return con.createStatement();
}
pgjdbc >= 9.4.1202, -Xmx128m, OracleJDK 1.8u40
# Warmup Iteration 1: 30 ns/op
# Warmup Iteration 2: 27 ns/op
...
github.com/pgjdbc/pgjdbc/pull/299
Убираем finalize из класса PgConnection
© Netcracker 2016 65
Вывод: чтобы работало быстро, нужно
как-то кэшировать statement’ы
ps = con.prepareStatement("select id,
name ...");
ps.execueQuery();
ps.close();
ps2 = con.prepareStatement("select id,
name ...");
Счастливые statement’ов не закрывают
© Netcracker 2016 66
•Кэш запросов появился в версии 9.4.1202
(2015-08-27)
см. https://github.com/pgjdbc/pgjdbc/pull/319
Кэш запросов в PgJDBC
© Netcracker 2016 67
•Кэш запросов появился в версии 9.4.1202
(2015-08-27)
см. https://github.com/pgjdbc/pgjdbc/pull/319
•Работает прозрачно для приложения
Кэш запросов в PgJDBC
© Netcracker 2016 68
•Кэш запросов появился в версии 9.4.1202
(2015-08-27)
см. https://github.com/pgjdbc/pgjdbc/pull/319
•Работает прозрачно для приложения
•Скорость такая, что PL/PgSQL не нужен
Кэш запросов в PgJDBC
© Netcracker 2016 69
•Кэш запросов появился в версии 9.4.1202
(2015-08-27)
см. https://github.com/pgjdbc/pgjdbc/pull/319
•Работает прозрачно для приложения
•Скорость такая, что PL/PgSQL не нужен
•Server-prepare активируется после 5-го
выполнения (prepareThreshold)
Кэш запросов в PgJDBC
© Netcracker 2016 70
•Конечно, затраты planning time напрямую
зависят от сложности запросов
Цифры где?
© Netcracker 2016 71
•Конечно, затраты planning time напрямую
зависят от сложности запросов
•У нас доходило до 20мс+ planning time на
OLTP запросах: 10КиБ запрос, 170 строк
explain
•
Цифры где?
© Netcracker 2016 72
•Конечно, затраты planning time напрямую
зависят от сложности запросов
•У нас доходило до 20мс+ planning time на
OLTP запросах: 10КиБ запрос, 170 строк
explain
•Стало ~0мс
Цифры где?
© Netcracker 2016 73
Если типы параметров меняются, то server-
prepared statement приходится менять
ps.setInt(1, 42);
...
ps.setNull(1, Types.VARCHAR);
JDBC: Типы параметров
© Netcracker 2016 74
Если типы параметров меняются, то server-
prepared statement приходится менять
ps.setInt(1, 42);
...
ps.setNull(1, Types.VARCHAR);
JDBC: Типы параметров
© Netcracker 2016 75
•Вывод: даже у NULL’ов должен быть
верный тип
JDBC: Тип параметров изменять нельзя
© Netcracker 2016 76
•Вывод: даже у NULL’ов должен быть
верный тип
•Ещё раз: setObject(1, null)
использовать нельзя
JDBC: Тип параметров изменять нельзя
© Netcracker 2016 77
•Перешли на prepared, и запрос замедлился
в 5'000 раз. Как так?
Нежданчик
© Netcracker 2016 78
•Перешли на prepared, и запрос замедлился
в 5'000 раз. Как так?
Нежданчик
A. Бага C. Фича
B. Фича D. Бага
© Netcracker 2016 79
https://gist.github.com/vlsi -> 01_plan_flipper.sql
select *
from plan_flipper -- <- таблица
where skewed = 0 -- 1 млн строк
and non_skewed = 42 -- 20 строк
Нежданчик
© Netcracker 2016 80
https://gist.github.com/vlsi -> 01_plan_flipper.sql
0.1мс  1-е выполнение
0.05мс  2-е выполнение
0.05мс  3-е выполнение
0.05мс  4-е выполнение
0.05мс  5-е выполнение
250 мс  6-е выполнение
Нежданчик
© Netcracker 2016 81
https://gist.github.com/vlsi -> 01_plan_flipper.sql
0.1мс  1-е выполнение
0.05мс  2-е выполнение
0.05мс  3-е выполнение
0.05мс  4-е выполнение
0.05мс  5-е выполнение
250 мс  6-е выполнение
Нежданчик
© Netcracker 2016 82
Запрещаем использование индекса через +0:
select *
from plan_flipper
where skewed+0 = 0  ~ /*+no_index*/
and non_skewed = 42
Чиним
© Netcracker 2016 83
Как сделать опциональные фичи?
•NO_RESULTS
•BOTH_ROWS_AND_STATUS
•DESCRIBE_ONLY
Фичи
© Netcracker 2016 84
Конечно, enum!
enum ... {
NO_RESULTS,
BOTH_ROWS_AND_STATUS,
DESCRIBE_ONLY;
}
Фичи
© Netcracker 2016 85
Конечно, enum!
enum ... {
NO_RESULTS,
BOTH_ROWS_AND_STATUS,
DESCRIBE_ONLY;
}
А на java 1.4?
Фичи
© Netcracker 2016 86
В java 1.4, конечно, interface!
interface ... {
int NO_RESULTS = 1;
int BOTH_ROWS_AND_STATUS = 2;
int DESCRIBE_ONLY = 4;
}
Фичи: java 1.4 наносит ответный удар
© Netcracker 2016 87
Меняем 1 строку, и скорость работы batch insert
возрастает в 10 раз:
https://github.com/pgjdbc/pgjdbc/pull/380
- static int QUERY_FORCE_DESCRIBE_PORTAL = 128;
+ static int QUERY_FORCE_DESCRIBE_PORTAL = 512;
Ужасы нашего городка
© Netcracker 2016 88
Меняем 1 строку, и скорость работы batch insert
возрастает в 10 раз:
https://github.com/pgjdbc/pgjdbc/pull/380
- static int QUERY_FORCE_DESCRIBE_PORTAL = 128;
+ static int QUERY_FORCE_DESCRIBE_PORTAL = 512;
// оказалось, значение 128 уже было занято
static int QUERY_DISALLOW_BATCHING = 128;
Ужасы нашего городка
© Netcracker 2016 89
•WildFly 8.2, JMS
HornetQ
© Netcracker 2016 90
•WildFly 8.2, JMS
•Всего ~100 JMS/сек
HornetQ
© Netcracker 2016 91
•WildFly 8.2, JMS
•Всего ~100 JMS/сек
•1 вызов sendMessage – 5-30 секунд
HornetQ
© Netcracker 2016 92
at java.util.concurrent.Semaphore.tryAcquire
at org.hornetq ... ClientProducerCreditsImpl.acquireCredits
at com ... JMSSender.sendMessage
kill -3 профайлер
© Netcracker 2016 93
at java.util.concurrent.Semaphore.tryAcquire
at org.hornetq ... ClientProducerCreditsImpl.acquireCredits
at com ... JMSSender.sendMessage
kill -3 профайлер
© Netcracker 2016 94
at java.util.concurrent.Semaphore.tryAcquire
at org.hornetq ... ClientProducerCreditsImpl.acquireCredits
at com ... JMSSender.sendMessage
kill -3 профайлер
© Netcracker 2016 95
at java.util.concurrent.Semaphore.tryAcquire
at org.hornetq ... ClientProducerCreditsImpl.acquireCredits
at org.hornetq ... ClientProducerImpl.sendRegularMessage
at com ... JMSSender.sendMessage
kill -3 профайлер
© Netcracker 2016 96
at java.util.concurrent.Semaphore.tryAcquire
at org.hornetq ... ClientProducerCreditsImpl.acquireCredits
at org.hornetq ... ClientProducerImpl.sendRegularMessage
at org.hornetq ... ClientProducerImpl.doSend
at com ... JMSSender.sendMessage
kill -3 профайлер
© Netcracker 2016 97
at java.util.concurrent.Semaphore.tryAcquire
at org.hornetq ... ClientProducerCreditsImpl.acquireCredits
at org.hornetq ... ClientProducerImpl.sendRegularMessage
at org.hornetq ... ClientProducerImpl.doSend
at org.hornetq ... ClientProducerImpl.send
at com ... JMSSender.sendMessage
kill -3 профайлер
© Netcracker 2016 98
at java.util.concurrent.Semaphore.tryAcquire
at org.hornetq ... ClientProducerCreditsImpl.acquireCredits
at org.hornetq ... ClientProducerImpl.sendRegularMessage
at org.hornetq ... ClientProducerImpl.doSend
at org.hornetq ... ClientProducerImpl.send
at org.hornetq ... HornetQMessageProducer.doSendx
at com ... JMSSender.sendMessage
kill -3 профайлер
© Netcracker 2016 99
• 'Producer Window Size’ на connection factory
Backpressure
© Netcracker 2016 100
• 'Producer Window Size’ на connection factory
• address-settings -> address-setting -> max-size-bytes
Backpressure
© Netcracker 2016 101
• 'Producer Window Size’ на connection factory
• address-settings -> address-setting -> max-size-bytes
• Если в JMS очереди накапливается 10МиБ, то отправка
JMS начинает притормаживать
Backpressure
© Netcracker 2016 102
• 'Producer Window Size’ на connection factory
• address-settings -> address-setting -> max-size-bytes
• Если в JMS очереди накапливается 10МиБ, то отправка
JMS начинает притормаживать
<address-settings>
<address-setting match="#">
<max-size-bytes>10 485 760</max-size-bytes>
…
Backpressure
© Netcracker 2016 103
•Настраиваем max-size-bytes для каждой
очереди
Backpressure: чиним
© Netcracker 2016 104
•Настраиваем max-size-bytes для каждой
очереди
•Либо смотрим в сторону RxJava
Backpressure: чиним
© Netcracker 2016 105
•Старт приложения на WF 8.2 занимает 2-5
минут
WildFly: пытаемся взлететь
© Netcracker 2016 106
•Старт приложения на WF 8.2 занимает 2-5
минут
•Concurrent deploy работает плохо
WildFly: пытаемся взлететь
© Netcracker 2016 107
•Старт приложения на WF 8.2 занимает 2-5
минут
•Concurrent deploy работает плохо
•Spring xml app config анализирует все
jar’ники
WildFly: пытаемся взлететь
© Netcracker 2016 108
•Уменьшать размер jar (исключать лишние)
• WildFly копирует jar в /tmp при запуске
WildFly: как чинить
© Netcracker 2016 109
•Уменьшать размер jar (исключать лишние)
• WildFly копирует jar в /tmp при запуске
•Делать патчи на WF, чтобы он не
складывал строки
• https://github.com/jbossas/jboss-vfs/pull/25
• https://github.com/wildfly/wildfly-core/pull/1219
WildFly: как чинить
© Netcracker 2016 110
•Уменьшать размер jar (исключать лишние)
• WildFly копирует jar в /tmp при запуске
•Делать патчи на WF, чтобы он не
складывал строки
• https://github.com/jbossas/jboss-vfs/pull/25
• https://github.com/wildfly/wildfly-core/pull/1219
•Профилировать запуск вашего WF (kill -3
profiler)
WildFly: как чинить
© Netcracker 2016 111
Самое главное в CI –
переменные окружения
Jenkins
© Netcracker 2016 112
https://wiki.jenkins-ci.org/display/JENKINS/EnvInject+Plugin
Jenkins: EnvInjectPlugin
© Netcracker 2016 113
Пишем по образу и подобию:
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ORAC
LE_HOME/…
PATH=$PATH:$ORACLE/bin:…
Jenkins: EnvInjectPlugin
© Netcracker 2016 114
EnvInjectEnvVars.resolveVars()
Jenkins: EnvInjectPlugin
© Netcracker 2016 115
EnvInjectEnvVars.resolveVars()
-> hudson.Util.replaceMacro()
Jenkins: EnvInjectPlugin
© Netcracker 2016 116
EnvInjectEnvVars.resolveVars()
-> hudson.Util.replaceMacro()
-> OutOfMemoryError.<init>()
Jenkins: EnvInjectPlugin
© Netcracker 2016 117
$LD_LIBRARY_PATH:$ORACLE_HOME/lib
:$ORACLE_HOME/lib:$ORACLE_HOME/lib
:$ORACLE_HOME/lib:$ORACLE_HOME/lib
:$ORACLE_HOME/lib:$ORACLE_HOME/lib
:$ORACLE_HOME/lib:$ORACLE_HOME/lib
:$ORACLE_HOME/lib:$ORACLE_HOME/lib
:$ORACLE_HOME/lib:$ORACLE_HOME/lib
:$ORACLE_HOME/lib:...
Jenkins: EnvInjectPlugin
© Netcracker 2016 118
https://issues.jenkins-ci.org/browse/JENKINS-
19856
^^^ с вами с 2013 года
Jenkins: EnvInjectPlugin
© Netcracker 2016 119
•Общение Jenkins master и slave тщательно
логируется
Jenkins: master vs slave
© Netcracker 2016 120
•Общение Jenkins master и slave тщательно
логируется
•«Разумеется», в памяти хранятся
последние 1000 записей
Jenkins: master vs slave
© Netcracker 2016 121
•Общение Jenkins master и slave тщательно
логируется
•«Разумеется», в памяти хранятся
последние 1000 записей
•Н
а эти логи может уходить 100-200МиБ
Jenkins: master vs slave
© Netcracker 2016 122
•Общение Jenkins master и slave тщательно
логируется
•«Разумеется», в памяти хранятся
последние 1000 записей
•Н
•Да, да. Логи хранятся в памяти и никогда не
попадают в файл
Jenkins: master vs slave
© Netcracker 2016 123
•Хорошо, что есть опция
• -Dhudson.remoting.ExportTable.unexportLog=0
Jenkins: master vs slave
© Netcracker 2016 124
•Хорошо, что есть опция
• -Dhudson.remoting.ExportTable.unexportLog=0
•Разумеется, в Google ровно один результат
Jenkins: master vs slave
© Netcracker 2016 125
•Хорошо, что есть опция
• -Dhudson.remoting.ExportTable.unexportLog=0
•Разумеется, в Google ровно один результат
•На исходный код, где она определена :)
Jenkins: master vs slave
© Netcracker 2016 126
•Оказалось, что запуск master занимает 50
минут
• 3000 jobs, 10-500 runs per job
• 24 CPU, 64 GiB RAM
• -Xmx40g
Jenkins: запускаемся
© Netcracker 2016 127
•При старте, Jenkins инициализирует job’ы
Jenkins: файлы разные нужны, файлы разные важны
© Netcracker 2016 128
•При старте, Jenkins инициализирует job’ы
•Maven job загружает данные по всем
запускам
Jenkins: файлы разные нужны, файлы разные важны
© Netcracker 2016 129
•При старте, Jenkins инициализирует job’ы
•Maven job загружает данные по всем
запускам
•В
каждом запуске есть fingerprint’ы, они тоже
грузятся
Jenkins: файлы разные нужны, файлы разные важны
© Netcracker 2016 130
•При старте, Jenkins инициализирует job’ы
•Maven job загружает данные по всем
запускам
•В
•В итоге много-много операций с диском
•и тоже грузятся
Jenkins: файлы разные нужны, файлы разные важны
© Netcracker 2016 131
•Решение в лоб: удалить fingerprint’ы перед
запуском
Jenkins: чиним
© Netcracker 2016 132
•Решение в лоб: удалить fingerprint’ы перед
запуском
•Более сложное: не плодить fingerprint’ы
Jenkins: чиним
© Netcracker 2016 133
•Решение в лоб: удалить fingerprint’ы перед
запуском
•Более сложное: не плодить fingerprint’ы
•Поможет и сокращение хранимой истории
Jenkins: чиним
© Netcracker 2016 134
•Решение в лоб: удалить fingerprint’ы перед
запуском
•Более сложное: не плодить fingerprint’ы
•Поможет и сокращение хранимой истории
•В идеальном мире нужно разбираться с
maven-jenkins-plugin
Jenkins: чиним
© Netcracker 2016 135
Кто виноват и что делать?
© Netcracker 2016 136
•Владимир Ситников
•Инженер по производительности в Netcracker
•sitnikov@netcracker.com
•@VladimirSitnikv
С вами был
© Netcracker 2016 137
Вопросы?

More Related Content

What's hot

Производительность open source решений
Производительность open source решенийПроизводительность open source решений
Производительность open source решенийVladimir Sitnikov
 
Быстрое построение backendов c помощью реактивных потоков
Быстрое построение backendов c помощью реактивных потоковБыстрое построение backendов c помощью реактивных потоков
Быстрое построение backendов c помощью реактивных потоковCodeFest
 
Организация процесса регулярной обработки больших объемов данных
Организация процесса регулярной обработки больших объемов данныхОрганизация процесса регулярной обработки больших объемов данных
Организация процесса регулярной обработки больших объемов данныхCodeFest
 
Zabbix 3.4 - простая непростая дружба с сообществом / Алексей Владышев (Zabbix)
Zabbix 3.4 - простая непростая дружба с сообществом / Алексей Владышев (Zabbix)Zabbix 3.4 - простая непростая дружба с сообществом / Алексей Владышев (Zabbix)
Zabbix 3.4 - простая непростая дружба с сообществом / Алексей Владышев (Zabbix)Ontico
 
Kubernetes
KubernetesKubernetes
KubernetesSQALab
 
Реактивный двигатель вашего Android приложения
Реактивный двигатель вашего Android приложенияРеактивный двигатель вашего Android приложения
Реактивный двигатель вашего Android приложенияMatvey Malkov
 
Алексей Романчук «Реактивное программирование»
Алексей Романчук «Реактивное программирование»Алексей Романчук «Реактивное программирование»
Алексей Романчук «Реактивное программирование»DevDay
 
Илья Кудинов
Илья КудиновИлья Кудинов
Илья КудиновCodeFest
 
Selenium grid on-demand
Selenium grid on-demandSelenium grid on-demand
Selenium grid on-demandSQALab
 
Всевидящее око. Мониторинг нагрузочного тестирования с InfluxDB и Grafana
Всевидящее око. Мониторинг нагрузочного тестирования с InfluxDB и GrafanaВсевидящее око. Мониторинг нагрузочного тестирования с InfluxDB и Grafana
Всевидящее око. Мониторинг нагрузочного тестирования с InfluxDB и GrafanaSQALab
 
Deployment to production with an unexpected load
Deployment to production with an unexpected loadDeployment to production with an unexpected load
Deployment to production with an unexpected loadGrid Dynamics
 
Что нам стоит DAL построить? Акуляков Артём D2D Just.NET
Что нам стоит DAL построить? Акуляков Артём D2D Just.NETЧто нам стоит DAL построить? Акуляков Артём D2D Just.NET
Что нам стоит DAL построить? Акуляков Артём D2D Just.NETDev2Dev
 
Service Discovery. More that it seems
Service Discovery. More that it seemsService Discovery. More that it seems
Service Discovery. More that it seemsAleksandr Tarasov
 
Переезжаем с Zabbix на Prometheus / Василий Озеров (fevlake)
Переезжаем с Zabbix на Prometheus / Василий Озеров (fevlake)Переезжаем с Zabbix на Prometheus / Василий Озеров (fevlake)
Переезжаем с Zabbix на Prometheus / Василий Озеров (fevlake)Ontico
 
Ядро автоматизации под микро-сервисную архитектуру
Ядро автоматизации под микро-сервисную архитектуруЯдро автоматизации под микро-сервисную архитектуру
Ядро автоматизации под микро-сервисную архитектуруSQALab
 
Эволюционный дизайн. Joker Students Day 2016
Эволюционный дизайн. Joker Students Day 2016Эволюционный дизайн. Joker Students Day 2016
Эволюционный дизайн. Joker Students Day 2016Кирилл Толкачёв
 
Continuous Delivery with Jenkins: Lessons Learned
Continuous Delivery with Jenkins: Lessons LearnedContinuous Delivery with Jenkins: Lessons Learned
Continuous Delivery with Jenkins: Lessons LearnedAleksandr Tarasov
 
Олег Миколайченко "Как перестать хранить секреты в git и начать использовать ...
Олег Миколайченко "Как перестать хранить секреты в git и начать использовать ...Олег Миколайченко "Как перестать хранить секреты в git и начать использовать ...
Олег Миколайченко "Как перестать хранить секреты в git и начать использовать ...Fwdays
 
Joker 2015. WILD microSERVICES
Joker 2015. WILD microSERVICESJoker 2015. WILD microSERVICES
Joker 2015. WILD microSERVICESAleksandr Tarasov
 

What's hot (20)

Производительность open source решений
Производительность open source решенийПроизводительность open source решений
Производительность open source решений
 
Быстрое построение backendов c помощью реактивных потоков
Быстрое построение backendов c помощью реактивных потоковБыстрое построение backendов c помощью реактивных потоков
Быстрое построение backendов c помощью реактивных потоков
 
Организация процесса регулярной обработки больших объемов данных
Организация процесса регулярной обработки больших объемов данныхОрганизация процесса регулярной обработки больших объемов данных
Организация процесса регулярной обработки больших объемов данных
 
Zabbix 3.4 - простая непростая дружба с сообществом / Алексей Владышев (Zabbix)
Zabbix 3.4 - простая непростая дружба с сообществом / Алексей Владышев (Zabbix)Zabbix 3.4 - простая непростая дружба с сообществом / Алексей Владышев (Zabbix)
Zabbix 3.4 - простая непростая дружба с сообществом / Алексей Владышев (Zabbix)
 
Kubernetes
KubernetesKubernetes
Kubernetes
 
Реактивный двигатель вашего Android приложения
Реактивный двигатель вашего Android приложенияРеактивный двигатель вашего Android приложения
Реактивный двигатель вашего Android приложения
 
Алексей Романчук «Реактивное программирование»
Алексей Романчук «Реактивное программирование»Алексей Романчук «Реактивное программирование»
Алексей Романчук «Реактивное программирование»
 
Илья Кудинов
Илья КудиновИлья Кудинов
Илья Кудинов
 
Selenium grid on-demand
Selenium grid on-demandSelenium grid on-demand
Selenium grid on-demand
 
Всевидящее око. Мониторинг нагрузочного тестирования с InfluxDB и Grafana
Всевидящее око. Мониторинг нагрузочного тестирования с InfluxDB и GrafanaВсевидящее око. Мониторинг нагрузочного тестирования с InfluxDB и Grafana
Всевидящее око. Мониторинг нагрузочного тестирования с InfluxDB и Grafana
 
Deployment to production with an unexpected load
Deployment to production with an unexpected loadDeployment to production with an unexpected load
Deployment to production with an unexpected load
 
Что нам стоит DAL построить? Акуляков Артём D2D Just.NET
Что нам стоит DAL построить? Акуляков Артём D2D Just.NETЧто нам стоит DAL построить? Акуляков Артём D2D Just.NET
Что нам стоит DAL построить? Акуляков Артём D2D Just.NET
 
Service Discovery. More that it seems
Service Discovery. More that it seemsService Discovery. More that it seems
Service Discovery. More that it seems
 
Переезжаем с Zabbix на Prometheus / Василий Озеров (fevlake)
Переезжаем с Zabbix на Prometheus / Василий Озеров (fevlake)Переезжаем с Zabbix на Prometheus / Василий Озеров (fevlake)
Переезжаем с Zabbix на Prometheus / Василий Озеров (fevlake)
 
Ядро автоматизации под микро-сервисную архитектуру
Ядро автоматизации под микро-сервисную архитектуруЯдро автоматизации под микро-сервисную архитектуру
Ядро автоматизации под микро-сервисную архитектуру
 
10M tests per day
10M tests per day10M tests per day
10M tests per day
 
Эволюционный дизайн. Joker Students Day 2016
Эволюционный дизайн. Joker Students Day 2016Эволюционный дизайн. Joker Students Day 2016
Эволюционный дизайн. Joker Students Day 2016
 
Continuous Delivery with Jenkins: Lessons Learned
Continuous Delivery with Jenkins: Lessons LearnedContinuous Delivery with Jenkins: Lessons Learned
Continuous Delivery with Jenkins: Lessons Learned
 
Олег Миколайченко "Как перестать хранить секреты в git и начать использовать ...
Олег Миколайченко "Как перестать хранить секреты в git и начать использовать ...Олег Миколайченко "Как перестать хранить секреты в git и начать использовать ...
Олег Миколайченко "Как перестать хранить секреты в git и начать использовать ...
 
Joker 2015. WILD microSERVICES
Joker 2015. WILD microSERVICESJoker 2015. WILD microSERVICES
Joker 2015. WILD microSERVICES
 

Viewers also liked

PostgreSQL and JDBC: striving for high performance
PostgreSQL and JDBC: striving for high performancePostgreSQL and JDBC: striving for high performance
PostgreSQL and JDBC: striving for high performanceVladimir Sitnikov
 
Семантика final полей в java
Семантика final полей в javaСемантика final полей в java
Семантика final полей в javaVladimir Sitnikov
 
High Performance Jdbc
High Performance JdbcHigh Performance Jdbc
High Performance JdbcSam Pattsin
 
67 - Spring. Начальные знания
67 - Spring. Начальные знания67 - Spring. Начальные знания
67 - Spring. Начальные знанияRoman Brovko
 
Контроль за стилем кода — Кирилл Борисов
Контроль за стилем кода — Кирилл БорисовКонтроль за стилем кода — Кирилл Борисов
Контроль за стилем кода — Кирилл БорисовYandex
 
Григорий Липин: Автоматизация нагрузочного тестирования
Григорий Липин: Автоматизация нагрузочного тестированияГригорий Липин: Автоматизация нагрузочного тестирования
Григорий Липин: Автоматизация нагрузочного тестированияYandex
 
«CI. Jenkins. 2GIS» — Игорь Павлов, 2ГИС
«CI. Jenkins. 2GIS» — Игорь Павлов, 2ГИС «CI. Jenkins. 2GIS» — Игорь Павлов, 2ГИС
«CI. Jenkins. 2GIS» — Игорь Павлов, 2ГИС DevDay
 
Дмитрий Пронин – Python для веба
Дмитрий Пронин – Python для вебаДмитрий Пронин – Python для веба
Дмитрий Пронин – Python для вебаYandex
 
Openstack Third-Party CI and the review of a few Openstack Infrastructure pro...
Openstack Third-Party CI and the review of a few Openstack Infrastructure pro...Openstack Third-Party CI and the review of a few Openstack Infrastructure pro...
Openstack Third-Party CI and the review of a few Openstack Infrastructure pro...Evgeny Antyshev
 
Developing PostgreSQL Performance, Simon Riggs
Developing PostgreSQL Performance, Simon RiggsDeveloping PostgreSQL Performance, Simon Riggs
Developing PostgreSQL Performance, Simon RiggsFuenteovejuna
 
jobDSL plugin: настройка jenkins ci скриптом
jobDSL plugin: настройка jenkins ci скриптомjobDSL plugin: настройка jenkins ci скриптом
jobDSL plugin: настройка jenkins ci скриптомVasilii Chernov
 
Разработка Enterprise-приложения на основе Spring Framework
Разработка Enterprise-приложения на основе Spring FrameworkРазработка Enterprise-приложения на основе Spring Framework
Разработка Enterprise-приложения на основе Spring FrameworkCUSTIS
 
Непрерывный анализ качества кода с помощью SonarQube
Непрерывный анализ качества кода с помощью SonarQubeНепрерывный анализ качества кода с помощью SonarQube
Непрерывный анализ качества кода с помощью SonarQubeVasilii Chernov
 
Konstantin slisenko - Spring Framework
Konstantin slisenko - Spring FrameworkKonstantin slisenko - Spring Framework
Konstantin slisenko - Spring Frameworkbeloslab
 
Highload в ВУЗе идеализм, расчётливый менеджмент или пустые надежды / Артем К...
Highload в ВУЗе идеализм, расчётливый менеджмент или пустые надежды / Артем К...Highload в ВУЗе идеализм, расчётливый менеджмент или пустые надежды / Артем К...
Highload в ВУЗе идеализм, расчётливый менеджмент или пустые надежды / Артем К...Ontico
 
Ceph BlueStore - новый тип хранилища в Ceph / Максим Воронцов, (Redsys)
Ceph BlueStore - новый тип хранилища в Ceph / Максим Воронцов, (Redsys)Ceph BlueStore - новый тип хранилища в Ceph / Максим Воронцов, (Redsys)
Ceph BlueStore - новый тип хранилища в Ceph / Максим Воронцов, (Redsys)Ontico
 
66 - Spring. Spring и JSF
66 - Spring. Spring и JSF66 - Spring. Spring и JSF
66 - Spring. Spring и JSFRoman Brovko
 
Apache Camel + Apache ActiveMQ persistence
Apache Camel + Apache ActiveMQ persistenceApache Camel + Apache ActiveMQ persistence
Apache Camel + Apache ActiveMQ persistenceIlya Lapitan
 
Движение по хрупкому дну / Сергей Караткевич (servers.ru)
Движение по хрупкому дну / Сергей Караткевич (servers.ru)Движение по хрупкому дну / Сергей Караткевич (servers.ru)
Движение по хрупкому дну / Сергей Караткевич (servers.ru)Ontico
 

Viewers also liked (20)

PostgreSQL and JDBC: striving for high performance
PostgreSQL and JDBC: striving for high performancePostgreSQL and JDBC: striving for high performance
PostgreSQL and JDBC: striving for high performance
 
Семантика final полей в java
Семантика final полей в javaСемантика final полей в java
Семантика final полей в java
 
High Performance Jdbc
High Performance JdbcHigh Performance Jdbc
High Performance Jdbc
 
67 - Spring. Начальные знания
67 - Spring. Начальные знания67 - Spring. Начальные знания
67 - Spring. Начальные знания
 
Final field semantics
Final field semanticsFinal field semantics
Final field semantics
 
Контроль за стилем кода — Кирилл Борисов
Контроль за стилем кода — Кирилл БорисовКонтроль за стилем кода — Кирилл Борисов
Контроль за стилем кода — Кирилл Борисов
 
Григорий Липин: Автоматизация нагрузочного тестирования
Григорий Липин: Автоматизация нагрузочного тестированияГригорий Липин: Автоматизация нагрузочного тестирования
Григорий Липин: Автоматизация нагрузочного тестирования
 
«CI. Jenkins. 2GIS» — Игорь Павлов, 2ГИС
«CI. Jenkins. 2GIS» — Игорь Павлов, 2ГИС «CI. Jenkins. 2GIS» — Игорь Павлов, 2ГИС
«CI. Jenkins. 2GIS» — Игорь Павлов, 2ГИС
 
Дмитрий Пронин – Python для веба
Дмитрий Пронин – Python для вебаДмитрий Пронин – Python для веба
Дмитрий Пронин – Python для веба
 
Openstack Third-Party CI and the review of a few Openstack Infrastructure pro...
Openstack Third-Party CI and the review of a few Openstack Infrastructure pro...Openstack Third-Party CI and the review of a few Openstack Infrastructure pro...
Openstack Third-Party CI and the review of a few Openstack Infrastructure pro...
 
Developing PostgreSQL Performance, Simon Riggs
Developing PostgreSQL Performance, Simon RiggsDeveloping PostgreSQL Performance, Simon Riggs
Developing PostgreSQL Performance, Simon Riggs
 
jobDSL plugin: настройка jenkins ci скриптом
jobDSL plugin: настройка jenkins ci скриптомjobDSL plugin: настройка jenkins ci скриптом
jobDSL plugin: настройка jenkins ci скриптом
 
Разработка Enterprise-приложения на основе Spring Framework
Разработка Enterprise-приложения на основе Spring FrameworkРазработка Enterprise-приложения на основе Spring Framework
Разработка Enterprise-приложения на основе Spring Framework
 
Непрерывный анализ качества кода с помощью SonarQube
Непрерывный анализ качества кода с помощью SonarQubeНепрерывный анализ качества кода с помощью SonarQube
Непрерывный анализ качества кода с помощью SonarQube
 
Konstantin slisenko - Spring Framework
Konstantin slisenko - Spring FrameworkKonstantin slisenko - Spring Framework
Konstantin slisenko - Spring Framework
 
Highload в ВУЗе идеализм, расчётливый менеджмент или пустые надежды / Артем К...
Highload в ВУЗе идеализм, расчётливый менеджмент или пустые надежды / Артем К...Highload в ВУЗе идеализм, расчётливый менеджмент или пустые надежды / Артем К...
Highload в ВУЗе идеализм, расчётливый менеджмент или пустые надежды / Артем К...
 
Ceph BlueStore - новый тип хранилища в Ceph / Максим Воронцов, (Redsys)
Ceph BlueStore - новый тип хранилища в Ceph / Максим Воронцов, (Redsys)Ceph BlueStore - новый тип хранилища в Ceph / Максим Воронцов, (Redsys)
Ceph BlueStore - новый тип хранилища в Ceph / Максим Воронцов, (Redsys)
 
66 - Spring. Spring и JSF
66 - Spring. Spring и JSF66 - Spring. Spring и JSF
66 - Spring. Spring и JSF
 
Apache Camel + Apache ActiveMQ persistence
Apache Camel + Apache ActiveMQ persistenceApache Camel + Apache ActiveMQ persistence
Apache Camel + Apache ActiveMQ persistence
 
Движение по хрупкому дну / Сергей Караткевич (servers.ru)
Движение по хрупкому дну / Сергей Караткевич (servers.ru)Движение по хрупкому дну / Сергей Караткевич (servers.ru)
Движение по хрупкому дну / Сергей Караткевич (servers.ru)
 

Similar to Проблемы производительности open source библиотек

Jenkins 2.0: Организуем тестирование в составе Continuous Delivery
Jenkins 2.0: Организуем тестирование в составе Continuous DeliveryJenkins 2.0: Организуем тестирование в составе Continuous Delivery
Jenkins 2.0: Организуем тестирование в составе Continuous DeliverySQALab
 
Moscow Jenkins Meetup #1. Pipeline для инженеров. Обзор экосистемы
Moscow Jenkins Meetup #1. Pipeline для инженеров. Обзор экосистемыMoscow Jenkins Meetup #1. Pipeline для инженеров. Обзор экосистемы
Moscow Jenkins Meetup #1. Pipeline для инженеров. Обзор экосистемыOleg Nenashev
 
Леонид Васильев "Python в инфраструктуре поиска"
Леонид Васильев "Python в инфраструктуре поиска"Леонид Васильев "Python в инфраструктуре поиска"
Леонид Васильев "Python в инфраструктуре поиска"Yandex
 
Асинхронность и сопрограммы
Асинхронность и сопрограммыАсинхронность и сопрограммы
Асинхронность и сопрограммыPlatonov Sergey
 
Drupal code sprint для новичков
Drupal code sprint для новичковDrupal code sprint для новичков
Drupal code sprint для новичковOvadiah Myrgorod
 
Где кончается react native? / Павел Кондратенко (Rambler&Co)
Где кончается react native? / Павел Кондратенко (Rambler&Co)Где кончается react native? / Павел Кондратенко (Rambler&Co)
Где кончается react native? / Павел Кондратенко (Rambler&Co)Ontico
 
Unsafe: to be or to be removed?
Unsafe: to be or to be removed?Unsafe: to be or to be removed?
Unsafe: to be or to be removed?Alexey Fyodorov
 
Борис Павлович - Производительность и масштабируемость OpenStack
Борис Павлович - Производительность и масштабируемость OpenStack Борис Павлович - Производительность и масштабируемость OpenStack
Борис Павлович - Производительность и масштабируемость OpenStack Yandex
 
Регрессионное тестирование на lenta.ru, Кондратенко Павел, Rambler&Co, Moscow...
Регрессионное тестирование на lenta.ru, Кондратенко Павел, Rambler&Co, Moscow...Регрессионное тестирование на lenta.ru, Кондратенко Павел, Rambler&Co, Moscow...
Регрессионное тестирование на lenta.ru, Кондратенко Павел, Rambler&Co, Moscow...MoscowJS
 
Easy authcache 2 кеширование для pro родионов игорь
Easy authcache 2   кеширование для pro родионов игорьEasy authcache 2   кеширование для pro родионов игорь
Easy authcache 2 кеширование для pro родионов игорьdrupalconf
 
Тестируй это / Виктор Русакович (GP Solutions)
Тестируй это / Виктор Русакович (GP Solutions)Тестируй это / Виктор Русакович (GP Solutions)
Тестируй это / Виктор Русакович (GP Solutions)Ontico
 
GitLab, Prometheus и Grafana с Kubernetes
GitLab, Prometheus и Grafana с KubernetesGitLab, Prometheus и Grafana с Kubernetes
GitLab, Prometheus и Grafana с KubernetesVictor Login
 
Инфраструктура распределенных приложений на Node.js
Инфраструктура распределенных приложений на Node.jsИнфраструктура распределенных приложений на Node.js
Инфраструктура распределенных приложений на Node.jsStanislav Gumeniuk
 
"Непрерывная интеграция или "Кто всё сломал?", Виктор Русакович, MoscowJS 23
"Непрерывная интеграция или "Кто всё сломал?", Виктор Русакович, MoscowJS 23"Непрерывная интеграция или "Кто всё сломал?", Виктор Русакович, MoscowJS 23
"Непрерывная интеграция или "Кто всё сломал?", Виктор Русакович, MoscowJS 23MoscowJS
 
Zero Downtime PHP Deployment with Envoyer And Forge
Zero Downtime PHP Deployment with Envoyer And ForgeZero Downtime PHP Deployment with Envoyer And Forge
Zero Downtime PHP Deployment with Envoyer And ForgeYehor Herasymchuk
 
Алексей Ильенко "In real-time with Apache Kafka"
Алексей Ильенко "In real-time with Apache Kafka"Алексей Ильенко "In real-time with Apache Kafka"
Алексей Ильенко "In real-time with Apache Kafka"Fwdays
 
Easy authcache 2 кэширование для pro. Родионов Игорь
Easy authcache 2   кэширование для pro. Родионов ИгорьEasy authcache 2   кэширование для pro. Родионов Игорь
Easy authcache 2 кэширование для pro. Родионов ИгорьPVasili
 
Multithreading in java past and actual
Multithreading in java past and actualMultithreading in java past and actual
Multithreading in java past and actualYevgen Levik
 
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#Andrey Karpov
 
Поговорим про память
Поговорим про памятьПоговорим про память
Поговорим про памятьAndrey Akinshin
 

Similar to Проблемы производительности open source библиотек (20)

Jenkins 2.0: Организуем тестирование в составе Continuous Delivery
Jenkins 2.0: Организуем тестирование в составе Continuous DeliveryJenkins 2.0: Организуем тестирование в составе Continuous Delivery
Jenkins 2.0: Организуем тестирование в составе Continuous Delivery
 
Moscow Jenkins Meetup #1. Pipeline для инженеров. Обзор экосистемы
Moscow Jenkins Meetup #1. Pipeline для инженеров. Обзор экосистемыMoscow Jenkins Meetup #1. Pipeline для инженеров. Обзор экосистемы
Moscow Jenkins Meetup #1. Pipeline для инженеров. Обзор экосистемы
 
Леонид Васильев "Python в инфраструктуре поиска"
Леонид Васильев "Python в инфраструктуре поиска"Леонид Васильев "Python в инфраструктуре поиска"
Леонид Васильев "Python в инфраструктуре поиска"
 
Асинхронность и сопрограммы
Асинхронность и сопрограммыАсинхронность и сопрограммы
Асинхронность и сопрограммы
 
Drupal code sprint для новичков
Drupal code sprint для новичковDrupal code sprint для новичков
Drupal code sprint для новичков
 
Где кончается react native? / Павел Кондратенко (Rambler&Co)
Где кончается react native? / Павел Кондратенко (Rambler&Co)Где кончается react native? / Павел Кондратенко (Rambler&Co)
Где кончается react native? / Павел Кондратенко (Rambler&Co)
 
Unsafe: to be or to be removed?
Unsafe: to be or to be removed?Unsafe: to be or to be removed?
Unsafe: to be or to be removed?
 
Борис Павлович - Производительность и масштабируемость OpenStack
Борис Павлович - Производительность и масштабируемость OpenStack Борис Павлович - Производительность и масштабируемость OpenStack
Борис Павлович - Производительность и масштабируемость OpenStack
 
Регрессионное тестирование на lenta.ru, Кондратенко Павел, Rambler&Co, Moscow...
Регрессионное тестирование на lenta.ru, Кондратенко Павел, Rambler&Co, Moscow...Регрессионное тестирование на lenta.ru, Кондратенко Павел, Rambler&Co, Moscow...
Регрессионное тестирование на lenta.ru, Кондратенко Павел, Rambler&Co, Moscow...
 
Easy authcache 2 кеширование для pro родионов игорь
Easy authcache 2   кеширование для pro родионов игорьEasy authcache 2   кеширование для pro родионов игорь
Easy authcache 2 кеширование для pro родионов игорь
 
Тестируй это / Виктор Русакович (GP Solutions)
Тестируй это / Виктор Русакович (GP Solutions)Тестируй это / Виктор Русакович (GP Solutions)
Тестируй это / Виктор Русакович (GP Solutions)
 
GitLab, Prometheus и Grafana с Kubernetes
GitLab, Prometheus и Grafana с KubernetesGitLab, Prometheus и Grafana с Kubernetes
GitLab, Prometheus и Grafana с Kubernetes
 
Инфраструктура распределенных приложений на Node.js
Инфраструктура распределенных приложений на Node.jsИнфраструктура распределенных приложений на Node.js
Инфраструктура распределенных приложений на Node.js
 
"Непрерывная интеграция или "Кто всё сломал?", Виктор Русакович, MoscowJS 23
"Непрерывная интеграция или "Кто всё сломал?", Виктор Русакович, MoscowJS 23"Непрерывная интеграция или "Кто всё сломал?", Виктор Русакович, MoscowJS 23
"Непрерывная интеграция или "Кто всё сломал?", Виктор Русакович, MoscowJS 23
 
Zero Downtime PHP Deployment with Envoyer And Forge
Zero Downtime PHP Deployment with Envoyer And ForgeZero Downtime PHP Deployment with Envoyer And Forge
Zero Downtime PHP Deployment with Envoyer And Forge
 
Алексей Ильенко "In real-time with Apache Kafka"
Алексей Ильенко "In real-time with Apache Kafka"Алексей Ильенко "In real-time with Apache Kafka"
Алексей Ильенко "In real-time with Apache Kafka"
 
Easy authcache 2 кэширование для pro. Родионов Игорь
Easy authcache 2   кэширование для pro. Родионов ИгорьEasy authcache 2   кэширование для pro. Родионов Игорь
Easy authcache 2 кэширование для pro. Родионов Игорь
 
Multithreading in java past and actual
Multithreading in java past and actualMultithreading in java past and actual
Multithreading in java past and actual
 
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#
PVS-Studio. Статический анализатор кода. Windows/Linux, C/C++/C#
 
Поговорим про память
Поговорим про памятьПоговорим про память
Поговорим про память
 

Проблемы производительности open source библиотек

  • 1. © Netcracker 2016 1 Производительность open source решений Владимир Ситников JPoint 2016
  • 2. © Netcracker 2016 2 •Владимир Ситников •Инженер по производительности в Netcracker, 10 лет •sitnikov@netcracker.com •@VladimirSitnikv Кто я
  • 3. © Netcracker 2016 3 •Spring •Cglib •Pgjdbc •HornetQ •Wildfly •Jenkins План
  • 4. © Netcracker 2016 4 План Наш любимый enterprise продукт
  • 5. © Netcracker 2016 5 Внедряем Spring в сжатые сроки Монолит spring
  • 6. © Netcracker 2016 6 Внедряем Spring в сжатые сроки Монолит spring
  • 7. © Netcracker 2016 7 Внедряем Spring в сжатые сроки Core Security UI
  • 8. © Netcracker 2016 8 Внедряем Spring в сжатые сроки Core Security UI
  • 9. © Netcracker 2016 9 Внедряем Spring в сжатые сроки Core Security UI
  • 10. © Netcracker 2016 10 •Когда нужен бин, то выполняем beanFactory.getBean(Security.class) В UI spring пока не наступил
  • 11. © Netcracker 2016 11 •Когда нужен бин, то выполняем beanFactory.getBean(Security.class) •Но где взять beanFactory? В UI spring пока не наступил
  • 12. © Netcracker 2016 12 •Когда нужен бин, то выполняем beanFactory.getBean(Security.class) •Но где взять beanFactory? •Правильно, Паблик Морозов поможет нам В UI spring пока не наступил
  • 13. © Netcracker 2016 13 public class AppContext implements BeanFactoryAware { static public BeanFactory beanFactory; ... Получаем бин
  • 14. © Netcracker 2016 14 public class AppContext implements BeanFactoryAware { static public BeanFactory beanFactory; ... AppContext.beanFactory.getBean(Security.class) Получаем бин
  • 15. © Netcracker 2016 15 •Работает Spring.getBean
  • 16. © Netcracker 2016 16 •Работает •Но медленно-медленно Spring.getBean
  • 17. © Netcracker 2016 17 •Работает •Но медленно-медленно •На getBean и 50% времени может уходить Spring.getBean
  • 18. © Netcracker 2016 18 •Java Flight Recorder Подходящие для анализа инструменты
  • 19. © Netcracker 2016 19 •Java Flight Recorder •kill -3 profiler (poormansprofiler.org) Подходящие для анализа инструменты
  • 20. © Netcracker 2016 20 •Java Flight Recorder •kill -3 profiler (poormansprofiler.org) •Инструментирующий профилировщик. Например самописный, настроенный на getBean Подходящие для анализа инструменты
  • 21. © Netcracker 2016 21 160 секунд на getBean. Здорово?
  • 22. © Netcracker 2016 22 160 секунд на getBean. Здорово? •Java 8 / Spring 4.1.7
  • 23. © Netcracker 2016 23 •SPR-6870 Cache by-type lookups in DefaultListableBeanFactory Проверяем известные проблемы
  • 24. © Netcracker 2016 24 •SPR-6870 Cache by-type lookups in DefaultListableBeanFactory Проверяем известные проблемы ЯЗЬ!!!
  • 25. © Netcracker 2016 25 •SPR-6870 Cache by-type lookups in DefaultListableBeanFactory •Fix version: 3.2 M1, а у нас 4.1+  Проверяем известные проблемы
  • 26. © Netcracker 2016 26 Flight Recorder, allocations in new TLAB
  • 27. © Netcracker 2016 27 protected Object getCacheKey( Class<?> beanClass, String beanName) { return beanClass.getName() + "_" + beanName; } AbstractAutoProxyCreator
  • 28. © Netcracker 2016 28 protected Object getCacheKey( Class<?> beanClass, String beanName) { return beanClass.getName() + "_" + beanName; } AbstractAutoProxyCreator
  • 29. © Netcracker 2016 29 protected Object getCacheKey( Class<?> beanClass, String beanName) { return beanName == null ? beanClass : ...; } github.com/spring-projects/spring- framework/pull/913 AbstractAutoProxyCreator
  • 30. © Netcracker 2016 30 public class SharedSecrets { @Inject public Security security; @PostConstruct public void init() { INSTANCE = this; } public static volatile SharedSecrets INSTANCE; Как выжить без обновления Spring?
  • 31. © Netcracker 2016 31 •Не стоит злоупотреблять prototype bean’ами. Если singleton, то singleton Prototype vs singleton
  • 32. © Netcracker 2016 32 •Не стоит злоупотреблять prototype bean’ами. Если singleton, то singleton •Замена getBean на javax.inject.Provider<...> лишь ухудшает время работы • Prototype vs singleton
  • 33. © Netcracker 2016 33 @Pointcut( "execution( public* my.service.*ServiceImpl.*(..))” ) Spring AOP
  • 34. © Netcracker 2016 34 •OutOfMemory: perm gen Spring AOP
  • 35. © Netcracker 2016 35 •OutOfMemory: perm gen •В хипдампе куча java.lang.reflect.Method Spring AOP
  • 36. © Netcracker 2016 36 •OutOfMemory: perm gen •В хипдампе куча java.lang.reflect.Method •Method’ы занимают 100-500MiB Spring AOP
  • 37. © Netcracker 2016 37 •OutOfMemory: perm gen •В хипдампе куча java.lang.reflect.Method •Method’ы занимают 100-500MiB •Все они лежат в AspectJExpressionPointcut Spring AOP
  • 38. © Netcracker 2016 38 @Pointcut( "execution( public* my.service.*ServiceImpl.*(..))” ) Spring AOP
  • 39. © Netcracker 2016 39 •Решение: добавлять within(my.package.service.business..*) Spring AOP vs AspectJ
  • 40. © Netcracker 2016 40 •Решение: добавлять within(my.package.service.business..*) •Разумеется, AspectJ рекомендуют использовать within всегда: http://dev.eclipse.org/mhonarc/lists/aspectj- users/msg10969.html • Spring AOP vs AspectJ
  • 41. © Netcracker 2016 41 •Cglib используется много где: рукотворный код, тот же Spring Cglib
  • 42. © Netcracker 2016 42 •Cglib используется много где: рукотворный код, тот же Spring •Наверняка уже всё исправлено давным- давно Cglib
  • 43. © Netcracker 2016 43 •Cglib используется много где: рукотворный код, тот же Spring •Наверняка уже всё исправлено давным- давно •Наверняка туда давно никто не заглядывал Cglib
  • 44. © Netcracker 2016 44 @Benchmark public Object newProxy() { return Beans.newProxy(Beans.class); } Cglib: замеряем
  • 45. © Netcracker 2016 45 0 2 4 6 8 10 12 14 16 18 Cglib 3.1 1 поток 2 потока 4 потока 8 потоков Замеры Cglib, μs/opБыстрее
  • 46. © Netcracker 2016 46 0 2 4 6 8 10 12 14 16 18 Cglib 3.1 Cglib 3.2.2 1 поток 2 потока 4 потока 8 потоков Замеры Cglib, μs/opБыстрее
  • 47. © Netcracker 2016 47 Benchmark Score newProxy 2.1 ± 0.3 μs/op newProxy.alloc.rate 1240 B/op Стало newProxy 0.14 ± 0.02 μs/op newProxy.alloc.rate 256 B/op Cglib 3.2.2: ждём в очередном Spring
  • 48. © Netcracker 2016 48 •Skip finalize while building proxy https://github.com/cglib/cglib/pull/51 •Concurrent cache of generated classes https://github.com/cglib/cglib/pull/53 План захвата Cglib
  • 49. © Netcracker 2016 49 •А, может, ну его этот cglib, есть же быстрый ByteBuddy? Но есть же ByteBuddy
  • 50. © Netcracker 2016 50 •А, может, ну его этот cglib, есть же быстрый ByteBuddy? @Benchmark public ExampleClass benchmarkCglib() { Enhancer enhancer = new Enhancer(); enhancer.setUseCache(false); ByteBuddy, jmh тест
  • 51. © Netcracker 2016 51 •А, может, ну его этот cglib, есть же быстрый ByteBuddy? @Benchmark public ExampleClass benchmarkCglib() { Enhancer enhancer = new Enhancer(); enhancer.setUseCache(false); ByteBuddy, jmh тест
  • 52. © Netcracker 2016 52 •JMH тесты в ByteBuddy показывают скорость создания классов •Постоянно создавать классы нехорошо •Значит, нужно измерять скорость кэшированного обращения ByteBuddy, jmh тест
  • 53. © Netcracker 2016 53 •КО: «Бери pgjdbc» Подключаемся к PostgreSQL
  • 54. © Netcracker 2016 54 •КО: «Бери pgjdbc» •КО: «Используй batch statements» Подключаемся к PostgreSQL
  • 55. © Netcracker 2016 55 •КО: «Бери pgjdbc» •КО: «Используй batch statements» •Что может пойти не так? Подключаемся к PostgreSQL
  • 56. © Netcracker 2016 56 Connection con = ...; PreparedStatement ps = con.prepareStatement("SELECT..."); ... ps.close(); PreparedStatement
  • 57. © Netcracker 2016 57 Connection con = ...; PreparedStatement ps = con.prepareStatement("SELECT..."); ... ps.close(); PreparedStatement
  • 58. © Netcracker 2016 58 PARSE S_1 as ...; // con.prepareStmt BIND/EXEC DEALLOCATE // ps.close() PARSE S_2 as ...; BIND/EXEC DEALLOCATE // ps.close() Работа с PostgreSQL курильщика
  • 59. © Netcracker 2016 59 PARSE S_1 as ...;  BIND/EXEC BIND/EXEC BIND/EXEC  BIND/EXEC BIND/EXEC ... DEALLOCATE Работа с PostgreSQL здорового человека
  • 60. © Netcracker 2016 60 PARSE S_1 as ...;  1 раз в жизни BIND/EXEC  обработка REST BIND/EXEC BIND/EXEC  ещё REST BIND/EXEC BIND/EXEC ... DEALLOCATE  желательно «никогда» DEALLOCATE Работа с PostgreSQL здорового человека
  • 61. © Netcracker 2016 61 Вывод: чтобы работало быстрее, закрывать statement’ы не нужно ps = con.prepareStatement(...) ps.execueQuery(); ps = con.prepareStatement(...) ps.execueQuery(); ... Счастливые statement’ов не закрывают
  • 62. © Netcracker 2016 62 Вывод: чтобы работало быстрее, закрывать statement’ы не нужно ps = con.prepare... ps.execueQuery(); ps = con.prepare... ps.execueQuery(); ... Счастливые statement’ов не закрывают
  • 63. © Netcracker 2016 63 @Benchmark public Statement leakStatement() { return con.createStatement(); } pgjdbc < 9.4.1202, -Xmx128m, OracleJDK 1.8u40 # Warmup Iteration 1: 1147,070 ns/op # Warmup Iteration 2: 12101,537 ns/op # Warmup Iteration 3: 90825,971 ns/op # Warmup Iteration 4: <failure> java.lang.OutOfMemoryError: GC overhead limit exceeded OpenJDK: не все JRE одинаково полезны
  • 64. © Netcracker 2016 64 @Benchmark public Statement leakStatement() { return con.createStatement(); } pgjdbc >= 9.4.1202, -Xmx128m, OracleJDK 1.8u40 # Warmup Iteration 1: 30 ns/op # Warmup Iteration 2: 27 ns/op ... github.com/pgjdbc/pgjdbc/pull/299 Убираем finalize из класса PgConnection
  • 65. © Netcracker 2016 65 Вывод: чтобы работало быстро, нужно как-то кэшировать statement’ы ps = con.prepareStatement("select id, name ..."); ps.execueQuery(); ps.close(); ps2 = con.prepareStatement("select id, name ..."); Счастливые statement’ов не закрывают
  • 66. © Netcracker 2016 66 •Кэш запросов появился в версии 9.4.1202 (2015-08-27) см. https://github.com/pgjdbc/pgjdbc/pull/319 Кэш запросов в PgJDBC
  • 67. © Netcracker 2016 67 •Кэш запросов появился в версии 9.4.1202 (2015-08-27) см. https://github.com/pgjdbc/pgjdbc/pull/319 •Работает прозрачно для приложения Кэш запросов в PgJDBC
  • 68. © Netcracker 2016 68 •Кэш запросов появился в версии 9.4.1202 (2015-08-27) см. https://github.com/pgjdbc/pgjdbc/pull/319 •Работает прозрачно для приложения •Скорость такая, что PL/PgSQL не нужен Кэш запросов в PgJDBC
  • 69. © Netcracker 2016 69 •Кэш запросов появился в версии 9.4.1202 (2015-08-27) см. https://github.com/pgjdbc/pgjdbc/pull/319 •Работает прозрачно для приложения •Скорость такая, что PL/PgSQL не нужен •Server-prepare активируется после 5-го выполнения (prepareThreshold) Кэш запросов в PgJDBC
  • 70. © Netcracker 2016 70 •Конечно, затраты planning time напрямую зависят от сложности запросов Цифры где?
  • 71. © Netcracker 2016 71 •Конечно, затраты planning time напрямую зависят от сложности запросов •У нас доходило до 20мс+ planning time на OLTP запросах: 10КиБ запрос, 170 строк explain • Цифры где?
  • 72. © Netcracker 2016 72 •Конечно, затраты planning time напрямую зависят от сложности запросов •У нас доходило до 20мс+ planning time на OLTP запросах: 10КиБ запрос, 170 строк explain •Стало ~0мс Цифры где?
  • 73. © Netcracker 2016 73 Если типы параметров меняются, то server- prepared statement приходится менять ps.setInt(1, 42); ... ps.setNull(1, Types.VARCHAR); JDBC: Типы параметров
  • 74. © Netcracker 2016 74 Если типы параметров меняются, то server- prepared statement приходится менять ps.setInt(1, 42); ... ps.setNull(1, Types.VARCHAR); JDBC: Типы параметров
  • 75. © Netcracker 2016 75 •Вывод: даже у NULL’ов должен быть верный тип JDBC: Тип параметров изменять нельзя
  • 76. © Netcracker 2016 76 •Вывод: даже у NULL’ов должен быть верный тип •Ещё раз: setObject(1, null) использовать нельзя JDBC: Тип параметров изменять нельзя
  • 77. © Netcracker 2016 77 •Перешли на prepared, и запрос замедлился в 5'000 раз. Как так? Нежданчик
  • 78. © Netcracker 2016 78 •Перешли на prepared, и запрос замедлился в 5'000 раз. Как так? Нежданчик A. Бага C. Фича B. Фича D. Бага
  • 79. © Netcracker 2016 79 https://gist.github.com/vlsi -> 01_plan_flipper.sql select * from plan_flipper -- <- таблица where skewed = 0 -- 1 млн строк and non_skewed = 42 -- 20 строк Нежданчик
  • 80. © Netcracker 2016 80 https://gist.github.com/vlsi -> 01_plan_flipper.sql 0.1мс  1-е выполнение 0.05мс  2-е выполнение 0.05мс  3-е выполнение 0.05мс  4-е выполнение 0.05мс  5-е выполнение 250 мс  6-е выполнение Нежданчик
  • 81. © Netcracker 2016 81 https://gist.github.com/vlsi -> 01_plan_flipper.sql 0.1мс  1-е выполнение 0.05мс  2-е выполнение 0.05мс  3-е выполнение 0.05мс  4-е выполнение 0.05мс  5-е выполнение 250 мс  6-е выполнение Нежданчик
  • 82. © Netcracker 2016 82 Запрещаем использование индекса через +0: select * from plan_flipper where skewed+0 = 0  ~ /*+no_index*/ and non_skewed = 42 Чиним
  • 83. © Netcracker 2016 83 Как сделать опциональные фичи? •NO_RESULTS •BOTH_ROWS_AND_STATUS •DESCRIBE_ONLY Фичи
  • 84. © Netcracker 2016 84 Конечно, enum! enum ... { NO_RESULTS, BOTH_ROWS_AND_STATUS, DESCRIBE_ONLY; } Фичи
  • 85. © Netcracker 2016 85 Конечно, enum! enum ... { NO_RESULTS, BOTH_ROWS_AND_STATUS, DESCRIBE_ONLY; } А на java 1.4? Фичи
  • 86. © Netcracker 2016 86 В java 1.4, конечно, interface! interface ... { int NO_RESULTS = 1; int BOTH_ROWS_AND_STATUS = 2; int DESCRIBE_ONLY = 4; } Фичи: java 1.4 наносит ответный удар
  • 87. © Netcracker 2016 87 Меняем 1 строку, и скорость работы batch insert возрастает в 10 раз: https://github.com/pgjdbc/pgjdbc/pull/380 - static int QUERY_FORCE_DESCRIBE_PORTAL = 128; + static int QUERY_FORCE_DESCRIBE_PORTAL = 512; Ужасы нашего городка
  • 88. © Netcracker 2016 88 Меняем 1 строку, и скорость работы batch insert возрастает в 10 раз: https://github.com/pgjdbc/pgjdbc/pull/380 - static int QUERY_FORCE_DESCRIBE_PORTAL = 128; + static int QUERY_FORCE_DESCRIBE_PORTAL = 512; // оказалось, значение 128 уже было занято static int QUERY_DISALLOW_BATCHING = 128; Ужасы нашего городка
  • 89. © Netcracker 2016 89 •WildFly 8.2, JMS HornetQ
  • 90. © Netcracker 2016 90 •WildFly 8.2, JMS •Всего ~100 JMS/сек HornetQ
  • 91. © Netcracker 2016 91 •WildFly 8.2, JMS •Всего ~100 JMS/сек •1 вызов sendMessage – 5-30 секунд HornetQ
  • 92. © Netcracker 2016 92 at java.util.concurrent.Semaphore.tryAcquire at org.hornetq ... ClientProducerCreditsImpl.acquireCredits at com ... JMSSender.sendMessage kill -3 профайлер
  • 93. © Netcracker 2016 93 at java.util.concurrent.Semaphore.tryAcquire at org.hornetq ... ClientProducerCreditsImpl.acquireCredits at com ... JMSSender.sendMessage kill -3 профайлер
  • 94. © Netcracker 2016 94 at java.util.concurrent.Semaphore.tryAcquire at org.hornetq ... ClientProducerCreditsImpl.acquireCredits at com ... JMSSender.sendMessage kill -3 профайлер
  • 95. © Netcracker 2016 95 at java.util.concurrent.Semaphore.tryAcquire at org.hornetq ... ClientProducerCreditsImpl.acquireCredits at org.hornetq ... ClientProducerImpl.sendRegularMessage at com ... JMSSender.sendMessage kill -3 профайлер
  • 96. © Netcracker 2016 96 at java.util.concurrent.Semaphore.tryAcquire at org.hornetq ... ClientProducerCreditsImpl.acquireCredits at org.hornetq ... ClientProducerImpl.sendRegularMessage at org.hornetq ... ClientProducerImpl.doSend at com ... JMSSender.sendMessage kill -3 профайлер
  • 97. © Netcracker 2016 97 at java.util.concurrent.Semaphore.tryAcquire at org.hornetq ... ClientProducerCreditsImpl.acquireCredits at org.hornetq ... ClientProducerImpl.sendRegularMessage at org.hornetq ... ClientProducerImpl.doSend at org.hornetq ... ClientProducerImpl.send at com ... JMSSender.sendMessage kill -3 профайлер
  • 98. © Netcracker 2016 98 at java.util.concurrent.Semaphore.tryAcquire at org.hornetq ... ClientProducerCreditsImpl.acquireCredits at org.hornetq ... ClientProducerImpl.sendRegularMessage at org.hornetq ... ClientProducerImpl.doSend at org.hornetq ... ClientProducerImpl.send at org.hornetq ... HornetQMessageProducer.doSendx at com ... JMSSender.sendMessage kill -3 профайлер
  • 99. © Netcracker 2016 99 • 'Producer Window Size’ на connection factory Backpressure
  • 100. © Netcracker 2016 100 • 'Producer Window Size’ на connection factory • address-settings -> address-setting -> max-size-bytes Backpressure
  • 101. © Netcracker 2016 101 • 'Producer Window Size’ на connection factory • address-settings -> address-setting -> max-size-bytes • Если в JMS очереди накапливается 10МиБ, то отправка JMS начинает притормаживать Backpressure
  • 102. © Netcracker 2016 102 • 'Producer Window Size’ на connection factory • address-settings -> address-setting -> max-size-bytes • Если в JMS очереди накапливается 10МиБ, то отправка JMS начинает притормаживать <address-settings> <address-setting match="#"> <max-size-bytes>10 485 760</max-size-bytes> … Backpressure
  • 103. © Netcracker 2016 103 •Настраиваем max-size-bytes для каждой очереди Backpressure: чиним
  • 104. © Netcracker 2016 104 •Настраиваем max-size-bytes для каждой очереди •Либо смотрим в сторону RxJava Backpressure: чиним
  • 105. © Netcracker 2016 105 •Старт приложения на WF 8.2 занимает 2-5 минут WildFly: пытаемся взлететь
  • 106. © Netcracker 2016 106 •Старт приложения на WF 8.2 занимает 2-5 минут •Concurrent deploy работает плохо WildFly: пытаемся взлететь
  • 107. © Netcracker 2016 107 •Старт приложения на WF 8.2 занимает 2-5 минут •Concurrent deploy работает плохо •Spring xml app config анализирует все jar’ники WildFly: пытаемся взлететь
  • 108. © Netcracker 2016 108 •Уменьшать размер jar (исключать лишние) • WildFly копирует jar в /tmp при запуске WildFly: как чинить
  • 109. © Netcracker 2016 109 •Уменьшать размер jar (исключать лишние) • WildFly копирует jar в /tmp при запуске •Делать патчи на WF, чтобы он не складывал строки • https://github.com/jbossas/jboss-vfs/pull/25 • https://github.com/wildfly/wildfly-core/pull/1219 WildFly: как чинить
  • 110. © Netcracker 2016 110 •Уменьшать размер jar (исключать лишние) • WildFly копирует jar в /tmp при запуске •Делать патчи на WF, чтобы он не складывал строки • https://github.com/jbossas/jboss-vfs/pull/25 • https://github.com/wildfly/wildfly-core/pull/1219 •Профилировать запуск вашего WF (kill -3 profiler) WildFly: как чинить
  • 111. © Netcracker 2016 111 Самое главное в CI – переменные окружения Jenkins
  • 112. © Netcracker 2016 112 https://wiki.jenkins-ci.org/display/JENKINS/EnvInject+Plugin Jenkins: EnvInjectPlugin
  • 113. © Netcracker 2016 113 Пишем по образу и подобию: LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$ORAC LE_HOME/… PATH=$PATH:$ORACLE/bin:… Jenkins: EnvInjectPlugin
  • 114. © Netcracker 2016 114 EnvInjectEnvVars.resolveVars() Jenkins: EnvInjectPlugin
  • 115. © Netcracker 2016 115 EnvInjectEnvVars.resolveVars() -> hudson.Util.replaceMacro() Jenkins: EnvInjectPlugin
  • 116. © Netcracker 2016 116 EnvInjectEnvVars.resolveVars() -> hudson.Util.replaceMacro() -> OutOfMemoryError.<init>() Jenkins: EnvInjectPlugin
  • 117. © Netcracker 2016 117 $LD_LIBRARY_PATH:$ORACLE_HOME/lib :$ORACLE_HOME/lib:$ORACLE_HOME/lib :$ORACLE_HOME/lib:$ORACLE_HOME/lib :$ORACLE_HOME/lib:$ORACLE_HOME/lib :$ORACLE_HOME/lib:$ORACLE_HOME/lib :$ORACLE_HOME/lib:$ORACLE_HOME/lib :$ORACLE_HOME/lib:$ORACLE_HOME/lib :$ORACLE_HOME/lib:... Jenkins: EnvInjectPlugin
  • 118. © Netcracker 2016 118 https://issues.jenkins-ci.org/browse/JENKINS- 19856 ^^^ с вами с 2013 года Jenkins: EnvInjectPlugin
  • 119. © Netcracker 2016 119 •Общение Jenkins master и slave тщательно логируется Jenkins: master vs slave
  • 120. © Netcracker 2016 120 •Общение Jenkins master и slave тщательно логируется •«Разумеется», в памяти хранятся последние 1000 записей Jenkins: master vs slave
  • 121. © Netcracker 2016 121 •Общение Jenkins master и slave тщательно логируется •«Разумеется», в памяти хранятся последние 1000 записей •Н а эти логи может уходить 100-200МиБ Jenkins: master vs slave
  • 122. © Netcracker 2016 122 •Общение Jenkins master и slave тщательно логируется •«Разумеется», в памяти хранятся последние 1000 записей •Н •Да, да. Логи хранятся в памяти и никогда не попадают в файл Jenkins: master vs slave
  • 123. © Netcracker 2016 123 •Хорошо, что есть опция • -Dhudson.remoting.ExportTable.unexportLog=0 Jenkins: master vs slave
  • 124. © Netcracker 2016 124 •Хорошо, что есть опция • -Dhudson.remoting.ExportTable.unexportLog=0 •Разумеется, в Google ровно один результат Jenkins: master vs slave
  • 125. © Netcracker 2016 125 •Хорошо, что есть опция • -Dhudson.remoting.ExportTable.unexportLog=0 •Разумеется, в Google ровно один результат •На исходный код, где она определена :) Jenkins: master vs slave
  • 126. © Netcracker 2016 126 •Оказалось, что запуск master занимает 50 минут • 3000 jobs, 10-500 runs per job • 24 CPU, 64 GiB RAM • -Xmx40g Jenkins: запускаемся
  • 127. © Netcracker 2016 127 •При старте, Jenkins инициализирует job’ы Jenkins: файлы разные нужны, файлы разные важны
  • 128. © Netcracker 2016 128 •При старте, Jenkins инициализирует job’ы •Maven job загружает данные по всем запускам Jenkins: файлы разные нужны, файлы разные важны
  • 129. © Netcracker 2016 129 •При старте, Jenkins инициализирует job’ы •Maven job загружает данные по всем запускам •В каждом запуске есть fingerprint’ы, они тоже грузятся Jenkins: файлы разные нужны, файлы разные важны
  • 130. © Netcracker 2016 130 •При старте, Jenkins инициализирует job’ы •Maven job загружает данные по всем запускам •В •В итоге много-много операций с диском •и тоже грузятся Jenkins: файлы разные нужны, файлы разные важны
  • 131. © Netcracker 2016 131 •Решение в лоб: удалить fingerprint’ы перед запуском Jenkins: чиним
  • 132. © Netcracker 2016 132 •Решение в лоб: удалить fingerprint’ы перед запуском •Более сложное: не плодить fingerprint’ы Jenkins: чиним
  • 133. © Netcracker 2016 133 •Решение в лоб: удалить fingerprint’ы перед запуском •Более сложное: не плодить fingerprint’ы •Поможет и сокращение хранимой истории Jenkins: чиним
  • 134. © Netcracker 2016 134 •Решение в лоб: удалить fingerprint’ы перед запуском •Более сложное: не плодить fingerprint’ы •Поможет и сокращение хранимой истории •В идеальном мире нужно разбираться с maven-jenkins-plugin Jenkins: чиним
  • 135. © Netcracker 2016 135 Кто виноват и что делать?
  • 136. © Netcracker 2016 136 •Владимир Ситников •Инженер по производительности в Netcracker •sitnikov@netcracker.com •@VladimirSitnikv С вами был
  • 137. © Netcracker 2016 137 Вопросы?