Slide 1

Slide 1 text

«JAVA, СДЕЛАЙ МНЕ БОЛЬНО!» JAVA Егор Зиборов | Сбер 1

Slide 2

Slide 2 text

whoami 2

Slide 3

Slide 3 text

2014 МФТИ 11 лет в IT whoami 5 лет в Сбере 3

Slide 4

Slide 4 text

ПланЪ Немного контекста Немного про Spring AOP Совсем чуть-чуть про DataSource GRPC на дорожку 01 02 03 04 4

Slide 5

Slide 5 text

НЕМНОГО КОНТЕКСТА 5

Slide 6

Slide 6 text

СБОЛ жи есть Активных клиентов в месяц MAU 80млн 4000rps Количество одновременных входов в приложение 6

Slide 7

Slide 7 text

СБОЛ жи есть СБОЛ КАРТЫ ВКЛАДЫ КРЕДИТЫ 7

Slide 8

Slide 8 text

TechOverview Project Reactor 8

Slide 9

Slide 9 text

Disclaimer О чем? • Про опыт • Про ресерч • Про боль Для кого? • Для разработчиков • Для Ops инженеров 9

Slide 10

Slide 10 text

ОДНАЖДЫ В SPRING AOP 10

Slide 11

Slide 11 text

Новый релиз… 3 месяца разработки команды 100500 бизнес фичей 11

Slide 12

Slide 12 text

Горы-горы 12

Slide 13

Slide 13 text

Тем временем на мониторинге 13

Slide 14

Slide 14 text

Откатываем релиз… 14

Slide 15

Slide 15 text

Надо разобраться 15

Slide 16

Slide 16 text

Что за ошибки-то? HTTP 1.1 POST Cookie: JSESSION=UNEXISTED_SESSION HTTP Status: 403 Клиент BackEnd 16

Slide 17

Slide 17 text

Floating bug 17

Slide 18

Slide 18 text

Что делать-то? Как исследуем плавающие дефекты? Локализуем: o Один VM? o Один ExecutorService? o Один Thread? 18

Slide 19

Slide 19 text

TL курильщика 19

Slide 20

Slide 20 text

TL здорового человека 20

Slide 21

Slide 21 text

В поисках проблемы 21

Slide 22

Slide 22 text

Идем к истоку Логи заротировались… Воспроизводим ошибку еще раз Ищем первую ошибку и… 22

Slide 23

Slide 23 text

Бага в Spring? 23

Slide 24

Slide 24 text

Принятие дефекта 24

Slide 25

Slide 25 text

Что там в Spring’e? ExposeInvocationInterceptor Internal – API Возвращает предыдущее значение 25

Slide 26

Slide 26 text

Разовый провал или…? TransactionAspectSupport 26

Slide 27

Slide 27 text

Разовый провал или…? AopContext 27

Slide 28

Slide 28 text

28

Slide 29

Slide 29 text

А локи как? 29

Slide 30

Slide 30 text

StackOverflow в Java EntryFrame Frame 1 Frame 2 Frame 3 Frame 4 Yellow Zone Red Zone XSS Fatal JVM error StackOverflowError 30

Slide 31

Slide 31 text

Java решает! (с jdk 9) JEP 270: Reserved Stack Areas for Critical Sections Reserve extra space on thread stacks for use by critical sections, so that they can complete even when stack overflows occur. https://pangin.pro/posts/stack-overflow-handling EntryFrame Frame 1 Frame 2 Frame 3 Reserved Zone Yellow Zone Red Zone Fatal JVM error StackOverflowError StackOverflowError ПОСЛЕ выхода из секции 31

Slide 32

Slide 32 text

Чудо-аннотация 32

Slide 33

Slide 33 text

Чудо-фикс 33

Slide 34

Slide 34 text

А воспроизвести? 34

Slide 35

Slide 35 text

Make Java Great Again JDK-8318888 - ReentrantLock results in a locked state after StackOverflowError JDK-8319090 - StackOverflow from ThreadLocal.set might shadow the root cause 35

Slide 36

Slide 36 text

Логируй, логируй… 36

Slide 37

Slide 37 text

Логируй правильно! 37

Slide 38

Slide 38 text

Или даже так 38

Slide 39

Slide 39 text

А со ScopedValue? 39

Slide 40

Slide 40 text

А со ScopedValue? 40

Slide 41

Slide 41 text

Подождем… Тут скриншот готового ПР в jdk и картинка со дуном 41

Slide 42

Slide 42 text

• Нет StackOverFlow – нет проблем! • Мониторь StackOverflowError и OutOfMemoryError в системе • Добавлять? –XX:AbortVMOnException=java.lang.StackOverflowError Мораль 42

