Перейти к содержимому

NATS и JetStream в production

Зачем знать. NATS — лёгкая, быстрая и простая в эксплуатации messaging-система; JetStream добавляет персистентность и стримы. Часто встречается в Cloud Native и edge архитектурах (CNCF graduated, 2018). Middle 2 Go-инженер должен уметь выбрать между NATS / Kafka / RabbitMQ, настроить cluster + JetStream, реализовать durable consumers, KV-store, mirror streams и понимать гарантии доставки.

  1. Концепция: NATS Core и JetStream
  2. Production-практики
  3. Gotchas
  4. Real cases: Synadia, Walmart, Mastercard
  5. 25 вопросов
  6. Practice
  7. Источники

NATS — pub/sub бус без персистентности (in-memory), миллионы сообщений/сек, sub-ms latency.

┌─────────┐ publish "orders.created" ┌─────────┐
│Publisher│ ──────────────────────────▶│ NATS │
└─────────┘ │ server │
└────┬────┘
subscribe "orders.*" │
┌──────────┐
│Subscriber│
└──────────┘

Subjects — иерархические темы через точку: orders.us.created, metrics.cpu.high.

Wildcards:

  • * — один уровень: orders.*.created matches orders.us.created, не matches orders.us.created.v2.
  • > — все уровни от текущего: orders.> matches orders.us.created.v2.

Queue groups — load balancing внутри группы subscriber’ов:

publish ─▶ orders.created ─┬─▶ worker-1 (queue "workers") ┐
└─▶ worker-2 (queue "workers") ┘ один из них получит
└─▶ logger (без queue group) ← получит всегда

Request-Reply — встроенный pattern (RPC поверх pub/sub): publisher отправляет message на subject + inbox-subject для ответа.

msg, err := nc.Request("calc.add", []byte(`{"a":1,"b":2}`), time.Second)

NATS Core не хранит сообщения: если subscriber offline — он пропустил.

JetStream добавляет персистентный стрим поверх subjects, по сути это log с retention + durable consumers + replication.

┌─────────────────────────────────────────────────┐
│ JetStream cluster (3 nodes, RAFT) │
│ │
│ Stream "ORDERS" (subjects: orders.>) │
│ ┌──────────────────────────────────────────┐ │
│ │ msg1 msg2 msg3 ... msgN │ │
│ └──────────────────────────────────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ Consumer "billing" Consumer "shipping" │
│ (durable, ack) (durable, ack) │
└─────────────────────────────────────────────────┘

Сущности:

  • Stream — persistent set сообщений с заданным subject filter (orders.>).
  • Consumer — позиция чтения + полиси acknowledgement. Бывают push (server пушит сообщения) и pull (клиент сам pull в нужном темпе). Durable имя сохраняется при reconnect, ephemeral — удаляется по таймауту.

Acks:

  • AckExplicit (default для durable) — нужен явный ack за каждое сообщение.
  • AckNone — не нужны (fire-and-forget).
  • AckAll — ack одного сообщения = ack всех предыдущих.
  • Nak() — negative ack, redeliver.
  • InProgress() — обновить таймер AckWait, ещё работаем.
  • Term() — terminate: больше не пытайся, удали (не отправляй в DLQ-стрим).

Retention policies для stream:

  • LimitsPolicy (default) — хранить пока в пределах лимитов (MaxBytes, MaxAge, MaxMsgs).
  • WorkQueuePolicy — удаляем сообщение как только оно прочитано хоть одним consumer (queue semantics; max 1 consumer на subject в этом stream).
  • InterestPolicy — хранить пока есть consumer, заинтересованный в этом сообщении.

Storage:

  • FileStorage — файловое, persist через restart.
  • MemoryStorage — RAM-only, теряется при restart, но быстрое.

Replication: Replicas=3 — данные на 3 узлах через RAFT (NATS использует JetStream RAFT для consensus).

Server-side filtering: FilterSubject на consumer — стрим может содержать orders.>, а consumer читать только orders.us.>.

KV (Key-Value) — поверх JetStream stream с compaction:

bucket "user-prefs"
─ key "user.42.theme" ──▶ "dark"
─ key "user.42.locale" ──▶ "ru"

API: Get/Put/Delete + Watch (subscribe на изменения) + History (последние N значений).

Object Store — для blob (файлы, > 8 MB):

bucket "uploads"
─ object "report.pdf" (chunked, metadata)

Mirror — read-only копия stream в другом cluster / на другом server. Используется для:

  • Geo-replication (DR copy в другом регионе).
  • Read scaling (mirror ближе к читателю).

