Compare commits

..

2 Commits

Author SHA1 Message Date
60c252c339
Обновление dev заметок
All checks were successful
continuous-integration/drone/push Build is passing
2024-10-02 21:27:43 +03:00
1cef2785a6
Исправление даты 2024-10-01 08:52:43 +03:00
12 changed files with 154 additions and 17 deletions

View File

@ -4,7 +4,7 @@ aliases:
- внедрение зависимостей
tags:
- maturity/🌱
date: "[[2023-10-26]]"
date: 2023-10-26
zero-link:
- "[[../../meta/zero/00 Архитектура ПО|00 Архитектура ПО]]"
parents:

View File

@ -1,5 +1,7 @@
---
aliases:
- событийного цикла
- событийный цикл
tags:
- maturity/🌱
date: 2023-10-26
@ -9,16 +11,31 @@ parents:
- "[[Реактивное программирование]]"
linked:
---
По сути, Event Loop - это реализация [шаблона Reactor](http://design-pattern.ru/patterns/reactor.html). Является неблокирующим потоком ввода-вывода, который работает непрерывно. Его основная задача — проверка новых событий. И как только событие пришло перенаправлять его тому, кто в данный момент может его обработать. Иногда их может быть несколько для увеличения производительности.
**Event loop** (цикл событий) — это фундаментальная концепция в асинхронном программировании, которая позволяет системе обрабатывать большое количество задач без создания множества [[../fundamental/Поток процесса ОС|потоков]].
По сути, Event Loop - это реализация [шаблона Reactor](http://design-pattern.ru/patterns/reactor.html). Он используется в языках и фреймворках, которые должны обрабатывать большое количество операций [[../../../../_inbox/Ввод-вывод|ввода-вывода]] (I/O) эффективно, минимизируя затраты на создание и управление потоками. Цикл событий стал особенно популярным в таких технологиях, как JavaScript (Node.js), Python (asyncio), и современных реактивных фреймворках на Java (Vert.x, [[../../meta/zero/00 Quarkus|Quarkus]]).
Цикл событий представляет собой непрерывную петлю, которая ожидает появления событий, таких как запросы клиентов, завершение операций I/O, сигналы от системных ресурсов и другие задачи. Когда событие происходит, цикл событий вызывает соответствующий обработчик, который выполняется без блокировки основной петли ([[../../../../_inbox/Не блокирующийся ввод-вывод|неблокирующийся ввод-вывод]]).
![](../../meta/files/images/Pasted%20image%2020231026115508.png)
Выше приведён абстрактный дизайн цикла событий, который представляет идеи реактивного асинхронного программирования:
Основные шаги работы event loop:
1. **Ожидание событий.** Цикл событий ожидает появления новых задач (например, клиентских запросов, ответов от базы данных, сообщений от других сервисов).
2. **Помещение задачи в очередь.** Когда событие происходит (например, пришел запрос от клиента), оно добавляется в очередь задач, ожидающих обработки.
3. **Выполнение задачи.** Цикл событий начинает обработку задачи, извлекая её из очереди и вызывая соответствующий обработчик.
4. **Завершение задачи.** Когда задача завершена (например, отправлен ответ клиенту), цикл переходит к следующему событию в очереди.
**Преимущества**
- **Эффективное использование ресурсов.** Event loop позволяет системе обрабатывать большое количество запросов без необходимости создания множества потоков. Это снижает накладные расходы на память и процессорное время.
- **Масштабируемость.** Благодаря асинхронной модели, event loop может обрабатывать сотни тысяч запросов одновременно, что делает его идеальным решением для [[../../meta/zero/00 HighLoad|высоконагруженных систем]].
- **Неблокирующее выполнение.** В отличие от традиционных моделей, где операции ввода-вывода блокируют поток ([[Блокирующий вызов]]), в модели event loop такие операции выполняются асинхронно, освобождая поток для выполнения других задач.
- Минимум [[../fundamental/Переключение контекста|контекстных переключений]]. Цикл событий снижает количество переключений между потоками, что снижает накладные расходы на переключение контекста и увеличивает производительность.
**Недостатки**
- **Ограниченная поддержка CPU-ориентированных задач.** Модель event loop идеально подходит для операций ввода-вывода, но для задач, требующих интенсивных вычислений, такая модель не так эффективна. В таком случае ==поток может быть занят длительное время, блокируя выполнение других задач.==
- **Сложность управления.** Асинхронные операции требуют управления состояниями и корректной обработки событий, что усложняет разработку и отладку. ==Ошибки в одном обработчике могут затронуть другие запросы, обрабатываемые тем же циклом событий.==
- **“Заблокированный” цикл.** Если цикл событий заблокирован долгой синхронной операцией, это может затормозить выполнение всех задач, так как весь поток будет занят одной задачей.
- Цикл событий выполняется непрерывно в одном потоке, хотя у нас может быть столько циклов событий, сколько доступно [[../fundamental/Ядро процессора|ядер]].
- Цикл событий последовательно обрабатывает события из очереди событий и возвращается сразу после регистрации [[../../../../_inbox/Callback|обратного вызова]] в платформе.
- Платформа может инициировать завершение операции, такой как вызов базы данных или вызов внешней службы.
- Цикл событий может запускать обратный вызов при уведомлении о завершении операции и отправлять результат обратно исходному вызывающему.
***
## Мета информация
**Область**:: [[../../meta/zero/00 Архитектура ПО|00 Архитектура ПО]]

View File

@ -3,7 +3,7 @@ aliases:
- IoC
tags:
- maturity/🌱
date: "[[2023-10-26]]"
date: 2023-10-26
zero-link:
- "[[../../meta/zero/00 Архитектура ПО|00 Архитектура ПО]]"
parents:

View File

@ -9,6 +9,8 @@ parents:
linked:
---
- [[Inversion of Control]]
- [[Один клиент — один поток]]
- [[Много клиентов — один поток]]
***
## Мета информация
**Область**:: [[../../meta/zero/00 Архитектура ПО|00 Архитектура ПО]]
@ -21,3 +23,9 @@ linked:
### Дочерние заметки
<!-- 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) -->
- [[Inversion of Control]]
- [[Паттерн программирования]]
- [[Один клиент — один поток]]
- [[Много клиентов — один поток]]
<!-- SerializedQuery END -->

View File

@ -9,11 +9,12 @@ tags:
- maturity/🌱
date:
- - 2024-01-28
- - 2024-04-13
zero-link:
- "[[../../meta/zero/00 Архитектура ПО|00 Архитектура ПО]]"
parents:
linked:
- "[[Бэкенд большую часть времени ждет]]"
- "[[Блокирующий вызов]]"
---
Блокирующий вызов блокирует [поток](../fundamental/Поток%20процесса%20ОС.md) до того момента, как будут-получены данные. Во время блокировки [процесс](../fundamental/Процесс%20ОС.md) не потребляет процессорное время, но потребляет память. Например, для выполнения запроса к БД из пула потоков берётся поток, далее он ожидает, пока БД выполнит запрос и вернёт результат.
@ -24,7 +25,11 @@ linked:
## Почему простаивание потока — это проблема?
Каждый поток нуждается в памяти для хранения своего стека вызовов и других связанных с ним структур данных. ==Когда поток простаивает, он продолжает потреблять ресурсы для поддержания своего состояния.==
Кроме того, процессорное время, которое выделяется неработающим потокам, могло бы быть использовано для других задач. Если большое количество потоков простаивает, это может привести к увеличению загрузки процессора и снижению производительности, так как операционная система будет тратить больше времени на переключение между потоками.
Кроме того, процессорное время, которое выделяется неработающим потокам, могло бы быть использовано для других задач. Если большое количество потоков простаивает, это может привести к увеличению загрузки процессора и снижению производительности, так как операционная система будет тратить больше времени на [[../fundamental/Переключение контекста|переключение между потоками]].
![](../../meta/files/images/Pasted%20image%2020240413205842.png)
Если посмотреть на соотношение скорости [[../fundamental/Центральный процессор|процессора]] и возможности сетевых соединений, то отличия на пару порядков. Например, на этом слайде сжатие 1 Кб данных занимает 3 мкс, в то время как round trip в одну сторону даже внутри одного дата-центра это уже 0,5 мс. Любое сетевое взаимодействие, которое нужно бэкенду (например, отправка запроса в БД), потребует, как минимум 2х round trip-ов и по сравнению с тем процессорным временем, которое он тратит на обработку данных, это совершенно незначительно. Большую часть времени обработки запроса [бэкенд](Бэкенд.md) ничего не делает, просто ждет.
## Заметки
- Чтение с диска в linux может быть только блокирующим.
***
@ -34,7 +39,5 @@ linked:
**Источник**::
**Автор**::
**Создана**:: [[2024-01-28]]
### Дополнительные материалы
- [[../../../../_inbox/Бэкенд большую часть времени ждет|Бэкенд большую часть времени ждет]]
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->

View File

@ -26,6 +26,6 @@ linked:
**Автор**::
**Создана**:: [[2024-04-13]]
### Дополнительные материалы
- [[../../../../_inbox/Бэкенд большую часть времени ждет|Бэкенд большую часть времени ждет]]
- [[Блокирующий вызов|Блокирующий вызов]]
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->

View File

@ -0,0 +1,45 @@
---
aliases:
tags:
- maturity/🌱
date: 2024-10-02
zero-link:
- "[[../../meta/zero/00 Архитектура ПО|00 Архитектура ПО]]"
parents:
- "[[Архитектурная концепция]]"
linked:
---
Концепция “много клиентов — один поток” предполагает, что один [[../fundamental/Поток процесса ОС|поток]] может обрабатывать множество клиентских запросов. Это возможно благодаря асинхронному или [[../../../../_inbox/Событийно-ориентированное программирование|событийно-ориентированному подходу]], где поток не привязывается к одному запросу, а может переключаться между задачами в зависимости от их состояния (например, ожидания данных). Такой подход широко используется для решения проблем масштабируемости и производительности в современных [[../../meta/zero/00 HighLoad|высоконагруженных системах]].
В отличие от модели “[[один клиент — один поток]]”, где для каждого запроса создается отдельный поток, в модели “много клиентов — один поток” используется один или ограниченное количество потоков для обслуживания множества клиентов. Этот подход достигается за счет использования [[../../../../_inbox/Не блокирующийся ввод-вывод|неблокирующего ввода/вывода]] (non-blocking I/O) и [[Event Loop|событийного цикла]]. Когда клиентский запрос инициирует операцию, например обращение к базе данных, поток может освободиться и перейти к следующей задаче, вместо того чтобы блокироваться и ждать завершения операции.
Обычно используется неблокирующая модель обработки событий: когда запрос клиента инициируется, он может находиться в очереди событий и быть выполнен в момент, когда необходимые ресурсы будут готовы, при этом один поток обрабатывает множество событий последовательно или параллельно.
**Плюсы подхода**
- **Масштабируемость.** Один из ключевых плюсов модели — значительно лучшая масштабируемость по сравнению с моделью “один клиент — один поток”. Благодаря неблокирующему вводу/выводу и использованию небольшого количества потоков, такие системы могут обрабатывать тысячи и даже миллионы клиентских запросов, не создавая избыточного потребления ресурсов.
- **Эффективное использование ресурсов.** Один поток может выполнять множество задач последовательно, освобождаясь от блокировки в ожидании внешних ресурсов (например, базы данных или сети). Это позволяет максимально эффективно использовать доступные системные ресурсы, такие как память и процессорное время.
- Меньше [[../fundamental/Переключение контекста|контекстных переключений]]. Поскольку количество потоков минимально, система тратит меньше времени на контекстные переключения, что снижает накладные расходы на процессор и повышает общую производительность.
- **Высокая производительность при высоких нагрузках.** Эта модель отлично подходит для [[../../meta/zero/00 HighLoad|высоконагруженных систем]], таких как веб-сервера, системы обработки сообщений и стриминговые платформы, где каждый клиент может генерировать множество мелких запросов.
**Минусы подхода**
- **Сложность реализации.** Асинхронная модель требует более сложной архитектуры и управления состояниями. Разработчикам нужно работать с обратными вызовами (callbacks) или реактивными потоками, что увеличивает сложность кода и повышает риск ошибок.
- **Отладка и поддержка.** Из-за использования асинхронности и событийной обработки отладка таких систем может быть сложнее. Потоки могут переключаться между задачами в произвольные моменты времени, что затрудняет поиск и исправление ошибок.
- **Изоляция ошибок.** Если происходит ошибка в одном потоке, она может повлиять на множество запросов, поскольку один поток обслуживает сразу несколько клиентов. В таких случаях важно предусмотреть механизмы обработки ошибок и защиты от сбоев.
**Кто использует этот подход**
- [[../../../../wiki/zero/00 Nginx|Nginx]]. Один из самых известных примеров событийно-ориентированного сервера, использующий асинхронный подход. Nginx эффективно обрабатывает множество клиентских запросов с минимальными затратами ресурсов.
- **Node.js.** Однопоточная архитектура с использованием событийной петли, которая позволяет одному потоку обрабатывать множество запросов одновременно. Node.js широко применяется для построения масштабируемых серверов и микросервисов.
- Vert.x и [[../../meta/zero/00 Quarkus|Quarkus]]. Эти фреймворки используют реактивные подходы для обработки запросов, обеспечивая высокую производительность и асинхронную обработку данных в [[../../../../wiki/zero/Микросервисная архитектура|микросервисной архитектуре]].
- Netty. Асинхронный сетевой фреймворк, который широко используется для создания высокопроизводительных сетевых приложений на Java, таких как серверы и клиентские приложения.
***
## Мета информация
**Область**:: [[../../meta/zero/00 Архитектура ПО|00 Архитектура ПО]]
**Родитель**:: [[Архитектурная концепция]]
**Источник**::
**Создана**:: [[2024-10-02]]
**Автор**::
### Дополнительные материалы
- [[Один клиент — один поток]]
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->

View File

@ -0,0 +1,52 @@
---
aliases:
tags:
- maturity/🌱
date: 2024-10-02
zero-link:
- "[[../../meta/zero/00 Архитектура ПО|00 Архитектура ПО]]"
parents:
- "[[Архитектурная концепция]]"
linked:
---
“Один клиент — один поток” — это концепция обработки запросов, в которой для каждого клиента или запроса выделяется отдельный [[../fundamental/Поток процесса ОС|поток]] выполнения. Этот подход исторически использовался в многопоточных серверных архитектурах для обработки клиентских соединений. Концепция проста в реализации и часто применяется в традиционных системах, однако с ростом нагрузки и требованиями к масштабируемости начинают проявляться ее недостатки.
Суть концепции заключается в том, что на каждый новый клиентский запрос создается отдельный поток в системе. ==Этот поток обрабатывает запрос от начала до конца==, включая этапы получения данных, выполнения логики и возврата ответа клиенту. Как только запрос обработан, поток освобождается или завершает выполнение. Таким образом, каждый клиент имеет свой “личный” поток выполнения, изолированный от других клиентов.
**Плюсы**
- **Простота реализации.** Каждый запрос выполняется в отдельном потоке, что делает архитектуру интуитивно понятной для разработчиков. Легче управлять состоянием внутри потока, так как нет необходимости беспокоиться о синхронизации между потоками.
- **Изоляция ошибок.** Ошибка, возникшая в одном потоке, как правило, не затрагивает другие потоки. Это снижает риск влияния одного сбойного запроса на остальные.
- **Четкое распределение ресурсов.** При каждом запросе сервер выделяет четко определённое количество ресурсов (один поток), что может упростить мониторинг и управление системой.
**Недостатки**
- **Проблемы с масштабируемостью.** Основной недостаток концепции — это плохая масштабируемость. Потоки требуют выделения значительных системных ресурсов, таких как память и процессорное время. При увеличении числа клиентов нагрузка на процессор и оперативную память возрастает, а также увеличивается количество контекстных переключений между потоками, что снижает общую производительность системы.
- **Потребление ресурсов.** Для каждого клиента выделяется не только поток, но и сопутствующие ресурсы, такие как стеки вызовов, которые могут занимать значительное количество памяти. Системы, работающие с тысячами или миллионами клиентов, могут столкнуться с исчерпанием ресурсов.
- [[../fundamental/Переключение контекста|Переключение контекста]] Каждый раз, когда система переключается между потоками, происходит контекстное переключение, которое добавляет накладные расходы на процессор. Эти переключения могут значительно замедлять работу системы при большом количестве потоков.
- [[Блокирующий вызов|Блокирующий вызов]]. Даже если клиентский запрос простаивает (например, ожидает ответа от базы данных или другого сервиса), поток остается занятым и не может быть использован для других задач, что приводит к неэффективному использованию ресурсов.
**Кто использует этот подход**
Подход “один клиент — один поток” использовался в ранних версиях популярных серверов и библиотек:
- **Apache HTTP Server (классический режим работы).** В старых конфигурациях Apache каждый запрос обрабатывался отдельным потоком или процессом.
- **Tomcat (до перехода на NIO).** В классическом Tomcat для каждого HTTP-запроса создавался отдельный поток для его обработки.
Однако с ростом числа пользователей и нагрузки такие серверы начали испытывать проблемы с производительностью. Поэтому многие современные серверы перешли к более эффективным асинхронным моделям обработки запросов.
**Современные альтернативы**
С ростом масштабов приложений, особенно в веб-разработке, стали популярны асинхронные и реактивные подходы, где один поток может обслуживать множество клиентов, не создавая новый поток для каждого запроса. Такие подходы позволяют лучше использовать ресурсы системы:
- **Асинхронные модели.** Серверы, такие как [[../../../../wiki/zero/00 Nginx|Nginx]], используют [[../../../../_inbox/Событийно-ориентированное программирование|событийно-ориентированную архитектуру]], где запросы обрабатываются без необходимости создавать новый поток на каждый запрос. Это снижает потребление памяти и улучшает масштабируемость.
- [[../../../../knowledge/dev/Реактивное программирование|Реактивное программирование]]. В таких фреймворках, как [[../../meta/zero/00 Quarkus|Quarkus]], Vert.x или [[../../meta/zero/00 SpringBoot|Spring]] WebFlux, запросы обрабатываются асинхронно с использованием реактивных потоков, что позволяет эффективно распределять ресурсы даже при высокой нагрузке.
***
## Мета информация
**Область**:: [[../../meta/zero/00 Архитектура ПО|00 Архитектура ПО]]
**Родитель**:: [[Архитектурная концепция]]
**Источник**::
**Создана**:: [[2024-10-02]]
**Автор**::
### Дополнительные материалы
- [[Много клиентов — один поток]]
### Дочерние заметки
<!-- QueryToSerialize: LIST FROM [[]] WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) -->