Slide 43

Slide 43 text

1 СОВСЕМ НЕМНОГО DATASOURCE’ОВ 43

Slide 44

Slide 44 text

У вас и БД есть? БД Зачем? o Кэш o Мастер-данные СБОЛ КАРТЫ ВКЛАДЫ КРЕДИТЫ 44

Slide 45

Slide 45 text

StandIn Что важно? o Есть резервный блок, без нагрузки o В любой момент можно перевести всю нагрузку на него Активный блок Резервный блок NGINX БД БД Репликации 45

Slide 46

Slide 46 text

DataSource – это просто Как мы все работают с DataSource 46

Slide 47

Slide 47 text

И вот однажды… Переключение в StandBy под нагрузкой Не прогретые DataSource’ы Массовое создание Connection’ов Logon Storm на БД Что произошло? 47

Slide 48

Slide 48 text

48

Slide 49

Slide 49 text

49

Slide 50

Slide 50 text

Но в DataSource же…. 50

Slide 51

Slide 51 text

Как же так…? WebSphere::Minimum connections This property defines the minimum number of physical connections that will be kept open in the free pool. When the JVM is started, WAS does not automatically create the number of connections that is defined by this property. HikariCP::minimumIdle 🔢minimumIdle This property controls the minimum number of idle connections that HikariCP tries to maintain in the pool. If the idle connections dip below this value and total connections in the pool are less than maximumPoolSize, HikariCP will make a best effort to add additional connections quickly and efficiently. However, for maximum performance and responsiveness to spike demands, we recommend not setting this value and instead allowing HikariCP to act as a fixed size connection pool. Default: same as maximumPoolSize 51

Slide 52

Slide 52 text

Грелка! CONNECTION WARMUP SLEEP 52

Slide 53

Slide 53 text

Грелка! 53

Slide 54

Slide 54 text

Грелка! 54

Slide 55

Slide 55 text

Немного рандома T1 T2 T3 T4 T5 55

Slide 56

Slide 56 text

Мораль 56

Slide 57

Slide 57 text

Мораль Есть StandBy? Проверяй “холодный” переход на него под полной нагрузкой 57

Slide 58

Slide 58 text

1 GRPC НА ДОРОЖКУ 58

Slide 59

Slide 59 text

Пара слов о 59

Slide 60

Slide 60 text

Создавай gRPC клиент генерируется на основе: o proto файл o Google либы o Gradle таск 60

Slide 61

Slide 61 text

Подключай 61

Slide 62

Slide 62 text

Используй! 62

Slide 63

Slide 63 text

Все работает! Node1 Node2 NodeN External System gRPC Connect gRPC Connect gRPC Connect Имеем: o для всех нод одна точка подключения (LoadBalancer) – ничего не знаем о его структуре o каждая нода держит один connection 63

Slide 64

Slide 64 text

Или нет… Node1 Node2 NodeN External System gRPC Connect gRPC Connect gRPC Connect Что-то случилось! o На одной из нод начались таймауты на 100% запросов Что делаем? Конечно, ребутаем! 64

Slide 65

Slide 65 text

Одним ребутом сыт не будешь Node1 Node2 NodeN gRPC Connect gRPC Connect gRPC Connect LoadBalancer POD1 POD2 POD3 65

Slide 66

Slide 66 text

Одним ребутом сыт не будешь Node1 Node2 NodeN gRPC Connect gRPC Connect gRPC Connect LoadBalancer POD1 POD2 POD3 POD2 POD3 66

Slide 67

Slide 67 text

Одним ребутом сыт не будешь Node1 Node2 NodeN gRPC Connect gRPC Connect gRPC Connect LoadBalancer POD1 POD2 POD3 POD2 POD3 67

Slide 68

Slide 68 text

ClientReconnect io.grpc.ManagedChannel 68

Slide 69

Slide 69 text

Иииииспользуем 69

Slide 70

Slide 70 text

Ииии… 70

Slide 71

Slide 71 text

gRPC ли? Node1 Node2 NodeN HTTP Connect HTTP Connect HTTP Connect LoadBalancer POD1 POD2 POD3 POD2 POD3 71

Slide 72

Slide 72 text

Мораль Есть пул соединений? Убедись, что в нем есть реконнекты 72

Slide 73

Slide 73 text

1 ИТОГИ 73

Slide 74

Slide 74 text

Выводы 1. Что такое СБОЛ 2. StackOverflow в finally блоке 3. Важность проверки переключения на StandBy 4. Важность reconnect’a внутри ConnectionPool’ов 74

Slide 75

Slide 75 text

Контакты @WinZib [email protected] 75