Source — стрим может пополняться сообщениями из других стримов (mux нескольких stream в один).

Leaf node — NATS-server, который подключается к hub-кластеру как «edge-узел». Локальные клиенты работают через leaf, hub видит leaf как обычный subscriber.

┌──────────────────────┐
│ HUB cluster (cloud) │
└──────────┬───────────┘
│ leaf-connect
┌──────────▼───────────┐ ┌──────────────────────┐
│ Leaf node (edge) │ │ Leaf node (edge) │
│ Factory robot │ │ Branch office │
└──────────────────────┘ └──────────────────────┘

Subject пространство склеивается, JetStream может быть и на leaf, и на hub.

  • Cluster — 3+ NATS-серверов, гошшипят, обеспечивают HA.
  • Gateway — connection между cluster’ами (для гео-распределённой архитектуры).
  • Super-cluster — несколько cluster’ов соединены через gateways. Subject-пространство глобально, маршрутизация автоматическая.
┌──────────────┐ gateway ┌──────────────┐
│ Cluster US │──────────▶│ Cluster EU │
│ 3 servers │◀──────────│ 3 servers │
└──────────────┘ └──────────────┘
NATSNATS JetStreamKafkaRabbitMQ
Persistenceнетдадада
Throughputочень высокийвысокийочень высокийсредний
Latencysub-ms~ms~ms-10msms
Opsочень простойпростойсложныйсредний
Single binaryдаданет (JVM)нет (Erlang)
Ecosystemрастущийрастущийогромныйбольшой
Use caseRPC, real-timestreams, KVdata pipelines, EoSflexible routing

import "github.com/nats-io/nats.go"
nc, err := nats.Connect(
"nats://n1:4222,nats://n2:4222,nats://n3:4222",
nats.Name("orders-service"),
nats.MaxReconnects(-1), // бесконечно
nats.ReconnectWait(2*time.Second),
nats.PingInterval(20*time.Second),
nats.MaxPingsOutstanding(5),
nats.ReconnectBufSize(8*1024*1024), // буфер на время disconnect
nats.ErrorHandler(func(_ *nats.Conn, sub *nats.Subscription, err error) {
log.Errorw("nats error", "sub", sub.Subject, "err", err)
}),
nats.DisconnectErrHandler(func(_ *nats.Conn, err error) {
log.Warnw("disconnected", "err", err)
}),
nats.ReconnectHandler(func(c *nats.Conn) {
log.Infow("reconnected", "url", c.ConnectedUrl())
}),
nats.UserCredentials("./user.creds"), // для NATS 2.0+ accounts/JWT
nats.RootCAs("./ca.pem"),
)
// publish
nc.Publish("orders.created", payload)
// subscribe
sub, _ := nc.Subscribe("orders.*", func(m *nats.Msg) {
process(m.Data)
})
defer sub.Unsubscribe()
// queue group (load balancing)
nc.QueueSubscribe("orders.created", "workers", func(m *nats.Msg) { ... })
// request-reply
msg, err := nc.Request("calc.add", body, 2*time.Second)
js, err := nc.JetStream(nats.PublishAsyncMaxPending(256))
_, err = js.AddStream(&nats.StreamConfig{
Name: "ORDERS",
Subjects: []string{"orders.>"},
Storage: nats.FileStorage,
Replicas: 3,
Retention: nats.LimitsPolicy,
MaxAge: 7 * 24 * time.Hour,
MaxBytes: 100 << 30, // 100 GB
Discard: nats.DiscardOld,
Duplicates: 2 * time.Minute, // окно дедупликации
})
ack, err := js.Publish("orders.us.created", payload,
nats.MsgId(orderID), // дедупликация в окне Duplicates
nats.AckWait(5*time.Second),
)
log.Infow("published", "stream", ack.Stream, "seq", ack.Sequence)

⚠️ NATS дедуплицирует по Nats-Msg-Id в окне Duplicates (default 2 минуты). Этого достаточно для retry, но не «вечная» дедупликация.

Pull (предпочтительно для backend):

sub, _ := js.PullSubscribe("orders.>", "billing",
nats.AckExplicit(),
nats.MaxDeliver(5),
nats.AckWait(30*time.Second),
)
for {
msgs, err := sub.Fetch(100, nats.MaxWait(5*time.Second))
if errors.Is(err, nats.ErrTimeout) { continue }
for _, m := range msgs {
if err := process(m.Data); err != nil {
m.NakWithDelay(30 * time.Second) // retry через 30 секунд
continue
}
m.Ack()
}
}

