diff --git a/dev/architecture/Event Loop.md b/dev/architecture/Event Loop.md index 8e229868..c71b5115 100644 --- a/dev/architecture/Event Loop.md +++ b/dev/architecture/Event Loop.md @@ -40,7 +40,7 @@ linked: *** ## Мета информация **Область**:: [[../../meta/zero/00 Архитектура ПО|00 Архитектура ПО]] -**Родитель**:: [[../../../../knowledge/dev/Реактивное программирование|Реактивное программирование]] +**Родитель**:: [[Реактивное программирование|Реактивное программирование]] **Источник**:: **Автор**:: **Создана**:: diff --git a/dev/architecture/Transactional Outbox.md b/dev/architecture/Transactional Outbox.md new file mode 100644 index 00000000..6f40d7d8 --- /dev/null +++ b/dev/architecture/Transactional Outbox.md @@ -0,0 +1,55 @@ +--- +aliases: + - transactional outbox + - транзакционный аутбокс +tags: + - maturity/🌱 +date: 2024-11-15 +--- +Transactional Outbox — это [[Паттерн проектирования|шаблон проектирования]], используемый в распределённых системах для обеспечения гарантированной отправки сообщений, особенно при интеграции с [[Брокер сообщений|брокерами сообщений]]. Этот шаблон помогает решить [[Отправка сообщений в Kafka из транзакции БД| проблему атомарности между изменениями в базе данных и отправкой событий]], гарантируя, что сообщение будет отправлено только после успешного выполнения транзакции в базе данных. + +**Схема работы:** +1. При выполнении бизнес-операции, например, при изменении данных в базе данных, создаётся запись в таблице `outbox`. Эта запись содержит сообщение, которое нужно отправить другим сервисам. +2. Операция создания записи в таблице `outbox` происходит в одной транзакции с основной бизнес-операцией. Это гарантирует, что и изменение данных, и запись сообщения будут выполнены атомарно. +3. После успешной фиксации транзакции фоновый процесс или отдельный компонент читает сообщения из таблицы `outbox` и отправляет их в [[брокер сообщений]]. +4. После успешной отправки сообщения запись в таблице outbox помечается как обработанная и спустя какое-то время удаляется. + +**Преимущества:** +- **Гарантированная доставка сообщений**: сообщения фиксируются вместе с бизнес-операциями, что предотвращает ситуацию, когда данные в базе данных обновлены, а сообщение не отправлено. +- **Упрощение архитектуры**: использование таблицы `outbox` вместо распределённых транзакций (2PC) значительно упрощает архитектуру и позволяет избежать сложных механизмов блокировки. + +**Недостатки:** +- **Дополнительная задержка**: отправка сообщений через фоновый процесс может вызвать небольшую задержку в доставке сообщений, по сравнению с немедленной отправкой. +- **Увеличение нагрузки на базу данных**: таблица `outbox` требует дополнительного хранения и управления, что увеличивает нагрузку на базу данных, особенно при большом объёме сообщений. + +Сначала необходимо создать таблицу `outbox` в вашей базе данных для хранения сообщений, ожидающих отправки в Kafka. + +Возможная структура `outbox` таблицы +```sql +CREATE TABLE outbox ( + id BIGSERIAL PRIMARY KEY, + topic VARCHAR(255) NOT NULL, + payload TEXT NOT NULL, + status VARCHAR(20) DEFAULT 'PENDING', + created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, + updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP +); +``` +- `id`: Уникальный идентификатор записи. +- `topic`: Название топика/очереди, в который должно быть отправлено событие. +- `payload`: данные события. +- `status`: Статус обработки (`PENDING`, `SENT`, `FAILED`). +- `created_at` и `updated_at`: Временные метки для отслеживания создания и обновления записи. +*** +## Мета информация +**Область**:: [[../../meta/zero/00 Архитектура ПО|00 Архитектура ПО]] +**Родитель**:: [[Паттерн проектирования]] +**Источник**:: +**Создана**:: [[2024-11-15]] +**Автор**:: +### Дополнительные материалы +- [[../../../../_inbox/Transactional Inbox|Transactional Inbox]] + +### Дочерние заметки + + diff --git a/dev/architecture/Архитектурная концепция.md b/dev/architecture/Архитектурная концепция.md index 8551a6e9..52135cf5 100644 --- a/dev/architecture/Архитектурная концепция.md +++ b/dev/architecture/Архитектурная концепция.md @@ -3,11 +3,21 @@ aliases: tags: - maturity/🌱 date: 2024-10-01 -zero-link: - - "[[../garden/ru/meta/zero/00 Архитектура ПО|00 Архитектура ПО]]" -parents: -linked: --- +Архитектурная концепция это общая идея или принцип построения архитектуры системы или отдельного компонента системы. + +**Цель**: +- Определить базовые принципы, которые будут направлять разработку всей системы. +- Решать проблемы на уровне системы, а не отдельных компонентов. + +## Классификация +На уровне системы: +- [[../../../../wiki/zero/Микросервисная архитектура|Микросервисная архитектура]] +- [[../../../../_inbox/Событийно-ориентированное программирование|Событийно-ориентированное программирование]] +- [[Асинхронное программирование]] +- [[Реактивное программирование|Реактивное программирование]] + +На уровне компонентов системы: - [[Inversion of Control]] - [[Один клиент — один поток]] - [[Много клиентов — один поток]] @@ -24,8 +34,11 @@ linked: ### Дочерние заметки +- [[Событийно-ориентированное программирование]] +- [[Микросервисная архитектура]] - [[Inversion of Control]] - [[Много клиентов — один поток]] - [[Один клиент — один поток]] - [[Паттерн проектирования]] +- [[Асинхронное программирование]] diff --git a/dev/fundamental/Асинхронное программирование.md b/dev/architecture/Асинхронное программирование.md similarity index 58% rename from dev/fundamental/Асинхронное программирование.md rename to dev/architecture/Асинхронное программирование.md index a0df4af9..df8ce7f3 100644 --- a/dev/fundamental/Асинхронное программирование.md +++ b/dev/architecture/Асинхронное программирование.md @@ -3,17 +3,14 @@ aliases: tags: - maturity/🌱 date: 2024-10-08 -zero-link: -parents: -linked: --- -Асинхронность позволяет задачам выполняться в фоновом режиме, не блокируя основной поток программы. В синхронных операциях задача должна завершиться, прежде чем начнётся следующая, тогда как асинхронные задачи могут выполняться независимо, что особенно полезно для [[../architecture/Блокирующий вызов|блокирующих операций]]. +Асинхронность позволяет задачам выполняться в фоновом режиме, не блокируя основной поток программы, тем самым реализуя [[Concurrency]]. В синхронных операциях задача должна завершиться, прежде чем начнётся следующая, тогда как асинхронные задачи могут выполняться независимо, что особенно полезно для [[../architecture/Блокирующий вызов|блокирующих операций]]. Асинхронное программирование делает программы более отзывчивыми, позволяя основному потоку продолжать выполнение других задач, пока асинхронная операция выполняется. После завершения такой операции программа может вернуться к её результатам. В Java для этого используется класс `CompletableFuture`. *** ## Мета информация -**Область**:: [[../../meta/zero/00 Разработка|00 Разработка]] -**Родитель**:: [[Concurrency]] +**Область**:: [[../../meta/zero/00 Архитектура ПО|00 Архитектура ПО]] +**Родитель**:: [[../architecture/Архитектурная концепция|Архитектурная концепция]] **Источник**:: **Создана**:: [[2024-10-08]] **Автор**:: diff --git a/dev/architecture/Брокер сообщений.md b/dev/architecture/Брокер сообщений.md index 14d2124d..d3f70262 100644 --- a/dev/architecture/Брокер сообщений.md +++ b/dev/architecture/Брокер сообщений.md @@ -1,5 +1,6 @@ --- -aliases: +aliases: + - брокерами сообщений tags: - maturity/🌱 date: 2024-07-02 diff --git a/dev/architecture/Идемпотентность.md b/dev/architecture/Идемпотентность.md index b7d31456..be3c1c7c 100644 --- a/dev/architecture/Идемпотентность.md +++ b/dev/architecture/Идемпотентность.md @@ -13,8 +13,8 @@ date: 2024-09-11 Идемпотентность позволяет системе быть устойчивой к ошибкам и повторам — если запрос случайно повторится, это не приведет к нежелательным изменениям. -Примеры реализации: -- С использованием уникального идентификатора +**Примеры реализации:** +- [[highload/Идемпотентность на базе уникального идентификатора|Идемпотентность на базе уникального идентификатора]] - Логика приложения устроена таким образом, что выполнение запроса с одними и теми же параметрами всегда приводит к одному и тому же результату. *** ## Мета информация diff --git a/dev/architecture/Один клиент — один поток.md b/dev/architecture/Один клиент — один поток.md index 68f45d62..d993c789 100644 --- a/dev/architecture/Один клиент — один поток.md +++ b/dev/architecture/Один клиент — один поток.md @@ -36,7 +36,7 @@ linked: С ростом масштабов приложений, особенно в веб-разработке, стали популярны асинхронные и реактивные подходы, где один поток может обслуживать множество клиентов, не создавая новый поток для каждого запроса. Такие подходы позволяют лучше использовать ресурсы системы: - **Асинхронные модели.** Серверы, такие как [[../../meta/zero/00 Nginx|Nginx]], используют [[../../../../_inbox/Событийно-ориентированное программирование|событийно-ориентированную архитектуру]], где запросы обрабатываются без необходимости создавать новый поток на каждый запрос. Это снижает потребление памяти и улучшает масштабируемость. -- [[../../../../knowledge/dev/Реактивное программирование|Реактивное программирование]]. В таких фреймворках, как [[../../meta/zero/00 Quarkus|Quarkus]], Vert.x или [[../../meta/zero/00 SpringBoot|Spring]] WebFlux, запросы обрабатываются асинхронно с использованием реактивных потоков, что позволяет эффективно распределять ресурсы даже при высокой нагрузке. +- [[Реактивное программирование|Реактивное программирование]]. В таких фреймворках, как [[../../meta/zero/00 Quarkus|Quarkus]], Vert.x или [[../../meta/zero/00 SpringBoot|Spring]] WebFlux, запросы обрабатываются асинхронно с использованием реактивных потоков, что позволяет эффективно распределять ресурсы даже при высокой нагрузке. *** ## Мета информация diff --git a/dev/architecture/Отправка сообщений в Kafka из транзакции БД.md b/dev/architecture/Отправка сообщений в Kafka из транзакции БД.md new file mode 100644 index 00000000..214b4043 --- /dev/null +++ b/dev/architecture/Отправка сообщений в Kafka из транзакции БД.md @@ -0,0 +1,29 @@ +--- +aliases: +tags: + - maturity/🌱 +date: 2024-11-15 +--- +Отправка сообщений в [[00 Kafka|Kafka]] из [[Транзакция БД|транзакций базы данных]] приводит к проблемам с согласованностью данных между системами, особенно в условиях распределённых систем. Если сначала происходит отправка сообщения в Kafka, а затем транзакция в БД откатывается, то сообщение останется в Kafka, но база данных не зафиксирует изменений, что приведёт к рассинхронизации данных. + +Для обеспечения согласованности данных между базой данных и Kafka необходимо использовать следующие подходы: + +- [[Transactional Outbox|Transactional Outbox]]. Этот подход позволяет отделить запись в базу данных от отправки сообщения в брокер. Изменения сначала фиксируются в основной таблице базы данных, а затем записываются в специальную таблицу "Outbox". Отдельный процесс или сервис асинхронно считывает из таблицы "Outbox" и отправляет сообщения в Kafka, что гарантирует согласованность данных. +- Change Data Capture (CDC). Использование CDC с инструментами вроде Debezium позволяет отслеживать изменения в базе данных и публиковать их в Kafka. Это решение подходит для случаев, когда необходимо обеспечить автоматическую синхронизацию изменений, но может потребовать дополнительных настроек и ресурсов. +- Распределённые транзакции (двухфазный коммит). Этот метод позволяет гарантировать согласованность между базой данных и Kafka за счёт координации транзакций между ними. Однако этот подход часто считается сложным и менее масштабируемым, особенно в распределённых системах. + +Другая серьёзная проблема связана с возможностью двойной обработки. В случае сбоя приложения или инфраструктуры транзакции могут повторяться, приводя к дублированию событий в Kafka. Дублирование событий может вызвать некорректное состояние системы, повторное выполнение операций. Чтобы предотвратить дублирование, можно использовать следующие подходы: +- [[highload/Идемпотентность на базе уникального идентификатора|Идемпотентность на базе уникального идентификатора]] +*** +## Мета информация +**Область**:: [[../../meta/zero/00 Архитектура ПО|00 Архитектура ПО]] +**Родитель**:: +**Источник**:: +**Создана**:: [[2024-11-15]] +**Автор**:: +### Дополнительные материалы +- + +### Дочерние заметки + + diff --git a/dev/architecture/Паттерн проектирования.md b/dev/architecture/Паттерн проектирования.md index 3abbd6a7..de549ac3 100644 --- a/dev/architecture/Паттерн проектирования.md +++ b/dev/architecture/Паттерн проектирования.md @@ -1,20 +1,17 @@ --- aliases: - паттерн + - шаблон проектирования tags: - maturity/🌱 date: 2023-11-05 -zero-link: - - "[[../../meta/zero/00 Архитектура ПО|00 Архитектура ПО]]" -parents: - - "[[Архитектурная концепция]]" linked: --- - [[Dependency Injection]] - [[Порождающий паттерн проектирования]] + - [[Builder Pattern|Builder Pattern]]: строит объекты поэтапно, разделяя процесс создания и внешний вид. - Abstract Factory: создаёт группы связанных элементов. -- [[Builder Pattern|Builder Pattern]]: строит объекты поэтапно, разделяя процесс создания и внешний вид. - Prototype: создаёт копии полностью подготовленных экземпляров. - Singleton: One and Only — особый класс, имеющий только один экземпляр. - Adapter: Universal Plug — соединяет объекты с разными интерфейсами. @@ -32,6 +29,9 @@ linked: - Observer: News Broadcaster — уведомляет классы об изменениях в других объектах. - Visitor: Skillful Guest — добавляет новые операции классу, не изменяя его. +- [[../../../../_inbox/Transactional Inbox|Transactional Inbox]] +- [[Transactional Outbox]] + *** ## Мета информация **Область**:: [[../../meta/zero/00 Архитектура ПО|00 Архитектура ПО]] @@ -44,6 +44,8 @@ linked: ### Дочерние заметки +- [[MVC]] - [[Dependency Injection]] - [[Порождающий паттерн проектирования]] +- [[Transactional Outbox]] diff --git a/dev/architecture/Реактивное программирование.md b/dev/architecture/Реактивное программирование.md new file mode 100644 index 00000000..a947a729 --- /dev/null +++ b/dev/architecture/Реактивное программирование.md @@ -0,0 +1,30 @@ +--- +aliases: + - реактивном программировании +tags: + - maturity/🌱 +date: "[[2023-10-26]]" +zero-link: + - "[[../../meta/zero/00 Разработка|00 Разработка]]" +parents: + - "[[Парадигмы разработки]]" +linked: +--- +**Реактивное программирование** — это парадигма, ориентированная на потоки данных и распространение изменений. Она использует асинхронные потоки данных (например, Observables в RxJava), которые позволяют обрабатывать события по мере их поступления с автоматическим управлением параллелизмом и асинхронностью. + +**Реактивное программирование** используется для создания отзывчивых, устойчивых и масштабируемых систем, где важно быстро реагировать на поступающие данные, управляя backpressure (ситуация, когда данные поступают быстрее, чем могут быть обработаны) и обеспечивая неблокирующее взаимодействие. +*** +## Мета информация +**Область**:: [[../../meta/zero/00 Разработка|00 Разработка]] +**Родитель**:: [[Архитектурная концепция]] +**Источник**:: +**Автор**:: +**Создана**:: [[2023-10-26]] +### Дополнительные материалы +- [Реактивное программирование на Java. Будущее, настоящее и прошлое](https://struchkov.dev/blog/ru/overview-of-reactive-programming/) +### Дочерние заметки +```dataview +LIST +FROM [[]] +WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link) +``` \ No newline at end of file diff --git a/dev/fundamental/Concurrency.md b/dev/fundamental/Concurrency.md index bbdfb1ff..89388756 100644 --- a/dev/fundamental/Concurrency.md +++ b/dev/fundamental/Concurrency.md @@ -12,13 +12,13 @@ linked: --- Конкурентность — это общий термин, описывающий способность программы обрабатывать несколько задач. ==Это не обязательно означает одновременное выполнение.== -- [[Parallelism]]. Физическое одновременное выполнение нескольких задач на разных ядрах или процессорах. Параллелизм является формой конкурентности, но требует аппаратной поддержки для одновременного выполнения. +[[Parallelism]]. Физическое одновременное выполнение нескольких задач на разных ядрах или процессорах. Параллелизм является формой конкурентности, но требует аппаратной поддержки для одновременного выполнения. **Механизмы реализации конкурентности** - [[Многозадачность|Multitasking]]. - [[Multithreading]]. Использование нескольких потоков внутри одного процесса. Потоки могут выполняться конкурентно, разделяя память и ресурсы процесса. Также требует механизма переключения контекстов, но на уровне потоков. -- [[Асинхронное программирование]] -- [[../../../../knowledge/dev/Реактивное программирование|Реактивное программирование]] +- [[../architecture/Асинхронное программирование]] +- [[../architecture/Реактивное программирование|Реактивное программирование]] ![[../../meta/files/images/telegram-cloud-photo-size-2-5271536941378167546-y.jpg]] *** @@ -33,6 +33,5 @@ linked: ### Дочерние заметки -- [[Асинхронное программирование]] - [[Многозадачность]] diff --git a/dev/java/Границы применимости Tuple и Pair в разработке.md b/dev/java/Границы применимости Tuple и Pair в разработке.md index 0f3b5a0e..365e4cdf 100644 --- a/dev/java/Границы применимости Tuple и Pair в разработке.md +++ b/dev/java/Границы применимости Tuple и Pair в разработке.md @@ -89,7 +89,7 @@ private Tuple fetchUserData() { - Если потребуется передавать данные в другие классы в будущем. - Если работа с данными требует дополнительной логики, такой как валидация или преобразование. ## Tuple в реактивном программировании -В [[../../../../knowledge/dev/Реактивное программирование|реактивном программировании]], особенно с использованием [[../../meta/zero/00 Quarkus|Quarkus]] и Mutiny, часто возникает необходимость передачи нескольких значений между стадиями реактивного потока данных. `Tuple` может быть удобным решением для объединения значений, особенно когда результат остаётся внутри потока и не становится частью публичного API. +В [[../architecture/Реактивное программирование|реактивном программировании]], особенно с использованием [[../../meta/zero/00 Quarkus|Quarkus]] и Mutiny, часто возникает необходимость передачи нескольких значений между стадиями реактивного потока данных. `Tuple` может быть удобным решением для объединения значений, особенно когда результат остаётся внутри потока и не становится частью публичного API. Например, в реактивных пайпах могут использоваться такие структуры, как `Tuple2`, `Tuple3` и далее: diff --git a/dev/system-design/GraphQL.md b/dev/system-design/GraphQL.md index 4535faf6..db0375d5 100644 --- a/dev/system-design/GraphQL.md +++ b/dev/system-design/GraphQL.md @@ -16,7 +16,7 @@ date: 2024-11-03 *** ## Мета информация -**Область**:: [[../../meta/zero/00 System Design|00 System Design]] +**Область**:: [[../../meta/zero/00 Архитектура ИС|00 Архитектура ИС]] **Родитель**:: [[Протоколы коммуникаций|Протоколы коммуникаций]] **Источник**:: **Создана**:: [[2024-11-03]] diff --git a/dev/system-design/Long polling.md b/dev/system-design/Long polling.md index adff5647..92c3b57a 100644 --- a/dev/system-design/Long polling.md +++ b/dev/system-design/Long polling.md @@ -15,7 +15,7 @@ date: 2024-11-03 - Удержание открытого соединения может быть менее эффективным для серверов с ограниченными ресурсами, особенно при большом количестве клиентов. *** ## Мета информация -**Область**:: [[../../meta/zero/00 System Design|00 System Design]] +**Область**:: [[../../meta/zero/00 Архитектура ИС|00 Архитектура ИС]] **Родитель**:: **Источник**:: **Создана**:: [[2024-11-03]] diff --git a/dev/system-design/RESTful.md b/dev/system-design/RESTful.md index 6785c014..cb21d3c9 100644 --- a/dev/system-design/RESTful.md +++ b/dev/system-design/RESTful.md @@ -16,7 +16,7 @@ date: 2024-11-03 ![[../../meta/files/images/Pasted image 20241103020635.png]] *** ## Мета информация -**Область**:: [[../../meta/zero/00 System Design|00 System Design]] +**Область**:: [[../../meta/zero/00 Архитектура ИС|00 Архитектура ИС]] **Родитель**:: [[Протоколы коммуникаций|Протоколы коммуникаций]] **Источник**:: **Создана**:: [[2024-11-03]] diff --git a/dev/system-design/Remote Procedure Call.md b/dev/system-design/Remote Procedure Call.md index 9ca51457..67a67de2 100644 --- a/dev/system-design/Remote Procedure Call.md +++ b/dev/system-design/Remote Procedure Call.md @@ -11,7 +11,7 @@ RPC (удалённый вызов процедур) — это **общая к *** ## Мета информация -**Область**:: [[../../meta/zero/00 System Design|00 System Design]] +**Область**:: [[../../meta/zero/00 Архитектура ИС|00 Архитектура ИС]] **Родитель**:: **Источник**:: **Создана**:: [[2024-11-03]] diff --git a/dev/system-design/Webhook.md b/dev/system-design/Webhook.md index fd33f09b..3a845cca 100644 --- a/dev/system-design/Webhook.md +++ b/dev/system-design/Webhook.md @@ -17,7 +17,7 @@ date: 2024-11-03 - Сложнее тестировать и отлаживать, так как вебхуки зависят от событий, происходящих на сервере. *** ## Мета информация -**Область**:: [[../../meta/zero/00 System Design|00 System Design]] +**Область**:: [[../../meta/zero/00 Архитектура ИС|00 Архитектура ИС]] **Родитель**:: [[Протоколы коммуникаций]] **Источник**:: **Создана**:: [[2024-11-03]] diff --git a/dev/system-design/gRPC.md b/dev/system-design/gRPC.md index e2f316a8..8325f698 100644 --- a/dev/system-design/gRPC.md +++ b/dev/system-design/gRPC.md @@ -19,7 +19,7 @@ date: 2024-04-12 **Балансировка нагрузки L7 vs L4**: Kubernetes обычно использует балансировку нагрузки на уровне 4 (L4), которая перенаправляет трафик на основе информации IP и порта. Однако gRPC полагается на HTTP/2, что требует балансировки на уровне 7 (L7) для эффективного распределения запросов. Это может потребовать дополнительных настроек или использования специализированных ингресс-контроллеров, поддерживающих HTTP/2. *** ## Мета информация -**Область**:: [[../../meta/zero/00 System Design|00 System Design]] +**Область**:: [[../../meta/zero/00 Архитектура ИС|00 Архитектура ИС]] **Родитель**:: [[Remote Procedure Call|RPC]], [[Протоколы коммуникаций]] **Источник**:: **Автор**:: diff --git a/dev/system-design/Протоколы коммуникаций.md b/dev/system-design/Протоколы коммуникаций.md index 904c3f4b..2edd217b 100644 --- a/dev/system-design/Протоколы коммуникаций.md +++ b/dev/system-design/Протоколы коммуникаций.md @@ -23,7 +23,7 @@ date: 2024-11-03 - Уведомляет системы при наступлении событий *** ## Мета информация -**Область**:: [[../../meta/zero/00 System Design|00 System Design]] +**Область**:: [[../../meta/zero/00 Архитектура ИС|00 Архитектура ИС]] **Родитель**:: **Источник**:: **Создана**:: [[2024-11-03]] @@ -34,9 +34,9 @@ date: 2024-11-03 ### Дочерние заметки -- [[RESTful]] - [[GraphQL]] -- [[gRPC]] +- [[RESTful]] - [[Webhook]] +- [[gRPC]]