Доклад. Могут ли Virtual threads заменить Webflux.md
All checks were successful
continuous-integration/drone/push Build is passing
@ -5,6 +5,7 @@ aliases:
|
||||
- блокирующий вызов
|
||||
- блокирующий ввод-вывод
|
||||
- блокирующего
|
||||
- блокирующей операции
|
||||
tags:
|
||||
- maturity/🌱
|
||||
date:
|
||||
|
@ -7,6 +7,9 @@ aliases:
|
||||
- нити ос
|
||||
- нити операционной системы
|
||||
- нить ос
|
||||
- потоку
|
||||
- потоком ОС
|
||||
- потоку ОС
|
||||
tags:
|
||||
- maturity/🌱
|
||||
date: 2024-01-28
|
||||
|
25
dev/java/Java 21 LTS.md
Normal file
@ -0,0 +1,25 @@
|
||||
---
|
||||
aliases:
|
||||
- java 21
|
||||
tags:
|
||||
- maturity/🌱
|
||||
date: "[[2023-11-08]]"
|
||||
zero-link: []
|
||||
parents:
|
||||
linked:
|
||||
---
|
||||
- [[Java Virtual Threads|Java Virtual Threads]]
|
||||
***
|
||||
## Мета информация
|
||||
**Область**:: [[../../meta/zero/00 Java разработка|00 Java разработка]]
|
||||
**Родитель**::
|
||||
**Источник**::
|
||||
**Автор**::
|
||||
**Создана**:: [[2023-11-08]]
|
||||
### Дополнительные материалы
|
||||
-
|
||||
### Дочерние заметки
|
||||
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
|
||||
<!-- SerializedQuery: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
|
||||
- [[Java Virtual Threads]]
|
||||
<!-- SerializedQuery END -->
|
32
dev/java/Java Virtual Threads.md
Normal file
@ -0,0 +1,32 @@
|
||||
---
|
||||
aliases:
|
||||
- виртуальные потоки
|
||||
- виртуальный поток
|
||||
- виртуальных потоков
|
||||
tags:
|
||||
- maturity/🌱
|
||||
date: 2024-10-03
|
||||
zero-link:
|
||||
parents:
|
||||
linked:
|
||||
---
|
||||
Виртуальный поток не привязан к конкретному [[../fundamental/Поток процесса ОС|потоку ОС]]. При вызове [[../architecture/Блокирующий вызов|блокирующей операции]] Java останавливает этот поток, до момента пока его можно будет вызвать. То есть мы освобождаем настоящий поток ОС, чтобы он не простаивал.
|
||||
|
||||
![[../../../../garden/ru/meta/files/images/Pasted image 20241003081726.png]]
|
||||
|
||||
В виртуальных потоках не рекомендуется использовать ThreadLocal.
|
||||
|
||||
Виртуальный поток не поможет вам, если ваши операции требуют активной работы CPU.
|
||||
***
|
||||
## Мета информация
|
||||
**Область**:: [[../../../../garden/ru/meta/zero/00 Java разработка|00 Java разработка]]
|
||||
**Родитель**:: [[../../../../garden/ru/dev/java/Java 21 LTS|Java 21 LTS]]
|
||||
**Источник**::
|
||||
**Создана**:: [[2024-10-03]]
|
||||
**Автор**::
|
||||
### Дополнительные материалы
|
||||
- [Примеры · GitHub](https://github.com/petrelevich/jvm-digging/tree/master/virtual-thread)
|
||||
|
||||
### Дочерние заметки
|
||||
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
|
||||
|
BIN
meta/files/images/Pasted image 20241003080932.png
Normal file
After Width: | Height: | Size: 292 KiB |
BIN
meta/files/images/Pasted image 20241003081345.png
Normal file
After Width: | Height: | Size: 686 KiB |
BIN
meta/files/images/Pasted image 20241003081726.png
Normal file
After Width: | Height: | Size: 270 KiB |
BIN
meta/files/images/Pasted image 20241003083724.png
Normal file
After Width: | Height: | Size: 862 KiB |
BIN
meta/files/images/Pasted image 20241003083758.png
Normal file
After Width: | Height: | Size: 763 KiB |
BIN
meta/files/images/Pasted image 20241003084259.png
Normal file
After Width: | Height: | Size: 192 KiB |
BIN
meta/files/images/comp/Pasted image 20241003080932.png
Normal file
After Width: | Height: | Size: 72 KiB |
@ -0,0 +1 @@
|
||||
de6bbeb59e7f968b70fba8fc6cd72488
|
BIN
meta/files/images/comp/Pasted image 20241003081345.png
Normal file
After Width: | Height: | Size: 235 KiB |
@ -0,0 +1 @@
|
||||
79ae40ee77e2be2b1b3487299c015919
|
BIN
meta/files/images/comp/Pasted image 20241003081726.png
Normal file
After Width: | Height: | Size: 110 KiB |
@ -0,0 +1 @@
|
||||
f3af942d08fb6dc05ffb50dac442572a
|
BIN
meta/files/images/comp/Pasted image 20241003083724.png
Normal file
After Width: | Height: | Size: 238 KiB |
@ -0,0 +1 @@
|
||||
7c464fc07c731c74abbc8291583a205d
|
BIN
meta/files/images/comp/Pasted image 20241003083758.png
Normal file
After Width: | Height: | Size: 218 KiB |
@ -0,0 +1 @@
|
||||
de5dd568e4fd9931381d45c85ae1735a
|
BIN
meta/files/images/comp/Pasted image 20241003084259.png
Normal file
After Width: | Height: | Size: 51 KiB |
@ -0,0 +1 @@
|
||||
86bf2315bbfbc55772c532fb68d1de00
|
BIN
meta/files/images/webp/Pasted image 20241003080932.webp
Normal file
After Width: | Height: | Size: 33 KiB |
@ -0,0 +1 @@
|
||||
de6bbeb59e7f968b70fba8fc6cd72488
|
BIN
meta/files/images/webp/Pasted image 20241003081345.webp
Normal file
After Width: | Height: | Size: 71 KiB |
@ -0,0 +1 @@
|
||||
79ae40ee77e2be2b1b3487299c015919
|
BIN
meta/files/images/webp/Pasted image 20241003081726.webp
Normal file
After Width: | Height: | Size: 38 KiB |
@ -0,0 +1 @@
|
||||
f3af942d08fb6dc05ffb50dac442572a
|
BIN
meta/files/images/webp/Pasted image 20241003083724.webp
Normal file
After Width: | Height: | Size: 95 KiB |
@ -0,0 +1 @@
|
||||
7c464fc07c731c74abbc8291583a205d
|
BIN
meta/files/images/webp/Pasted image 20241003083758.webp
Normal file
After Width: | Height: | Size: 84 KiB |
@ -0,0 +1 @@
|
||||
de5dd568e4fd9931381d45c85ae1735a
|
BIN
meta/files/images/webp/Pasted image 20241003084259.webp
Normal file
After Width: | Height: | Size: 21 KiB |
@ -0,0 +1 @@
|
||||
86bf2315bbfbc55772c532fb68d1de00
|
22
meta/organizations/Т-Банк.md
Normal file
@ -0,0 +1,22 @@
|
||||
---
|
||||
aliases:
|
||||
tags:
|
||||
- maturity/🌱
|
||||
date: 2024-10-02
|
||||
zero-link:
|
||||
parents:
|
||||
linked:
|
||||
---
|
||||
|
||||
***
|
||||
## Мета информация
|
||||
**Область**::
|
||||
**Родитель**::
|
||||
**Источник**::
|
||||
**Создана**:: [[2024-10-02]]
|
||||
**Автор**::
|
||||
### Дополнительные материалы
|
||||
-
|
||||
|
||||
### Дочерние заметки
|
||||
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
|
14
meta/people/Сергей Петрелевич.md
Normal file
@ -0,0 +1,14 @@
|
||||
---
|
||||
tags:
|
||||
- type/people
|
||||
date: "[[2024-10-02]]"
|
||||
---
|
||||
**Work**::
|
||||
**Position**::
|
||||
**Создана**:: [[2024-10-02]]
|
||||
**Telegram**::
|
||||
## Упоминается в заметках
|
||||
<!-- QueryToSerialize: LIST FROM [[]] -->
|
||||
<!-- SerializedQuery: LIST FROM [[]] -->
|
||||
- [[Доклад. Могут ли Virtual threads заменить Webflux]]
|
||||
<!-- SerializedQuery END -->
|
14
meta/people/Томас Эдисон.md
Normal file
@ -0,0 +1,14 @@
|
||||
---
|
||||
tags:
|
||||
- type/people
|
||||
date: "[[2024-10-02]]"
|
||||
---
|
||||
**Work**::
|
||||
**Position**::
|
||||
**Создана**:: [[{date}]]
|
||||
**Telegram**::
|
||||
## Упоминается в заметках
|
||||
<!-- QueryToSerialize: LIST FROM [[]] -->
|
||||
<!-- SerializedQuery: LIST FROM [[]] -->
|
||||
- [[Супрахиазматическое ядро]]
|
||||
<!-- SerializedQuery END -->
|
@ -36,7 +36,7 @@ title: Java разработка
|
||||
- [Java 12](Java%2012.md)
|
||||
- [[Java 15]]
|
||||
- [[Java 17 LTS]]
|
||||
- [[Java 21 LTS]]
|
||||
- [[../../dev/java/Java 21 LTS|Java 21 LTS]]
|
||||
## Дополнительно
|
||||
- [Нативные сборки в Java](../../dev/java/Нативные%20сборки%20в%20Java.md)
|
||||
|
||||
|
14
source/00 Источники.md
Normal file
@ -0,0 +1,14 @@
|
||||
---
|
||||
tags:
|
||||
- type/zero-link
|
||||
date: 2024-10-02
|
||||
---
|
||||
Здесь собраны ссылки на заметки, в которых я анализирую прочитанный/просмотренный материал.
|
||||
## Доклады
|
||||
<!-- QueryToSerialize: LIST FROM #type/source/lecture SORT Создана DESC -->
|
||||
<!-- SerializedQuery: LIST FROM #type/source/lecture SORT Создана DESC -->
|
||||
- [[Доклад. Могут ли Virtual threads заменить Webflux]]
|
||||
- [[Доклад]]
|
||||
<!-- SerializedQuery END -->
|
||||
## Статьи
|
||||
<!-- QueryToSerialize: LIST FROM #type/source/article SORT Создана DESC -->
|
27
source/conference/Конференция. JVM Day 2024.md
Normal file
@ -0,0 +1,27 @@
|
||||
---
|
||||
aliases:
|
||||
date: 2024-10-02
|
||||
zero-link:
|
||||
parents:
|
||||
linked:
|
||||
---
|
||||
**Организатор**:: [[../../meta/organizations/Т-Банк|Т-Банк]]
|
||||
|
||||
## Доклады
|
||||
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Конференция, this.file.link) -->
|
||||
<!-- SerializedQuery: LIST FROM [[]] WHERE contains(Конференция, this.file.link) -->
|
||||
- [[Доклад. Могут ли Virtual threads заменить Webflux]]
|
||||
<!-- SerializedQuery END -->
|
||||
|
||||
***
|
||||
## Мета информация
|
||||
**Область**::
|
||||
**Родитель**:: [[../../meta/organizations/Т-Банк|Т-Банк]]
|
||||
**Источник**::
|
||||
**Создана**:: [[2024-10-02]]
|
||||
**Автор**::
|
||||
### Дополнительные материалы
|
||||
-
|
||||
|
||||
### Дочерние заметки
|
||||
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
|
@ -0,0 +1,105 @@
|
||||
---
|
||||
aliases:
|
||||
tags:
|
||||
- maturity/🌱
|
||||
- type/source/lecture
|
||||
date: 2024-10-02
|
||||
zero-link:
|
||||
parents:
|
||||
linked:
|
||||
---
|
||||
**Организатор**:: [[../../meta/organizations/Т-Банк|Т-Банк]]
|
||||
**Конференция**:: [[../conference/Конференция. JVM Day 2024|Конференция. JVM Day 2024]]
|
||||
**Автор**:: [[../../meta/people/Сергей Петрелевич|Сергей Петрелевич]]
|
||||
**Ссылка::** [Могут ли Virtual threads заменить Webflux? — Сергей Петрелевич, Squad - YouTube](https://www.youtube.com/watch?v=SOvzg-uoVco)
|
||||
|
||||
|
||||
***
|
||||
**О чем доклад:** Автор пытается понять есть ли место реактивной парадигме в современной Java, после выхода [[../../dev/java/Java Virtual Threads|виртуальных потоков]]. Для этого он проводит нагрузочное тестирование и сравнивает результаты.
|
||||
|
||||
## Тезисы
|
||||
- Прикладным разработчикам удобнее работать с абстракциями высшего порядка (Spring WebFlux, Quarkus Reactive).
|
||||
- Реактивный подход остается актуальным в некоторых задачах. Архитектору как и прежде необходимо выбирать подходящий инструмент для конкретной задачи.
|
||||
- Виртуальные потоки могут дать существенный прирост (в 2 раза) производительности существующему приложению.
|
||||
- Виртуальные потоки легко включить, от разработчика не требуется переписывать существующий код.
|
||||
- Реактивный подход (Spring WebFlux) позволит дать максимальный прирост производительности (в 3.8 раза), но за это придется заплатить.
|
||||
- [[../../../../knowledge/dev/Реактивное программирование|Реактивное программирование]] требует от разработчика изучение новой парадигмы и новых подходов: "функциональный" стиль разработки (Fluent API).
|
||||
***
|
||||
## Конспект
|
||||
Автор считает, что Java не самый эффективный язык программирования с точки зрения потребления ресурсов
|
||||
|
||||
Имеется куча вариантов оптимизации, которые автор предлагает рассмотреть. Рассматривать начинаем с двух концепций
|
||||
- [[../../dev/architecture/Один клиент — один поток|Один клиент — один поток]]
|
||||
- С таким подходов в Java быстро доходим до пределов количества потоков, которые возможно создать
|
||||
- Применим, если нагрузка на систему не большая
|
||||
- [[../../dev/architecture/Много клиентов — один поток|Много клиентов — один поток]]
|
||||
- Кажется, что это то что надо, но это не всегда так
|
||||
|
||||
Автор рассматривает [[../../dev/architecture/Event Loop|Event Loop]]. Реализация в Java: NIO Selector.
|
||||
|
||||
Можно работать напрямую с NIO, но прикладным разработчикам удобнее работать с Netty, который позволяет работать с более высокоуровневыми абстракциям, при этом сохраняя все преимущества NIO. Но есть еще более высокоуровневая абстракция поверх Netty.
|
||||
|
||||
NIO посылает события Netty их преобразовывает в более удобный вид. Далее можно сделать [[../../../../_inbox/Callback|Callback-и]], на основе этого работает Vert.x. Второй подход это использовать реактивный API: Reactor Netty. Именно этот подход автор и будет рассматривать.
|
||||
|
||||
![[../../meta/files/images/Pasted image 20241003080932.png]]
|
||||
|
||||
Можно реализовывать свои приложения сразу на Reactor Netty, но еще удобнее использовать Spring Webflux. Это реактивный функциональный (позволяет разрабатывать в функциональном стиле) http-сервер, который эффективно использует ресурсы.
|
||||
|
||||
Пример "функционального" подхода. Fluent API
|
||||
![[../../meta/files/images/Pasted image 20241003081345.png]]
|
||||
|
||||
Теперь рассмотрим [[../../dev/java/Java Virtual Threads|виртуальные потоки]], которые появились в Java 21. Один платформенный поток Java может работать со множеством клиентов одновременно. По сути виртуальный поток это объект класса, который выполняется на базе платформенного потока, который в свою очередь является фактически [[../../dev/fundamental/Поток процесса ОС|потоком ОС]].
|
||||
|
||||
![[../../../../garden/ru/meta/files/images/Pasted image 20241003081726.png]]
|
||||
|
||||
Виртуальный поток помогает с операциями, где есть [[../../dev/architecture/Блокирующий вызов|блокирующие операции]], где нужно "подождать". В таком случае ожидание практически ничего не стоит, так как виртуальный поток на это время блокируется и уступает платформенный поток другому виртуальному потоку. Но если вам нужно что-то считать, если у вас какие-то тяжелые CPU задачи, то виртуальные потоки вам не подходят.
|
||||
|
||||
Для работы с виртуальными потоками в SpingBoot достаточно включить одну проперти.
|
||||
|
||||
Примеры: [jvm-digging/virtual-thread at master · petrelevich/jvm-digging · GitHub](https://github.com/petrelevich/jvm-digging/tree/master/virtual-thread)
|
||||
|
||||
Итого, Sping WebFlux позволял нам обрабатывать множество запросов на одном потоке. И виртуальные потоки нам позволяют делать по сути то же самое. При этом не нужно разбираться в реактивной парадигме разработки. Тогда зачем нам WebFlux?
|
||||
|
||||
## Сравнение производительности
|
||||
Для этого сравним два подхода на примере [небольшого приложения](https://github.com/petrelevich/jvm-digging/tree/master/virtual-thread), которое будет принимать REST запросы и отправлять их в кафку, после чего отвечать клиенту что сообщение доставлено.
|
||||
|
||||
![[../../meta/files/images/Pasted image 20241003083724.png]]
|
||||
|
||||
![[../../meta/files/images/Pasted image 20241003083758.png]]
|
||||
|
||||
Сравнение производительности. Генератор нагрузки: https://github.com/rakyll/hey
|
||||
|
||||
```
|
||||
/hey -n=1000000 -C=300
|
||||
```
|
||||
- 300 клиентов отправляют 1000000 запросов
|
||||
- Ethernet 1000 Mb/s
|
||||
- Запускаем в докере: 256 Mb, 1 cpu.
|
||||
- [[../../dev/java/gc/Garbage Collector|Garbage Collector]]: G1
|
||||
- Прогрев: два запуска
|
||||
- Измерений: 7
|
||||
- Стандартное отклонение: 3,8; 3,7; 2,6
|
||||
|
||||
![[../../meta/files/images/Pasted image 20241003084259.png|500]]
|
||||
|
||||
Прирост производительности: 200% Virtual Thread по сравнению с платформенными потоками, а если переключиться на Webflux, то мы получим **поверх** еще 30%.
|
||||
|
||||
Переход на Virtual Thread максимально прост, при этом максимально эффективен. Поэтому особого смысла переписывать старые приложения на рекативной подход нет, проще включить виртуальные потоки.
|
||||
### Причины
|
||||
Почему Webflux производительней виртуальных потоков?
|
||||
- Может быть, где-то в коде есть synchronized? События jdk.VirtualThreadPinned не фиксируются
|
||||
- Замедление, наиболее вероятно, связано с переключением на платформенные потоки. JMC показывает множество событий: jdk.VirtualThreadStart, jdk.VirtualThreadEnd. При этом их длительность 0 (WTF?).
|
||||
## Дополнительные материалы
|
||||
-
|
||||
***
|
||||
## Мета информация
|
||||
**Область**::
|
||||
**Родитель**::
|
||||
**Источник**::
|
||||
**Создана**:: [[2024-10-02]]
|
||||
**Автор**::
|
||||
### Дополнительные материалы
|
||||
-
|
||||
|
||||
### Дочерние заметки
|
||||
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->
|