Push (server пушит, мы реагируем):

sub, _ := js.Subscribe("orders.>", func(m *nats.Msg) {
if err := process(m.Data); err != nil {
m.Nak()
return
}
m.Ack()
}, nats.Durable("billing"), nats.ManualAck())
js.AddConsumer("ORDERS", &nats.ConsumerConfig{
Durable: "us-billing",
FilterSubject: "orders.us.>", // только US
AckPolicy: nats.AckExplicitPolicy,
DeliverPolicy: nats.DeliverAllPolicy,
})

Network экономия: сообщения не из orders.us.> даже не отправляются на consumer.

kv, err := js.CreateKeyValue(&nats.KeyValueConfig{
Bucket: "user-prefs",
History: 5, // последние 5 значений
Storage: nats.FileStorage,
Replicas: 3,
})
kv.Put("user.42.theme", []byte("dark"))
entry, _ := kv.Get("user.42.theme")
// Watch (live-stream изменений)
w, _ := kv.WatchAll()
for upd := range w.Updates() {
if upd == nil { continue } // конец initial state
log.Infow("changed", "key", upd.Key(), "value", string(upd.Value()))
}

KV — отличная альтернатива Redis для feature flags, конфигов, distributed locks.

obs, _ := js.CreateObjectStore(&nats.ObjectStoreConfig{
Bucket: "uploads",
Storage: nats.FileStorage,
Replicas: 3,
})
obs.PutFile("report.pdf")
obs.GetFile("report.pdf", "/tmp/report.pdf")
js.AddStream(&nats.StreamConfig{
Name: "ORDERS_MIRROR_EU",
Mirror: &nats.StreamSource{
Name: "ORDERS",
FilterSubject: "orders.eu.>",
External: &nats.ExternalStream{
APIPrefix: "$JS.us.API",
DeliverPrefix: "deliver.us",
},
},
Replicas: 3,
})

nats-server.conf (один из 3 узлов):

server_name: n1
listen: 0.0.0.0:4222
cluster {
name: prod
listen: 0.0.0.0:6222
routes = [
nats://n1:6222
nats://n2:6222
nats://n3:6222
]
}
jetstream {
store_dir: /var/lib/nats
max_memory_store: 4G
max_file_store: 200G
}
http_port: 8222 # monitoring

3-узловый cluster — минимум для JetStream RAFT (quorum ≥ 2).

NATS 2.0+ имеет multi-tenant систему accounts: изоляция subject-пространства между приложениями, JWT-based authentication.

  • Operator (root)
  • Accounts (tenants)
  • Users (внутри account, JWT-signed)

Утилита nsc создаёт и подписывает JWT.

В Go-клиенте:

nats.UserCredentials("./alice.creds")
  • Встроенный HTTP monitoring на :8222: /varz, /jsz?streams=true, /connz, /routez.
  • prometheus-nats-exporter — официальный Prometheus exporter.
  • NATS surveyor — distributed monitoring.
  • NATS CLI: nats stream report, nats consumer info, nats pub, nats sub.

Бери NATS / JetStream если:

  • нужна простая ops: single binary, кластер из 3 узлов и поехали;
  • нужны RPC / request-reply / live pub-sub;
  • нужно edge / IoT (leaf nodes);
  • размер сообщений малый-средний, объём не петабайты;
  • хочется KV-store или object store в той же системе.

Бери Kafka если:

  • нужен максимальный throughput / retention петабайты;
  • нужен богатый ecosystem (Kafka Connect, Streams, ksqlDB, Schema Registry);
  • нужен EoS read-process-write pattern;
  • уже инвестировано в Kafka.

⚠️ NATS Core ≠ persistent. Если subscriber offline — сообщение потеряно. Для durable — JetStream.

⚠️ JetStream дедупликация имеет окно Duplicates (default 2 мин). Сверх окна — дубли пройдут. Не путать с idempotence Kafka.

⚠️ AckWait слишком короткий → сообщение redelivered, ты обрабатываешь повторно. Стандарт 30s, и периодически вызывай m.InProgress() для длинных задач.

⚠️ Pull subscription Fetch блокирует. Делай nats.MaxWait и обрабатывай ErrTimeout как «нет сообщений сейчас».

⚠️ JetStream cluster < 3 узлов = нет HA. Quorum для RAFT = (N/2)+1. На 1-2 узлах работает, но при падении lost.

