NATS и RabbitMQ в Go
Зачем знать: Kafka — не единственный брокер. NATS — лёгкий, быстрый для real-time messaging и RPC между микросервисами; JetStream добавляет persistence. RabbitMQ — гибкая маршрутизация на AMQP, идеален для task queues. Middle 1 Go-разработчик в 2026 должен понимать, когда выбрать NATS vs Kafka vs RabbitMQ, уметь работать с обоими клиентами и осознавать ограничения (at-most-once у Core NATS, retention у RabbitMQ).
Содержание
Заголовок раздела «Содержание»- Базовая концепция
- Как в Go (с примерами)
- Gotchas
- Best practices в production
- Вопросы на собесе
- Practice
- Источники
1. Базовая концепция
Заголовок раздела «1. Базовая концепция»NATS (от Apcera, сейчас CNCF) — высокопроизводительный pub-sub и request-reply messaging. Single binary, < 20MB, миллионы сообщений в секунду.
Subjects (темы)
Заголовок раздела «Subjects (темы)»Не очереди и не topics — subjects. Иерархия через .:
orders.createdpayments.refunded.eu
Wildcards:
*— один уровень:orders.*ловитorders.created,orders.canceled, но неorders.eu.created.>— много уровней:orders.>ловит всё подorders.
Core NATS — at-most-once
Заголовок раздела «Core NATS — at-most-once»- Fire-and-forget. Подписчика нет / в моменте недоступен → сообщение теряется.
- Очень быстрый: < 1ms latency, миллионы msg/sec.
- Использует TCP, но без durability.
NATS JetStream
Заголовок раздела «NATS JetStream»- Persistent layer поверх Core NATS.
- Streams (как Kafka topics), Consumers (durable / push / pull / ephemeral).
- At-least-once / exactly-once delivery.
- KV Store, Object Store (S3-like).
- Replication (Raft).
NATS use cases
Заголовок раздела «NATS use cases»- Microservices RPC (request-reply).
- Real-time notifications.
- IoT / edge messaging.
- Service mesh control plane.
- KV (как distributed Redis-lite).
RabbitMQ
Заголовок раздела «RabbitMQ»RabbitMQ — реализация AMQP 0.9.1 (Advanced Message Queuing Protocol). Erlang-based, зрелый (с 2007).
Концепции
Заголовок раздела «Концепции»- Connection — TCP-соединение клиент-сервер.
- Channel — мультиплексирование внутри connection (1 connection, N channels).
- Exchange — routing primitive (direct, fanout, topic, headers).
- Queue — собственно очередь сообщений (FIFO, persistent или нет).
- Binding — правило: какие сообщения exchange → queue по routing key.
- Consumer — приложение, читающее из queue.
Exchanges
Заголовок раздела «Exchanges»- Direct — routing key точно равно binding key. (
orders.created→ queue с bindingorders.created) - Fanout — игнорирует routing key, шлёт всем bind queues. (broadcast)
- Topic — wildcards (
*,#):orders.*→orders.createdmatches. - Headers — по headers (редко используется).
Acknowledgements
Заголовок раздела «Acknowledgements»- autoAck — сразу ack при доставке (риск потери).
- manualAck — consumer вызывает
Ack(deliveryTag, multiple)после обработки. - Nack/Reject — отрицательное подтверждение, может вернуть в очередь.
Queue types
Заголовок раздела «Queue types»- Classic queues — оригинальные. Не для prod в 2026 (mirrored queues deprecated в 3.9).
- Quorum queues — Raft-based, HA, replication. Стандарт для prod.
- Streams — append-only, Kafka-like (RabbitMQ 3.9+).
DLX (Dead Letter Exchange)
Заголовок раздела «DLX (Dead Letter Exchange)»Сообщения, которые отвергли (nack, expired, queue overflow), отправляются в DLX → DLQ.
RabbitMQ use cases
Заголовок раздела «RabbitMQ use cases»- Task queues (фоновые задачи, retries).
- Complex routing (one event → 5 queues).
- RPC (через reply_to и correlation_id).
- Workflow orchestration.
Сравнение
Заголовок раздела «Сравнение»| Kafka | NATS (Core) | NATS JetStream | RabbitMQ | |
|---|---|---|---|---|
| Latency | 5-50ms | < 1ms | 1-5ms | 1-10ms |
| Throughput | 1M msg/s/node | 5M+ msg/s | 100K-1M msg/s | 50K msg/s/queue |
| Persistence | yes | no | yes | yes |
| Ordering | per partition | no | per stream | per queue |
| Replay | yes | no | yes | streams only |
| Routing | по partition | subjects + wildcards | subjects | exchanges (direct/topic/fanout/header) |
| Per-msg ack | no | no | yes | yes |
| Priority | no | no | no | yes |
| Delay/scheduling | no | no | nakDelay | plugin / delayed exchange |
| Setup | heavy (broker + KRaft) | single binary | single binary | medium |
Выбор брокера (2026)
Заголовок раздела «Выбор брокера (2026)»- Real-time messaging, low latency, microservices RPC → NATS Core.
- At-least-once + persistence + streams, медиум scale → NATS JetStream.
- High throughput streaming, replay, audit log → Kafka.
- Complex routing, task queues, retries/delays → RabbitMQ.
- Tiny scale, dev/local → Redis Streams.
2. Как в Go (с примерами)
Заголовок раздела «2. Как в Go (с примерами)»2.1 NATS Core: установка
Заголовок раздела «2.1 NATS Core: установка»go get github.com/nats-io/nats.goЛокальный nats-server:
docker run -p 4222:4222 nats:latest2.2 NATS publisher/subscriber
Заголовок раздела «2.2 NATS publisher/subscriber»package main
import ( "github.com/nats-io/nats.go" "log" "time")
func main() { nc, err := nats.Connect("nats://localhost:4222", nats.Name("my-service"), nats.MaxReconnects(-1), nats.ReconnectWait(time.Second), nats.DisconnectErrHandler(func(_ *nats.Conn, err error) { log.Printf("disconnected: %v", err) }), nats.ReconnectHandler(func(c *nats.Conn) { log.Printf("reconnected to %s", c.ConnectedUrl()) }), ) if err != nil { log.Fatal(err) } defer nc.Close()
// Subscriber (async) sub, _ := nc.Subscribe("orders.*", func(m *nats.Msg) { log.Printf("got: subject=%s data=%s", m.Subject, m.Data) }) defer sub.Unsubscribe()
// Publisher for i := 0; i < 10; i++ { nc.Publish("orders.created", []byte("hello")) } nc.Flush()
time.Sleep(time.Second)}2.3 NATS Request-Reply (RPC)
Заголовок раздела «2.3 NATS Request-Reply (RPC)»// Server sidenc.Subscribe("math.add", func(m *nats.Msg) { a, b := parse(m.Data) m.Respond([]byte(fmt.Sprintf("%d", a+b)))})
// Client sideresp, err := nc.Request("math.add", []byte("2 3"), 2*time.Second)if err == nil { fmt.Println(string(resp.Data)) // "5"}Под капотом — inbox subject и reply-to header.
2.4 NATS Queue Group (load balancing)
Заголовок раздела «2.4 NATS Queue Group (load balancing)»nc.QueueSubscribe("orders.created", "orders-workers", func(m *nats.Msg) { // сообщение получит один из подписчиков queue group})В отличие от обычного subscribe, в queue group сообщение получает только один подписчик. Это load balancing.
2.5 JetStream — stream + consumer
Заголовок раздела «2.5 JetStream — stream + consumer»js, _ := jetstream.New(nc) // jetstream package в nats.go
ctx := context.Background()
// Создаём stream_, err := js.CreateStream(ctx, jetstream.StreamConfig{ Name: "ORDERS", Subjects: []string{"orders.>"}, Storage: jetstream.FileStorage, Retention: jetstream.WorkQueuePolicy, // или LimitsPolicy MaxAge: 24 * time.Hour, Replicas: 3,})
// Producerack, _ := js.Publish(ctx, "orders.created", []byte(`{"id":"o-1"}`))log.Printf("seq=%d", ack.Sequence)
// Consumer (pull-based, рекомендуется)stream, _ := js.Stream(ctx, "ORDERS")cons, _ := stream.CreateOrUpdateConsumer(ctx, jetstream.ConsumerConfig{ Durable: "workers", AckPolicy: jetstream.AckExplicitPolicy, MaxDeliver: 5, AckWait: 30 * time.Second, DeliverPolicy: jetstream.DeliverNewPolicy,})
// Consume loopit, _ := cons.Messages()for { msg, err := it.Next() if err != nil { continue } if err := process(msg.Data()); err != nil { msg.Nak() continue } msg.Ack()}2.6 JetStream KV
Заголовок раздела «2.6 JetStream KV»kv, _ := js.CreateOrUpdateKeyValue(ctx, jetstream.KeyValueConfig{ Bucket: "config", TTL: time.Hour,})kv.Put(ctx, "service.url", []byte("https://..."))entry, _ := kv.Get(ctx, "service.url")Распределённый KV с TTL, watch, history.
2.7 RabbitMQ: установка
Заголовок раздела «2.7 RabbitMQ: установка»go get github.com/rabbitmq/amqp091-goЛокально:
docker run -p 5672:5672 -p 15672:15672 rabbitmq:3-managementUI на http://localhost:15672 (guest/guest).
2.8 RabbitMQ producer
Заголовок раздела «2.8 RabbitMQ producer»package main
import ( "context" "github.com/rabbitmq/amqp091-go" "log")
func main() { conn, err := amqp091.Dial("amqp://guest:guest@localhost:5672/") if err != nil { log.Fatal(err) } defer conn.Close()
ch, err := conn.Channel() if err != nil { log.Fatal(err) } defer ch.Close()
// Declare exchange (idempotent) err = ch.ExchangeDeclare( "orders", // name "topic", // type true, // durable false, // auto-delete false, // internal false, // no-wait nil, ) if err != nil { log.Fatal(err) }
// Publish ctx := context.Background() err = ch.PublishWithContext(ctx, "orders", // exchange "orders.created", // routing key false, // mandatory false, // immediate amqp091.Publishing{ ContentType: "application/json", Body: []byte(`{"id":"o-1"}`), DeliveryMode: amqp091.Persistent, // запись на диск MessageId: "msg-1", Timestamp: time.Now(), }, )}2.9 RabbitMQ consumer
Заголовок раздела «2.9 RabbitMQ consumer»ch, _ := conn.Channel()defer ch.Close()
// Declare queue (idempotent)q, _ := ch.QueueDeclare( "orders-workers", // name true, // durable false, // auto-delete false, // exclusive false, // no-wait amqp091.Table{ "x-queue-type": "quorum", // quorum queue "x-dead-letter-exchange": "orders.dlx", },)
// Bind queue to exchangech.QueueBind(q.Name, "orders.*", "orders", false, nil)
// Prefetch (QoS)ch.Qos(10, 0, false) // 10 unacked messages per consumer
// Consumemsgs, _ := ch.Consume( q.Name, // queue "", // consumer tag (auto-generated) false, // auto-ack=false (manual) false, // exclusive false, // no-local false, // no-wait nil,)
for msg := range msgs { if err := process(msg.Body); err != nil { msg.Nack(false, false) // не вернуть в очередь → DLX continue } msg.Ack(false)}2.10 RabbitMQ DLX/DLQ
Заголовок раздела «2.10 RabbitMQ DLX/DLQ»// Main queue с DLXch.QueueDeclare("orders", true, false, false, false, amqp091.Table{ "x-dead-letter-exchange": "orders.dlx",})
// DLX exchangech.ExchangeDeclare("orders.dlx", "fanout", true, false, false, false, nil)
// DLQ queue, bound to DLXch.QueueDeclare("orders.dlq", true, false, false, false, nil)ch.QueueBind("orders.dlq", "", "orders.dlx", false, nil)Nack(requeue=false) → exchange orders.dlx → queue orders.dlq.
2.11 Delayed messages (RabbitMQ plugin)
Заголовок раздела «2.11 Delayed messages (RabbitMQ plugin)»// Requires rabbitmq_delayed_message_exchange pluginch.ExchangeDeclare("orders.delayed", "x-delayed-message", true, false, false, false, amqp091.Table{ "x-delayed-type": "topic",})
ch.PublishWithContext(ctx, "orders.delayed", "orders.retry", false, false, amqp091.Publishing{ Body: []byte(`...`), Headers: amqp091.Table{ "x-delay": 30000, // 30 секунд },})2.12 RabbitMQ Publisher Confirms
Заголовок раздела «2.12 RabbitMQ Publisher Confirms»Чтобы гарантировать, что сообщение записано на диск:
ch.Confirm(false)confirms := ch.NotifyPublish(make(chan amqp091.Confirmation, 1))
ch.PublishWithContext(...)
conf := <-confirmsif !conf.Ack { // сообщение не записано, retry}В amqp091-go есть удобный PublishWithDeferredConfirmWithContext.
2.13 RabbitMQ RPC
Заголовок раздела «2.13 RabbitMQ RPC»// ClientreplyQ, _ := ch.QueueDeclare("", false, false, true, false, nil)corrID := uuid.NewString()
ch.PublishWithContext(ctx, "", "rpc.add", false, false, amqp091.Publishing{ ContentType: "application/json", CorrelationId: corrID, ReplyTo: replyQ.Name, Body: []byte(`{"a":2,"b":3}`),})
msgs, _ := ch.Consume(replyQ.Name, "", true, false, false, false, nil)for m := range msgs { if m.CorrelationId == corrID { fmt.Println(string(m.Body)) break }}2.14 Tracing OTel
Заголовок раздела «2.14 Tracing OTel»NATS:
import "github.com/nats-io/nats.go/encoders/protobuf"// trace propagation вручную через msg.Header.Set("traceparent", ...)RabbitMQ:
// trace propagation через headers в amqp091.Publishing.HeadersГотовых contrib-инструментаций как у HTTP пока меньше — обычно пишут middleware.
2.15 NATS multi-cluster
Заголовок раздела «2.15 NATS multi-cluster»Лежащие в разных DC NATS-кластеры можно связать через gateways и leaf nodes. Сообщения проходят между ними по subjects. Используется для гео-распределённых систем и edge.
3. Gotchas
Заголовок раздела «3. Gotchas»3.1 NATS Core теряет сообщения
Заголовок раздела «3.1 NATS Core теряет сообщения»nc.Publish("x", data) // если подписчика нет → потеряCore NATS — at-most-once. Для гарантий — JetStream.
3.2 Slow consumer в NATS
Заголовок раздела «3.2 Slow consumer в NATS»nats.SlowConsumerErrorЕсли ваш handler медленный, NATS буферизует, но при переполнении буфера — сообщения дропаются, consumer помечается «slow». Решения: вынести обработку в горутины с bounded channel.
3.3 nc.Publish + сразу exit
Заголовок раздела «3.3 nc.Publish + сразу exit»nc.Publish("x", data)os.Exit(0) // сообщение в буфере, не отправленоnc.Flush() перед exit или defer nc.Close() (закрытие flush-ит).
3.4 JetStream max msg size
Заголовок раздела «3.4 JetStream max msg size»Default 1MB. Конфигурируется на stream / server. Big payloads → Object Store.
3.5 JetStream consumer ack timeout
Заголовок раздела «3.5 JetStream consumer ack timeout»Default ack_wait = 30 секунд. Если обработка дольше — сообщение redelivered (дубль). Увеличьте AckWait или периодически вызывайте msg.InProgress().
3.6 RabbitMQ channel — не goroutine safe
Заголовок раздела «3.6 RabbitMQ channel — не goroutine safe»Один Channel нельзя использовать из нескольких горутин одновременно. Solution: pool of channels или channel per goroutine.
3.7 RabbitMQ prefetch
Заголовок раздела «3.7 RabbitMQ prefetch»ch.Qos(0, 0, false) // дефолт: unbounded prefetchБез QoS consumer получит все сообщения сразу → OOM. Установите prefetch=10-100.
3.8 RabbitMQ classic queues deprecated
Заголовок раздела «3.8 RabbitMQ classic queues deprecated»ch.QueueDeclare(...) // default: classic queueВ 2026 для prod — x-queue-type: quorum. Classic queues не HA, mirrored deprecated.
3.9 RabbitMQ publisher не получает ack
Заголовок раздела «3.9 RabbitMQ publisher не получает ack»Без ch.Confirm(false) и NotifyPublish — продюсер думает, что отправил, но broker мог потерять. Для важных событий — обязательно publisher confirms.
3.10 RabbitMQ reconnect
Заголовок раздела «3.10 RabbitMQ reconnect»Стандартная библиотека amqp091-go не делает auto-reconnect. Wrapper нужен (например github.com/wagslane/go-rabbitmq или своя обёртка).
3.11 NATS wildcards и pattern matching
Заголовок раздела «3.11 NATS wildcards и pattern matching»orders.*.created — НЕ matches orders.eu.uk.created (только один уровень)orders.> — matches orders.eu.uk.created3.12 NATS subject длина
Заголовок раздела «3.12 NATS subject длина»256 символов — деградация производительности. Держите subjects короткими.
3.13 RabbitMQ slow queue
Заголовок раздела «3.13 RabbitMQ slow queue»Длинная queue (миллионы сообщений) → деградация. Используйте Streams или лимиты.
3.14 NATS connection draining
Заголовок раздела «3.14 NATS connection draining»При shutdown:
nc.Drain() // обработать все буферизованные, потом closeБез drain — pending сообщения теряются.
3.15 RabbitMQ heartbeat
Заголовок раздела «3.15 RabbitMQ heartbeat»Если heartbeat не отвечает (default 60s) — connection закрывается. На медленных сетях — увеличить.
3.16 RabbitMQ Memory High Watermark
Заголовок раздела «3.16 RabbitMQ Memory High Watermark»Когда RAM > 40% (default), publishers блокируются. Симптом: producer зависает. Алертить.
3.17 NATS auto-create
Заголовок раздела «3.17 NATS auto-create»NATS Core не имеет «декларации» subjects — публикуй куда угодно. В JetStream — нужно создать stream.
3.18 RabbitMQ persistent + transient queues
Заголовок раздела «3.18 RabbitMQ persistent + transient queues»Если queue не durable, при рестарте RabbitMQ — пропадает. Если message не persistent, тоже пропадает. Для durability нужно ОБА: durable:true + DeliveryMode: Persistent.
4. Best practices в production
Заголовок раздела «4. Best practices в production»4.1 NATS — выбирайте JetStream если нужна durability
Заголовок раздела «4.1 NATS — выбирайте JetStream если нужна durability»Core NATS — для real-time non-critical (notifications, presence, metrics). JetStream — для critical events.
4.2 NATS — Queue Group для load balancing
Заголовок раздела «4.2 NATS — Queue Group для load balancing»Между N инстансами consumer-а используйте QueueSubscribe. Сообщение получит только один.
4.3 NATS — drain on shutdown
Заголовок раздела «4.3 NATS — drain on shutdown»defer nc.Drain() // не nc.Close()4.4 NATS — TLS и Auth
Заголовок раздела «4.4 NATS — TLS и Auth»В prod: TLS, NKey/JWT auth, accounts (multi-tenancy).
4.5 NATS JetStream — реплицируйте stream
Заголовок раздела «4.5 NATS JetStream — реплицируйте stream»Replicas: 3 для отказоустойчивости. Без этого падение одного брокера = потеря stream.
4.6 NATS JetStream — Pull consumers
Заголовок раздела «4.6 NATS JetStream — Pull consumers»Pull > Push для большинства случаев: контроль скорости consumer-ом, backpressure, нет slow-consumer проблемы.
4.7 NATS JetStream — AckExplicitPolicy
Заголовок раздела «4.7 NATS JetStream — AckExplicitPolicy»Не AckNonePolicy (потеря). Не AckAllPolicy (если crash после последнего ack, дубли). Explicit — ack каждое сообщение.
4.8 RabbitMQ — quorum queues
Заголовок раздела «4.8 RabbitMQ — quorum queues»В 2026 default для prod. Mirrored queues — deprecated.
4.9 RabbitMQ — Publisher confirms
Заголовок раздела «4.9 RabbitMQ — Publisher confirms»Для важных событий — ch.Confirm(false) + NotifyPublish. Иначе можно потерять (broker crash до flush).
4.10 RabbitMQ — manual ack
Заголовок раздела «4.10 RabbitMQ — manual ack»autoAck=false. Ack только после успешной обработки. На ошибке — Nack с requeue=false → DLX.
4.11 RabbitMQ — Prefetch
Заголовок раздела «4.11 RabbitMQ — Prefetch»ch.Qos(10-100, 0, false). Без этого consumer задохнётся.
4.12 RabbitMQ — DLX обязателен
Заголовок раздела «4.12 RabbitMQ — DLX обязателен»Для каждой важной queue настройте x-dead-letter-exchange. Без DLX — отвергнутые сообщения уходят в небытие.
4.13 RabbitMQ — connection pool
Заголовок раздела «4.13 RabbitMQ — connection pool»type Pool struct { conn *amqp091.Connection channels chan *amqp091.Channel}Один connection, много channels. Или несколько connections для distribute.
4.14 RabbitMQ — idempotent consumers
Заголовок раздела «4.14 RabbitMQ — idempotent consumers»message_id deduplication: храните processed IDs (с TTL), skip duplicates.
4.15 Tracing
Заголовок раздела «4.15 Tracing»Headers (traceparent) пробрасывайте вручную или через middleware. RecordHeader в NATS, Headers в RabbitMQ.
4.16 Metrics
Заголовок раздела «4.16 Metrics»NATS: nats-prometheus-exporter, nats_* метрики (slow consumers, msgs received/sent).
RabbitMQ: management plugin + Prometheus exporter (queue depth, message rate, channel count).
Метрики клиента: ack/nack rate, consumer latency.
4.17 Health check
Заголовок раздела «4.17 Health check»NATS: nc.IsConnected() или /healthz endpoint.
RabbitMQ: conn.IsClosed() + ping channel.
4.18 Не делать sync RPC через RabbitMQ для high QPS
Заголовок раздела «4.18 Не делать sync RPC через RabbitMQ для high QPS»RabbitMQ RPC pattern OK для редких запросов. Для high QPS — gRPC или NATS.
4.19 Graceful shutdown
Заголовок раздела «4.19 Graceful shutdown»NATS: Drain().
RabbitMQ: cancel consumer (ch.Cancel), wait inflight, then Close().
4.20 Capacity planning
Заголовок раздела «4.20 Capacity planning»NATS: in-memory, scales с RAM. JetStream — диск + replicas.
RabbitMQ: проверьте disk free alarm, memory high watermark, file descriptors. Один broker — до ~50K connection, 100K queues.
5. Вопросы на собесе
Заголовок раздела «5. Вопросы на собесе»-
Что такое subject в NATS? Иерархическое имя (
orders.created). Wildcards*(один уровень) и>(много). -
Core NATS vs JetStream? Core — at-most-once, fire-forget, без persistence. JetStream — persistent streams + consumers + acks.
-
Что такое queue group? Группа подписчиков, разделяющих сообщения (load balancing). Одно сообщение → один consumer в группе.
-
Чем NATS лучше Kafka для real-time? Низкая latency (< 1ms), single binary, не нужен JVM/Zookeeper. Но Kafka мощнее для high throughput streaming.
-
Что такое NATS Request-Reply? Sync RPC через subject + inbox для ответа.
nc.Request(subject, data, timeout). -
Что такое slow consumer? Consumer не успевает обрабатывать → буфер NATS переполняется → сообщения дропаются. Решение: вынести в горутины, увеличить буфер, переходить на JetStream pull.
-
AckPolicy в JetStream? None (без ack), All (acks все до текущего), Explicit (ack каждое — стандарт для гарантий).
-
Что такое Leaf Node / Gateway? Связь NATS кластеров (multi-cluster, edge-to-cloud).
-
NATS KV — что это? Distributed key-value поверх JetStream stream с compaction. Подходит для конфигов, флагов, координации.
-
Когда нельзя использовать NATS? Для очень больших объёмов retention (TB+, Kafka лучше), для priority/delay сообщений (RabbitMQ).
RabbitMQ
Заголовок раздела «RabbitMQ»-
Что такое exchange? Routing primitive: получает сообщение и распределяет в queues по правилам.
-
Типы exchanges? Direct (точное match key), Fanout (broadcast), Topic (wildcards
*и#), Headers (редко). -
Что такое binding? Правило: exchange + queue + routing key (или pattern). Без binding queue не получает сообщения.
-
Manual vs auto ack? Auto-ack — сразу после получения (риск потери при crash). Manual — после обработки.
-
Чем quorum queues отличаются от classic? Quorum — Raft, HA, replicated. Classic — single node (mirrored deprecated). В 2026 quorum default для prod.
-
Что такое DLX? Dead Letter Exchange. Куда уходят сообщения после nack/expired/overflow. Бывает связан с DLQ.
-
Что такое prefetch? Лимит unacked сообщений на consumer (
Qos(prefetch_count, 0, false)). Без него consumer получит всё сразу. -
Publisher confirms — зачем? Гарантия, что сообщение записано broker-ом. Без confirms producer не знает, дошло ли.
-
Channel vs Connection? Connection — TCP. Channel — мультиплекс внутри connection. Один connection — много channels.
-
Когда выбрать RabbitMQ? Сложная маршрутизация (один event → много queues разными правилами), per-message ack/delay/priority, task queues с retries.
Сравнение
Заголовок раздела «Сравнение»-
NATS vs Kafka? NATS — низкая latency, lightweight, simple ops. Kafka — высокий throughput, persistent log, replay.
-
RabbitMQ vs Kafka? RabbitMQ — гибкая routing, queue per consumer, ack per message. Kafka — log-based, replay, ordered, partitioned.
-
NATS vs RabbitMQ? NATS быстрее, проще, но менее гибкий routing. RabbitMQ — complex routing, scheduling, per-message features.
-
Какой брокер для микросервисной RPC? NATS Core (request-reply) или gRPC. RabbitMQ RPC возможен, но overkill.
-
Какой брокер для real-time notifications? NATS Core (fast pub-sub). Если нужна durability — JetStream.
-
Какой брокер для task queue с retries? RabbitMQ (quorum + DLX + delayed exchange) или NATS JetStream (MaxDeliver + NakWithDelay).
-
Какой брокер для audit log / event sourcing? Kafka (replay, retention годами, partitioned). NATS JetStream — для среднего масштаба.
-
Что такое Pulsar и зачем? Apache Pulsar — гибрид: pub-sub + queue, multi-tenancy, tiered storage. Альтернатива Kafka для multi-region.
-
NATS в K8s? Helm chart, StatefulSet (для JetStream), supercluster для multi-region.
-
RabbitMQ в K8s? RabbitMQ Cluster Operator. StatefulSet, persistent storage, quorum queues.
6. Practice
Заголовок раздела «6. Practice»Упражнение 1: NATS Pub-Sub
Заголовок раздела «Упражнение 1: NATS Pub-Sub»Запустите nats-server локально. Напишите publisher (10 msg/sec) и subscriber (orders.*). Проверьте wildcards.
Упражнение 2: NATS Request-Reply
Заголовок раздела «Упражнение 2: NATS Request-Reply»Реализуйте «math server» — отвечает на math.add, math.mul. Клиент с timeout 1s.
Упражнение 3: NATS Queue Group
Заголовок раздела «Упражнение 3: NATS Queue Group»3 инстанса consumer с одной queue group. Запустите 30 сообщений — увидьте ~10 каждому.
Упражнение 4: JetStream stream + consumer
Заголовок раздела «Упражнение 4: JetStream stream + consumer»Создайте stream EVENTS (subject events.>). Producer пишет, pull consumer читает с manual ack. Симулируйте crash после получения, до ack — сообщение redelivered.
Упражнение 5: NATS JetStream KV
Заголовок раздела «Упражнение 5: NATS JetStream KV»Запишите конфиг в KV bucket config. Сделайте watcher, который реагирует на изменения.
Упражнение 6: RabbitMQ direct exchange
Заголовок раздела «Упражнение 6: RabbitMQ direct exchange»Exchange orders, два queue: orders.eu (binding key orders.eu), orders.us (orders.us). Producer публикует с разными keys, проверьте маршрутизацию.
Упражнение 7: RabbitMQ topic + wildcards
Заголовок раздела «Упражнение 7: RabbitMQ topic + wildcards»Exchange events (topic). Queue audit (binding *.created.*). Producer публикует с разными keys, проверьте кто получает.
Упражнение 8: RabbitMQ quorum + DLX
Заголовок раздела «Упражнение 8: RabbitMQ quorum + DLX»Создайте quorum queue с DLX. Симулируйте обработку с ошибкой — увидьте сообщение в DLQ.
Упражнение 9: RabbitMQ publisher confirms
Заголовок раздела «Упражнение 9: RabbitMQ publisher confirms»Producer с Confirm mode. Симулируйте disconnect (docker stop rabbitmq на 5 сек) — увидите, что confirms не приходят, retry в коде.
Упражнение 10: Tracing across broker
Заголовок раздела «Упражнение 10: Tracing across broker»Producer добавляет traceparent header. Consumer читает header и продолжает trace. В Jaeger увидите связанный trace producer → consumer.
7. Источники
Заголовок раздела «7. Источники»- NATS docs — https://docs.nats.io/.
- nats.go — https://github.com/nats-io/nats.go.
- JetStream guide — https://docs.nats.io/nats-concepts/jetstream.
- RabbitMQ docs — https://www.rabbitmq.com/documentation.html.
- amqp091-go — https://github.com/rabbitmq/amqp091-go.
- AMQP 0.9.1 spec — https://www.rabbitmq.com/resources/specs/amqp0-9-1.pdf.
- “RabbitMQ in Depth” by Gavin M. Roy (Manning, 2017).
- “Mastering RabbitMQ” recent editions / RabbitMQ Summit talks — YouTube.
- NATS by Example — https://natsbyexample.com/.
- CNCF Cloud Native Landscape: Messaging — https://landscape.cncf.io/.