View File

@ -3,7 +3,7 @@ aliases:
- паттерн
tags:
- maturity/🌱
date: "[[2023-11-05]]"
date: 2023-11-05
zero-link:
- "[[../../meta/zero/00 Архитектура ПО|00 Архитектура ПО]]"
parents:

View File

@ -5,6 +5,9 @@ aliases:
- переключение контекстов
- переключения контекста
- переключению контекста
- Контекстные переключения
- переключение между потоками
- контекстных переключений
tags:
- maturity/🌱
date:

View File

@ -8,7 +8,11 @@ description: Эта страница рассказывает обо мне, к
> [!INFO] HR
> Если вы HR специалист, то писать с предложениями о работе сюда [👉 Career](https://career.habr.com/upagge)
## 💼 Коротко о работе
## Короткая автобиография
Моё знакомство с миром технологий началось в раннем возрасте. С 13 лет я увлекся разработкой сайтов на платформе uCoz, что привело к самостоятельному изучению HTML и CSS. Это хобби со временем переросло в страсть к технологиям и программированию.
В университете я продолжил своё развитие в этом направлении, начав помогать однокурсникам с лабораторными работами по программированию. Уже к концу первого курса я нашел единомышленников и запустил сайт для помощи студентам из различных вузов, который включал интернет магазин с возможностью онлайн оплаты. Но к концу третьего курса я решил завершить этот проект, чтобы сосредоточиться на своём профессиональном и карьерном росте.
## 💼 Коротко о карьере
Мой основной язык программирования Java. ==Развиваюсь в основном в направлении backend разработки и DevOps==: могу написать свой [SSO сервер с использованием Oauth2](https://struchkov.dev/blog/ru/how-oauth2-works/), написать библиотеку для реализации ABAC, написать сервис для хранения файлов с использованием MinIO S3. C декабря 2021 года активно осваиваю и [использую в работе Quarkus](https://struchkov.dev/blog/ru/tag/quarkus/) для написания микросервисов в реактивном стиле 🚀
Во фронт не лезу, не мое это, но могу немного в HTML и CSS. Также мне нравятся задачи связанные с DevOps: могу [настроить полный CI/CD](https://struchkov.dev/blog/ru/java-gitlab-cicd/), упаковать приложение в Docker и написать DockerCompose, [оптимизировать работу nginx](https://struchkov.dev/blog/ru/nginx-optimization/), или [создать собственную домашню экосистему облачных сервисов](https://struchkov.dev/blog/ru/raspberry-home-cloud-services-ecosystem/).
@ -21,6 +25,8 @@ description: Эта страница рассказывает обо мне, к
> [!INFO] Подробнее о работе в резюме
> [Struchkov Mark | Java Developer](https://mark.struchkov.dev/cv)
- [[../../Мое рабочее место|Мое рабочее место]]
## Публичная активность
### ✏️ B.log
В какой-то момент у меня появилось непреодолимое желание писать, а так как я умею программировать, то решил что самое время завести блог по программированию. Это мой основной блог, на него уходит большая часть творческих ресурсов.

View File

@ -6,6 +6,9 @@ parents:
title: HighLoad
aliases:
- HighLoad
- высоконагруженных системах
- высоконагруженная система
- высоконагруженных систем
---
## Что такое HighLoad?
Например, один запрос в секунду это нагрузка явно не highload, любой сервер, вроде бы, справится. Но, например, если он перекодирует видеоролики, то тут может наступить highload.