⚠️ Mirror stream — read-only. Publish напрямую в mirror невозможен.

⚠️ MaxAckPending (default 1000) ограничивает сколько unacked сообщений может быть «в работе» у consumer. Превышение → server перестаёт отдавать новые. Поднимай для batch-обработки.

⚠️ MaxDeliver=-1 = бесконечный redelivery; poison message может зациклиться. Ставь конечное значение + DLQ-стрим.

⚠️ DLQ в NATS делается через source stream или ручным publish; нет встроенного DLX как в RabbitMQ.

⚠️ Memory storage теряет данные при рестарте. Не используй для прод.

⚠️ WorkQueuePolicy + 2 consumer на одном subject = ошибка. Только один consumer на subject в work-queue stream.

⚠️ Subject хранятся в памяти на сервере (для роутинга). Миллионы уникальных subjects = memory pressure.

⚠️ Sticky connection. При nats://a,b,c клиент выбирает один сервер; reconnect — другой. Балансировка только при reconnect, не per-message.

⚠️ JWT-токены не expirable «вечно». Если оператор скомпрометирован — нужен rotate (новая chain trust).

⚠️ NATS использует Subject length ограничение 255, payload по умолчанию 1 MB (max_payload). Для блобов — Object Store.

⚠️ Конфликт версий между сервером и клиентом. Старый клиент может не понимать новых фич JetStream. Держи серверы свежие, клиенты в lockstep.


Synadia Cloud / NGS — managed NATS глобально, с decentralized auth (operators, accounts), используют JetStream для коммерческого SaaS. Доказывает что NATS масштабируется до глобального multi-tenant.

Walmart использует NATS для интеграции магазинов (десятки тысяч точек): leaf nodes в каждом магазине, hub-cluster в дата-центрах. Архитектура «edge with central control plane»: команды и события идут через NATS.

Mastercard использует NATS для микросервисной шины внутри платёжной обработки: высокая throughput, sub-ms latency для критических path. NATS Core (без JetStream) для быстрых внутренних RPC.

  • Microservices RPC: request-reply вместо REST/gRPC внутри cluster.
  • Real-time UI: WebSocket-сервис подписывается на JetStream, пушит изменения в браузер.
  • IoT/Edge: NATS как протокол для устройств (есть mqtt-мост, leaf nodes).
  • Replacement Redis Pub/Sub + опционально KV-store.

1. Что такое NATS? Лёгкая cloud-native messaging-система с pub/sub, request-reply, queue groups. Pure Go-сервер, single binary.

2. Чем NATS Core отличается от JetStream? Core — in-memory pub/sub без персистентности. JetStream — добавляет persistent streams, durable consumers, KV, Object Store.

3. Что такое subject в NATS? Иерархическая тема через точку (orders.us.created); может фильтроваться wildcards * и >.

4. Что делает * и > в subject? * — ровно один уровень; > — все уровни от текущего.

5. Что такое queue group? Группа subscriber’ов на один subject; сообщение получает только один член группы (load balancing).

6. Что такое request-reply в NATS? Built-in RPC pattern: client публикует на subject + указывает inbox-subject для ответа, server отвечает на inbox.

7. Что такое stream в JetStream? Persistent log сообщений с заданным subject filter, retention и replication.

8. Какие retention policies в JetStream?

  • LimitsPolicy — пока в пределах лимитов.
  • WorkQueuePolicy — удаляется после ack.
  • InterestPolicy — пока есть заинтересованный consumer.

9. Что такое consumer в JetStream? Позиция чтения в stream + ack policy; бывают push/pull и durable/ephemeral.

10. Pull vs push consumer? Push — сервер сам шлёт сообщения (нужна обработка backpressure на клиенте). Pull — клиент сам Fetch(N), удобнее для batch.

11. Какие ack-методы у JetStream? Ack, Nak, InProgress, Term, AckAll. Nak запускает redelivery, Term — окончательное прекращение.

12. Как сделать дедупликацию в JetStream? Publish с Nats-Msg-Id header (или nats.MsgId(id) в Go) — сервер дедуплицирует в окне Duplicates.

13. Что такое FilterSubject у consumer? Server-side фильтр: stream хранит broad subjects, consumer читает узкий подмножество.

14. Что такое KV bucket? Key-Value store поверх JetStream stream с compaction; поддерживает Get/Put/Delete/Watch/History.

15. Что такое Object Store? Хранилище для крупных blob (файлы) поверх JetStream; данные чанкуются.

