Брокеры сообщений
1) Зачем брокеры сообщений
Брокер развязывает продюсеров и консюмеров по времени/скорости/надежности:- Буферизация и сглаживание пиков, бэкпрешер.
- Масштабирование чтения/записи независимо.
- Наблюдаемость и воспроизведение (replay) событий.
- Архитектурные паттерны: event-driven, CQRS, event sourcing, outbox/inbox.
2) Базовые модели и термины
2.1 Kafka (логовая модель)
Топик → партиции (упорядоченные логи) → офсеты у консюмеров.
Consumer Group: параллелизм чтения, балансировка партиций.
Ретеншн по времени/объему; компакция по ключу.
Семантика: минимум — at-least-once, при настройках — effectively exactly-once (идемпотентные продюсеры + транзакции).
Порядок: гарантируется внутри партиции.
2.2 NATS (темы/subjects, низкая задержка)
Subject (тема) с иерархией и вайлдкартами (`foo.`, `foo.>`).
Режимы: pub/sub, queue-groups (фан-аут с распределением работы), request-reply (быстрый RPC).
Core NATS — эфемерный, сверхнизкая латентность; JetStream — персистентность/ретеншн/повторы.
Порядок: лучший-усилием, без сильной глобальной гарантии; с JetStream — упорядочивание на стриме, но возможны редкие переупорядочивания при отказах.
3) Семантики доставки и согласованность
Идемпотентность и дедуп — ответственность приложения/синка, даже при «exactly-once» в Kafka.
4) Порядок, партиционирование и ключи
Kafka
Выбор ключа сообщения определяет партицию → сильный локальный порядок.
Ключи: `aggregate_id`, `tenant_id`, `order_id`. Избегайте горячих ключей.
Баланс: N партиций ≈ уровень параллелизма чтения.
NATS
В Core баланс делает queue-group.
В JetStream Stream шардингуется по subjects; упор на широкую фан-аут/фан-ин с малой задержкой.
5) Ретеншн, реплей и компакция
Kafka
Retention: `retention.ms/bytes`.
Compaction: хранит «последнее значение по ключу» (подходит для снапшотов/кешей/саг).
Replay: любой консюмер может «отмотать» офсеты.
JetStream
Streams: файловые/мемори бэкенды, политикa хранения по времени/байтам/кол-ву сообщений.
Consumers: pull/push, durable/ephemeral, фильтр по subject-префиксам.
Replay: redelivery или чтение с начала/offset-like (sequence).
6) Транзакции, outbox и согласованность
Kafka
Idempotent Producer (`enable.idempotence=true`): защита от дублей.
Transactions: атомарная запись нескольких партиций + коммит consumer-offsets → паттерн read-process-write без «дырок».
Transactional Outbox: запись бизнес-события и outbox-строки в одной БД-транзакции, воркер публикует в Kafka.
NATS
Нет «меж-стримовых» транзакций как в Kafka; используйте outbox/inbox и идемпотентные консюмеры (ключи, дедуп-стор).
7) RPC и запрос-ответ
Kafka для RPC неудобна (высокий overhead, порядок/ответы сложнее). Используйте асинхронные команды/события.
NATS: идеален для request-reply (милисекунды, корелляция, таймауты).
go resp, err:= nc. Request("profile. get", []byte(`{"id":42}`), 200time. Millisecond)
8) Эксплуатация и топологии
8.1 Kafka
Кластер: брокеры + ZooKeeper (до старых версий) или KRaft (новая метадата).
Репликация: RF≥3 по зонам, ISR/контроллеры.
Мультирегион: MirrorMaker 2/Cluster Linking; актив-пассив/актив-актив с конфликт-политиками.
Дисковая/сетевая емкость: считать из `throughput × retention × replicas`.
8.2 NATS
Cluster: много узлов, super-cluster (геораспределение), leafnodes для периферии/edge.
JetStream: размещение стримов по наборам узлов (placement), репликация (R=1..5).
WAN: предсказуемо низкие задержки, легкая федерация.
9) Безопасность
Kafka
TLS (mTLS), SASL: SCRAM, OAuthBearer.
ACL на топики/группы/транзакции.
Шифрование «в покое» (OS/диски) + сетевые политики.
NATS
nkey/JWT идентичности, оператор-аккаунты, пер-subject ACL.
mTLS между узлами и клиентами.
Изоляция арендаторов (accounts) + лимиты.
10) Наблюдаемость и эксплуатационные метрики
Kafka
Брокер: `BytesIn/Out`, `RequestQueue`, `UnderReplicatedPartitions`, GC/FS stats.
Топик/партиция: `logEndOffset`, consumer lag (критично).
Продюсер/консюмер: ретраи, `batch.size`, `linger.ms`, `fetch.min.bytes`, ошибки.
Инструменты: JMX, Cruise Control (ре-баланс), Schema Registry.
NATS/JetStream
Сервер: conn/msgs/sec, RTT, CPU/mem, slow consumer детекция.
JetStream: per stream/consumer — lag, redeliveries, acks, storage bytes.
Мониторинг: встроенный endpoint, nsc/adm-CLI, дашборды.
11) Производительность и тюнинг
Kafka
Большие батчи и `linger.ms` улучшают throughput и сжимают p99.
Компрессия (lz4/zstd) экономит сеть/диск.
num.partitions по числу потребителей/ядер, но не перегибать (overhead).
Диски: NVMe предпочтительны, XFS/EXT4 с `noatime`.
NATS
Мелкие сообщения, много соединений — норма; держите queue groups «широкими».
JetStream: tune `max_ack_pending`, pull vs push, size of batches.
Backpressure: `FlowControl`, `IdleHeartbeat`, server-side limits.
12) Паттерны интеграции
Outbox/Inbox (и в Kafka, и в NATS).
SAGA: оркестрация событиями; дедуп по `saga_id+step`.
Change Data Capture (CDC): Debezium → Kafka; в NATS — паттерн «publisher из БД-триггеров/логов».
Stream processing: Kafka Streams/Flink/Spark; в NATS — сторонние процессоры/функции, JetStream consumers.
Dead Letter Queue (DLQ) и retry-политики (экспоненциальный backoff + jitter).
13) Примеры конфигураций
13.1 Kafka: создание топика и продюсер
bash kafka-topics. sh --create --topic orders \
--partitions 12 --replication-factor 3 \
--config cleanup. policy=delete \
--config retention. ms=604800000 # 7d
properties producer. properties bootstrap. servers=broker:9092 acks=all enable. idempotence=true batch. size=65536 linger. ms=10 compression. type=zstd
13.2 Kafka Streams: идемпотентная обработка (эскиз)
java builder. <String, Order>stream("orders")
.groupByKey()
.aggregate(/... /)
.toStream()
.to("orders-agg");
13.3 NATS JetStream: stream + consumer (nats CLI)
bash nats stream add ORDERS --subjects "orders. " --retention limits \
--storage file --max-bytes 100GB --replicas 3 --discard old
nats consumer add ORDERS ORDERS-WORKERS --filter "orders. created" \
--deliver pull --ack explicit --max-deliver 6 --backoff "1s,5s,30s,2m"
13.4 NATS Request-Reply (Go)
go nc, _:= nats. Connect("tls://nats:4222", nats. Secure(tlsConf))
sub, _:= nc. QueueSubscribe("calc. sum", "workers", func(m nats. Msg) {
//... process...
m. Respond([]byte("42"))
})
14) Выбор Kafka vs NATS: быстрый ориентир
Нужен реплей, длительный ретеншн, компакция, тяжелые стрим-процессы → Kafka.
Нужен быстрый RPC, фан-аут/фан-ин с микролатентностью, простая эксплуатация, edge/IoT → NATS (Core).
Нужна персистентность + фан-аут, но без тяжелой «логовой» платформы → NATS JetStream.
Строгий порядок по ключу и транзакции → Kafka.
15) Планирование емкости (упрощенно)
Kafka
1. Пропускная: `inbound_MBps × RF × retention_days × 86400` → диски.
2. Партиции: `target_concurrency` × запас 1.5–2×.
3. Сеть: p99 + репликация + продюсер компрессия.
NATS/JetStream
1. Сообщения/сек и средний размер → throughput.
2. Retention×replicas → storage.
3. Лимиты consumers (ack-pending, redeliveries), CPU на сериализацию.
16) Безопасная эксплуатация: чек-лист
- TLS/mTLS включен, секреты ротируются.
- ACL/аккаунты/квоты (per-tenant).
- Идемпотентность на консьюмерах, DLQ и ретраи с джиттером.
- Мониторинг lag/throughput/ошибок; алерты на URP (Kafka), redelivery-шторм (NATS).
- Capacity dashboards: партиции, storage, p99.
- Тесты на отказ узлов/зоны, game-days, реплей/бэкфилл.
- Документированы ключи партиционирования и схемы (Schema Registry/JSON Schema).
- Политики ретеншна/компакции/TTL согласованы с комплаенсом.
- Версии брокеров/клиентов регулярно обновляются; совместимость wire-протокола проверена.
17) Анти-паттерны
Горячий ключ (все события одного ID) → один «кипящий» поток. Шардируйте/буферизуйте.
Ретраи без идемпотентности → дубль-эффекты.
Огромные сообщения (MB-десятки) → фрагментация/паузы GC. Храните payload в объектном, посылайте ссылки.
Смешивание RPC и стриминга в Kafka → сложный жизненный цикл/порядок.
JetStream как «долговременный DWH» → не по назначению; храните долго в объектных/колоночных сторах.
Нет DLQ → «ядовитые» сообщения крутятся бесконечно.
Забытый ретеншн → диски заполнены, остановка кластера.
18) FAQ
Q: Можно ли сделать «exactly-once» в конце пайплайна?
A: На практике — эффективно да: Kafka (идемпотентный продюсер + транзакции) и идемпотентные синки (ключ, upsert). В NATS — через идемпотентность/дедуп в приложении.
Q: Что выбрать для миллиона мелких RPC/сек?
A: NATS Core: микролатентность, request-reply, легкие коннекты и queue-groups.
Q: Нужна компакция и снапшоты состояния?
A: Kafka с `cleanup.policy=compact`, ключ = агрегат/ресурс.
Q: Как бороться с лагом?
A: Увеличить число партиций/воркеров, уменьшить время обработки, батчи и prefetch, оптимизировать десериализацию, вертикально усилить брокеры/диски.
Q: Многорегион и DR?
A: Kafka — MirrorMaker 2/Cluster Linking, актив-пассив с RPO≈секунды. NATS — supercluster/leafnodes; JetStream зеркалирование/реплики по зонам.
19) Итоги
Kafka и NATS закрывают разные режимы: Kafka — долговечные журналы событий, высокий throughput, транзакционность и реплей; NATS — сверхлегкая шина для низких задержек, RPC и простого фан-аута, с JetStream для персистентности. Выбор делайте от семантики доставки, порядка и ретеншна, латентности и операционных затрат. Спроектируйте ключи/партиции, ретеншн, DLQ и наблюдаемость — и ваша событийная архитектура будет предсказуемой, масштабируемой и надежной.