-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
50 changed files
with
596 additions
and
86 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,26 @@ | ||
# NATS | ||
|
||
{! docs/en/helpful/in-progress.md !} | ||
## Advantages and disadvantages | ||
|
||
**NATS** is an easy-to-use, high-performance message broker written in *Golang*. If your application does not require complex routing logic, should cope with high load, scale and do not require large hardware costs, *NATS* will be an excellent choice for you. | ||
|
||
!!! note | ||
More information about *NATS* can be found on the [official website](https://nats.io ){.external-link target="_blank"} | ||
|
||
However, *NATS* has disadvantages that you should be aware of: | ||
|
||
* Messages are not persistent. If the message is published while your consumer is disconnected, it will be lost. | ||
* There are no complex routing mechanisms. | ||
* There are no mechanisms for confirming receipt and processing of messages from the consumer. | ||
|
||
These shortcomings are corrected by using the persistent level - *JetStream*. If you need strict guarantees for the delivery and processing of messages to the small detriment of the speed and resources consumed, you can use *NatsJS*. | ||
|
||
## Routing rules | ||
|
||
*NATS* does not have the ability to configure complex routing rules. The only entity in *NATS* is `subject`, which can be subscribed to either directly by name or by regular expression pattern. | ||
|
||
Both examples are discussed [a little further](../3_examples/1_direct). | ||
|
||
In order to support the ability to scale consumers horizontally, *NATS* supports the `queue group` functionality: | ||
a message sent to `subject` will be processed by a random consumer from the `queue group` subscribed to this `subject`. | ||
This approach allows you to increase the processing speed of `subject` by *N* times when starting *N* consumers with one group. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# NATS Publishing | ||
|
||
To send messages, `NatsBroker` uses the unified `publish` method. | ||
|
||
```python | ||
import asyncio | ||
from propan import NatsBroker | ||
|
||
async def pub(): | ||
async with NatsBroker() as broker: | ||
await broker.publish("Hi!", subject="test") | ||
|
||
asyncio.run(pub()) | ||
``` | ||
|
||
## Basic arguments | ||
|
||
The `publish` method accepts the following arguments: | ||
|
||
* `message`: bytes | str | dict | Sequence[Any] | pydatic.BaseModel - message to send | ||
* `subject`: str - *subject*, where the message will be sent. | ||
|
||
## Message Parameters | ||
|
||
* `headers`: dict[str, Any] | None = None - headers of the message being sent (used by consumers) | ||
|
||
## RPC arguments | ||
|
||
Also `publish` supports common arguments for creating [*RPC* queries](../../getting_started/4_broker/5_rpc/#_3): | ||
|
||
* `reply_to`: str = "" - which *channel* to send the response to (used for asynchronous RPC requests) | ||
* `callback`: bool = False - whether to expect a response to the message | ||
* `callback_timeout`: float | None = 30.0 - timeout waiting for a response. In the case of `None` - waits indefinitely | ||
* `raise_timeout`: bool = False | ||
* `False` - return None in case of timeout | ||
* `True` - error `asyncio.TimeoutError` in case of timeout |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
# Direct | ||
|
||
**Direct** Subject is the basic way to route messages in *NATS*. Its essence is very simple: | ||
`subject` sends messages to all consumers subscribed to it. | ||
|
||
## Scaling | ||
|
||
If one `subject` is listening by several consumers with the same `queue group`, the message will go to a random consumer each time. | ||
|
||
Thus, *NATS* can independently balance the load on queue consumers. You can increase the processing speed of the message flow from the queue by simply launching additional instances of the consumer service. You don't need to make changes to the current infrastructure configuration: *NATS* will take care of how to distribute messages between your services. | ||
|
||
## Example | ||
|
||
**Direct** Subject is the type used in **Propan** by default: you can simply declare it as follows | ||
|
||
```python | ||
@broker.handler("test_subject") | ||
async def handler(): | ||
... | ||
``` | ||
|
||
Full example: | ||
|
||
```python linenums="1" | ||
{!> docs_src/nats/direct.py !} | ||
``` | ||
|
||
### Consumer Announcement | ||
|
||
To begin with, we have declared several consumers for two `subjects`: `test-subj-1` and `test-subj-2`: | ||
|
||
```python linenums="7" hl_lines="1 5 9" | ||
{!> docs_src/nats/direct.py [ln:7-17]!} | ||
``` | ||
|
||
!!! note | ||
Note that all consumers are subscribed using the same `queue_group`: within the same service, this does not make sense, since messages will come to these handlers in turn. | ||
Here we emulate the work of several consumers and load balancing between them. | ||
|
||
### Message distribution | ||
|
||
Now the distribution of messages between these consumers will look like this: | ||
|
||
```python | ||
{!> docs_src/nats/direct.py [ln:21]!} | ||
``` | ||
|
||
The message `1` will be sent to `handler1` or `handler2`, because they are listening to one `subject` within one `queue group` | ||
|
||
--- | ||
|
||
```python | ||
{!> docs_src/nats/direct.py [ln:22]!} | ||
``` | ||
|
||
Message `2` will be sent similarly to message `1` | ||
|
||
--- | ||
|
||
```python | ||
{!> docs_src/nats/direct.py [ln:23]!} | ||
``` | ||
|
||
The message `3` will be sent to `handler3`, because he is the only one listening to `test-subj-2` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
# Pattern | ||
|
||
**Pattern** Subject is a powerful *NATS* routing engine. This type of `subject` messages to consumers by the *pattern* specified when they connect to `subject` and a message key. | ||
|
||
## Scaling | ||
|
||
If one `subject` is listening by several consumers with the same `queue group`, the message will go to a random consumer each time. | ||
|
||
Thus, *NATS* can independently balance the load on queue consumers. You can increase the processing speed of the message flow from the queue by simply launching additional instances of the consumer service. You don't need to make changes to the current infrastructure configuration: *NATS* will take care of how to distribute messages between your services. | ||
|
||
## Example | ||
|
||
```python linenums="1" | ||
{!> docs_src/nats/pattern.py !} | ||
``` | ||
|
||
### Consumer Announcement | ||
|
||
To begin with, we have announced several consumers for two `subjects`: `*.info` and `*.error`: | ||
|
||
```python linenums="7" hl_lines="1 5 9" | ||
{!> docs_src/nats/pattern.py [ln:7-17]!} | ||
``` | ||
|
||
At the same time, in the `subject` of our consumers, we specify the *pattern* that will be processed by these consumers. | ||
|
||
!!! note | ||
Note that all consumers are subscribed using the same `queue_group`: within the same service, this does not make sense, since messages will come to these handlers in turn. | ||
Here we emulate the work of several consumers and load balancing between them. | ||
|
||
### Message distribution | ||
|
||
Now the distribution of messages between these consumers will look like this: | ||
|
||
```python | ||
{!> docs_src/nats/pattern.py [ln:21]!} | ||
``` | ||
|
||
The message `1` will be sent to `handler1` or `handler2`, because they listen to the same `subject` template within the same `queue group` | ||
|
||
--- | ||
|
||
```python | ||
{!> docs_src/nats/pattern.py [ln:22]!} | ||
``` | ||
|
||
Message `2` will be sent similarly to message `1` | ||
|
||
--- | ||
|
||
```python | ||
{!> docs_src/nats/pattern.py [ln:23]!} | ||
``` | ||
|
||
The message `3` will be sent to `handler3`, because it is the only one listening to the pattern `*.error*` |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,26 @@ | ||
# NATS | ||
|
||
{! docs/ru/helpful/in-progress.md !} | ||
## Преимущества и недостатки | ||
|
||
**NATS** - простой в использовании высокопроизводительный брокер сообщений, написанный на *Golang*. Если ваше приложение не требует сложной логики маршрутизации, должно справляться с высокой нагрузкой, просто масштабироваться и не требовать больших затрат на железо, *NATS* станет для вас отличным выбором. | ||
|
||
!!! note | ||
Подробнее с *NATS* вы можете ознакомиться на [официальном сайте](https://nats.io){.external-link target="_blank"} | ||
|
||
Однако, у *NATS* есть и недостатки, о которых вам стоит знать: | ||
|
||
* Сообщения не персистентны. Если сообщение будет опубликовано пока ваш потребитель отключен - оно будет потеряно. | ||
* Отстутствуют механизмы сложной маршрутизации. | ||
* Отстутствуют механизмы подтверждения получения и обработки сообщений со стороны потребителя. | ||
|
||
Однако, эти недостатки исправляются использованием персистентного уровня - *JetStream*. Если вам нужны строгие гарантии доставки и обработки сообщений в небольшой ущерб скорости работы и потребляемым ресурсам, вы можете воспользоваться *NatsJS*. | ||
|
||
## Правила маршрутизации | ||
|
||
*NATS* не обладает возможностью настраивать сложные правила маршрутизации. Единственной сущностью в *NATS* является `subject`, на который можно подписаться либо напрямую по имени, либо по паттерну регулярного выражения. | ||
|
||
Оба примера рассмотрены [чуть далее](../3_examples/1_direct). | ||
|
||
С целью поддержки возможностей горизонтально масштабировать потребителей, *NATS* поддерживает функционал `queue group`: | ||
сообщение, отправленное в `subject` будет обработано случайным потребителем из `queue group`, подписанной на этот `subject`. | ||
Такой подход позволяет увеличить скорость обработки `subject` в *N* раз при запуске *N* потребителей с одной группой. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# NATS Publishing | ||
|
||
Для отправки сообщений `NatsBroker` использует унифицированный метод `publish`. | ||
|
||
```python | ||
import asyncio | ||
from propan import NatsBroker | ||
|
||
async def pub(): | ||
async with NatsBroker() as broker: | ||
await broker.publish("Hi!", subject="test") | ||
|
||
asyncio.run(pub()) | ||
``` | ||
|
||
## Базовые аргументы | ||
|
||
Метод `publish` принимает следующие аргументы: | ||
|
||
* `message`: bytes | str | dict | Sequence[Any] | pydatic.BaseModel - сообщение для отправки | ||
* `subject`: str - *subject*, куда будет отправлено сообщение. | ||
|
||
## Параметры сообщения | ||
|
||
* `headers`: dict[str, Any] | None = None - заголовки отправляемого сообщения (используются потребителями) | ||
|
||
## RPC аргументы | ||
|
||
Также `publish` поддерживает общие аргументы для создания [*RPC* запросов](../../getting_started/4_broker/5_rpc/#_3): | ||
|
||
* `reply_to`: str = "" - в какой *channel* отправить ответ (используется для асинхронных RPC запросов) | ||
* `callback`: bool = False - ожидать ли ответ на сообщение | ||
* `callback_timeout`: float | None = 30.0 - таймаут ожидания ответа. В случае `None` - ждет бесконечно | ||
* `raise_timeout`: bool = False | ||
* `False` - возвращать None в случае таймаута | ||
* `True` - ошибка `asyncio.TimeoutError` в случае таймаута |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
# Direct | ||
|
||
**Direct** Subject - базовый способ маршрутизации сообщений в *NATS*. Его суть очень проста: | ||
`subject` отправляет сообщения всем потребителям, подписанным на него. | ||
|
||
## Масштабирование | ||
|
||
Если один `subject` слушает несколько потребителей с одинаковой `queue group`, сообщение будет уходить каждый раз случайному потребителю. | ||
|
||
Таким образом, *NATS* может самостоятельно балансировать нагрузку на потребителей очереди. Вы можете увеличить скорость обработки потока сообщений из очереди просто запустив дополнительные инстансы сервиса-потребителя. Вам не нужно вносить изменений в текущую конфигурацию инфраструктуры: *NATS* сам позаботится о том, как распределить сообщения между вашими сервисами. | ||
|
||
## Пример | ||
|
||
**Direct** Subject - тип, используемый в **Propan** по умолчанию: вы можете просто объявить его следующим образом | ||
|
||
```python | ||
@broker.handler("test_subject") | ||
async def handler(): | ||
... | ||
``` | ||
|
||
Полный пример: | ||
|
||
```python linenums="1" | ||
{!> docs_src/nats/direct.py !} | ||
``` | ||
|
||
### Объявление потребителей | ||
|
||
Для начала мы объявили несколько потребителей для двух `subject`: `test-subj-1` и `test-subj-2`: | ||
|
||
```python linenums="7" hl_lines="1 5 9" | ||
{!> docs_src/nats/direct.py [ln:7-17]!} | ||
``` | ||
|
||
!!! note | ||
Обратите внимание, что все потребители подписаны с использованием одной `queue_group`: в рамках одного сервиса это не имеет смысла, так как сообщения будут приходить в эти обработчики поочередно. | ||
Здесь мы эмулируем работу несколько потребителей и балансировку нагрузки между ними. | ||
|
||
### Распределение сообщений | ||
|
||
Теперь распределение сообщений между этими потребителями будет выглядеть следующим образом: | ||
|
||
```python | ||
{!> docs_src/nats/direct.py [ln:21]!} | ||
``` | ||
|
||
Сообщение `1` будет отправлено в `handler1` или `handler2`, т.к. они слушают один `subject` в рамках одной `queue group` | ||
|
||
--- | ||
|
||
```python | ||
{!> docs_src/nats/direct.py [ln:22]!} | ||
``` | ||
|
||
Сообщение `2` будет отправлено аналогично сообщению `1` | ||
|
||
--- | ||
|
||
```python | ||
{!> docs_src/nats/direct.py [ln:23]!} | ||
``` | ||
|
||
Сообщение `3` будет отправлено в `handler3`, т.к. он единственный слушает `test-subj-2` |
Oops, something went wrong.