16. Что такое mirror stream? Read-only копия stream в другом cluster / на другом сервере; для DR/geo-replication.

17. Что такое leaf node? NATS-сервер на edge, подключённый к hub-cluster через leaf-connection; subject space склеивается.

18. Что такое gateway? Connection между cluster’ами в super-cluster; обеспечивает гео-распределение.

19. Минимум узлов для HA JetStream? 3 узла (RAFT quorum). На 1-2 — нет HA.

20. Какие основные параметры StreamConfig? Subjects, Storage, Replicas, Retention, MaxAge, MaxBytes, Discard, Duplicates.

21. Какие основные параметры ConsumerConfig? Durable, AckPolicy, AckWait, MaxDeliver, FilterSubject, DeliverPolicy, MaxAckPending.

22. Что такое accounts в NATS 2.0? Multi-tenant изоляция: subject-пространство, лимиты, JWT-auth разделены между accounts.

23. Когда выбрать NATS вместо Kafka? Если приоритет — простота ops, RPC/request-reply, edge, low-latency real-time messaging.

24. Когда Kafka выгоднее NATS? Очень высокая throughput, петабайтная retention, EoS read-process-write, богатый ecosystem (Connect, Streams, Schema Registry).

25. Как сделать DLQ в JetStream? Конечный MaxDeliver + publish failed-message в отдельный DLQ-stream (вручную) + Term() исходного.


  1. NATS cluster local. Запусти 3-узловый NATS-кластер локально (docker-compose), включи JetStream, проверь репликацию через nats stream report.

  2. Durable pull consumer. Реализуй Go-consumer на stream ORDERS, MaxDeliver=5, AckWait=30s, при ошибке — NakWithDelay(30s). Покажи что после 5 попыток сообщение уйдёт в DLQ-стрим.

  3. KV для feature flags. Создай KV-bucket flags, реализуй middleware который проверяет flag через Get, и Watch-loop, чтобы обновлять in-memory cache.

  4. Request-reply microservice. Сервис calc обрабатывает calc.add/calc.mul через nc.Subscribe; клиент использует nc.Request. Замерь latency vs HTTP/gRPC.

  5. Mirror stream. Создай stream ORDERS в одном cluster, mirror ORDERS_DR в другом; останови источник, проверь что mirror сохранил данные.

  6. Object store. Загрузи 100 MB файл в Object Store, скачай в другом процессе, проверь чанкование.

  7. Leaf node. Подними leaf node, соедини с hub, опубликуй subject из leaf, прими в hub.

  8. JetStream + outbox. Postgres outbox-таблица + Go-poller, публикует в JetStream с Nats-Msg-Id = outbox-id; verify дедупликацию.

  9. Сравни throughput NATS Core vs JetStream vs Kafka на одном железе (1 KB payload, 4 producers, 4 consumers).

  10. Prometheus monitoring. Подними prometheus-nats-exporter, дашборд в Grafana: stream lag, consumer pending, server CPU.


┌───────────────────────────────────────────────────────────┐
│ SUPER-CLUSTER │
│ │
│ ┌──────────────┐ gateway ┌──────────────┐ │
│ │ Cluster US │◀──────────▶│ Cluster EU │ │
│ │ │ │ │ │
│ │ ┌──┬──┬──┐ │ │ ┌──┬──┬──┐ │ │
│ │ │n1│n2│n3│ │ │ │e1│e2│e3│ │ │
│ │ └──┴──┴──┘ │ │ └──┴──┴──┘ │ │
│ └──┬───────────┘ └──────────────┘ │
│ │ leaf-connect │
│ ▼ │
│ ┌──────────────┐ │
│ │ Leaf (edge) │ ← локальные клиенты ходят сюда │
│ │ store 1 │ │
│ └──────────────┘ │
└───────────────────────────────────────────────────────────┘
Stream "ORDERS"
├── subjects: orders.>
├── storage: file
├── replicas: 3
├── retention: limits
├── max_age: 7d
├── max_bytes: 100GB
├── discard: old
├── duplicate_window: 2m
└── consumers:
├── "billing" (durable, pull, ack_explicit, max_deliver=5, filter=orders.us.>)
├── "shipping" (durable, push, ack_explicit, filter=orders.eu.>)
└── "audit" (ephemeral, push, ack_none)
for {
msgs, err := sub.Fetch(50, nats.MaxWait(2*time.Second))
if errors.Is(err, nats.ErrTimeout) { continue }
if err != nil {
log.Warnw("fetch failed", "err", err)
time.Sleep(time.Second) // не спамим брокер
continue
}
for _, m := range msgs {
meta, _ := m.Metadata()
if meta.NumDelivered > 5 {
// poison message → DLQ stream + Term
publishDLQ(m)
m.Term()
continue
}
if err := process(m.Data); err != nil {
delay := time.Duration(meta.NumDelivered) * 10 * time.Second
m.NakWithDelay(delay)
continue
}
m.Ack()
}
}
  • Feature flags: kv.Put("flag.new_checkout", []byte("on")) + Watch для live-обновлений.
  • Distributed lock: kv.Create(key, value) атомарен (Create fails если ключ есть) — простой lock.
  • Session storage: TTL per-key (History+MaxAge).
  • Service discovery: keys как services.<name>.<instance> + Watch для появления/исчезновения.
СценарийThroughputLatency p99
Core pub-sub, 256B7M msg/s0.5 ms
Core request-reply, 256B800k req/s1 ms
JetStream (file, RF=3), 1KB200k msg/s5-10 ms
JetStream (mem, RF=1), 1KB1M msg/s1-2 ms

(данные ориентировочные, зависят от железа; сравни с Kafka где JetStream-prod аналог ~ Kafka producer perf, но с гораздо меньшим bootstrap).

Кейс: команда платежей раньше пользовалась Kafka для микросервисной шины, перешла на NATS JetStream:

  • Ops стала проще — single binary, 3 узла, без Zookeeper/KRaft.
  • Удалось убрать RPC через REST → request-reply поверх NATS.
  • Throughput не пострадал (объёмы не петабайты).
  • Минус: пришлось заменить Kafka Connect-pipeline на собственный (NATS экосистема меньше).
  • Nak (или NakWithDelay) — временная ошибка: внешний сервис недоступен, retry поможет.
  • Term — постоянная ошибка: payload corrupt, validation failed, нет смысла retry.
  • Ack без обработки = потеря данных. Опасно для critical путей; делайте только когда уверены.
  • Cluster 3+ узлов с RAFT JetStream.
  • JetStream storage на SSD/NVMe, отдельный диск.
  • max_memory_store, max_file_store сконфигурированы.
  • Auth через accounts/JWT (не shared username/password).
  • TLS на listen-port и cluster route.
  • Streams с replicas=3, file storage.
  • DLQ stream + MaxDeliver конечный.
  • Prometheus monitoring + Grafana дашборд.
  • Alerts: stream pending, server down, raft un-healthy.
  • Backup: nats stream backup regular.
  • Тестирование leaf node disconnect/reconnect.
Окно терминала
# Состояние сервера
nats server check connection
nats server info
# Streams
nats stream ls
nats stream info ORDERS
nats stream report
nats stream backup ORDERS ./backup
# Consumers
nats consumer ls ORDERS
nats consumer info ORDERS billing
nats consumer report ORDERS billing
# KV
nats kv ls
nats kv put flags new_checkout on
nats kv watch flags
# Pub/sub
nats sub "orders.>"
nats pub "orders.us.created" '{"id":1}'
nats req "calc.add" '{"a":1,"b":2}'
# Контекст (multi-cluster)
nats context save prod --server nats://prod:4222 --creds ./prod.creds
nats context select prod

7.10 Сравнение JetStream и Kafka на конкретных аспектах

Заголовок раздела «7.10 Сравнение JetStream и Kafka на конкретных аспектах»
АспектKafkaJetStream
HA: replicationleader/followers ISRRAFT
HA: failoverleader electionRAFT leader election
Дедупликацияпо PID+seq внутри sessionпо Msg-Id в окне Duplicates
Retentionsize / timesize / time / interest / work-queue
Filtering на сервереpartitions onlyпо subject filter (точечный)
KV / Object Storeвнешние тулзывстроено
Cross-clusterMirrorMaker 2gateways / mirror streams
Single binaryнет (JVM)да
Min cluster3 brokers3 servers

  1. NATS Documentation — официальная документация.
  2. JetStream design and architecture — глубокий разбор.
  3. nats-io/nats.go — Go-клиент.
  4. NATS by Example — рецепты, в т.ч. на Go.
  5. Synadia blog — статьи от создателей.
  6. Practical NATS — Waldemar Quevedo.
  7. CNCF: NATS case studies — Walmart, Mastercard и др.
  8. nats-server конфигурация — все параметры.
  9. Comparing Kafka, RabbitMQ, NATS (Confluent blog, обзоры 2024) — сравнение.
  10. prometheus-nats-exporter — мониторинг.