Skip to main content

NATS Integration

Table of Contents

  1. Introduction
  2. Project Structure
  3. Core Components
  4. Architecture Overview
  5. Component Details
  6. Dependency Analysis
  7. Performance Considerations
  8. Troubleshooting Guide
  9. Conclusion
  10. Appendix

Introduction

This document targets microservices architecture developers, systematically explains NATS integration solutions in this project, focuses on:

  • NATS JetStream integration architecture and connection management
  • Event stream configuration and subject naming conventions
  • JetStream publisher and subscriber implementation principles, consumer groups and message acknowledgment mechanisms
  • NATS connection pool and reconnection strategies, timeout handling
  • NATS server configuration points, message serialization formats
  • Performance tuning recommendations, monitoring metrics and troubleshooting methods

This project provides both traditional NATS event bus (non-JetStream) and JetStream-based event stream publish/subscribe implementations, convenient for choosing appropriate solutions in different scenarios.

Project Structure

NATS integration is mainly distributed in the following modules:

  • Configuration Layer: NATS server address, event stream name, maximum retention time, etc.
  • Event Bus Layer: Traditional NATS event bus (non-JetStream)
  • Event Stream Layer: JetStream publisher, subscriber, event reader
  • Application Bootstrap Layer: Create NATS connection during application startup, register publish/subscribe, unified cleanup

Core Components

NATS Configuration Structure

  • Contains server address, event stream name, maximum retention time, etc.

Traditional NATS Event Bus

  • Based on standard NATS publish/subscribe, does not support JetStream's persistence and reliable delivery

JetStream Publisher

  • Responsible for creating/ensuring event stream exists, publishing domain events by subject

JetStream Subscriber

  • Based on persistent consumers, explicit acknowledgment, supports graceful shutdown and timeout control

JetStream Event Reader

  • Ephemeral consumer mode, supports full/by version/by offset replay

Event Stream Hub

  • Centralized subscription handler registration, unified start/close

Interfaces and Constraints

  • Defines unified interfaces such as StreamPublisher/StreamSubscriber/StreamReader

Architecture Overview

Overall architecture is divided into three layers:

  • Configuration Layer: Reads NATS server address, event stream name, maximum retention time, etc.
  • Event Stream Layer: Publisher responsible for creating/ensuring stream exists and publishing events; Subscriber responsible for creating persistent consumers and processing messages; Reader responsible for replay and reading
  • Application Layer: Application establishes connection during startup, registers publish/subscribe, unified graceful shutdown

Component Details

NATS Configuration and Connection Management

  • NATS configuration structure contains server address, event stream name, maximum retention time (days)
  • Global configuration provides default values, supports loading from multiple format configuration files, and automatically reads environment variables
  • Creates NATS connection during application startup, publisher/subscriber/reader are all based on this connection

Traditional NATS Event Bus

  • Performs publish/subscribe through standard NATS connection
  • Serializes events to JSON and publishes to subject during publishing
  • Generates unique subscription ID for each subject during subscribing, supports unsubscribe
  • Cancels all subscriptions and closes connection during close

JetStream Publisher

  • Creates/ensures event stream exists based on service name, subject collection is "aggregateType.>"
  • Serializes domain events to JSON during publishing, embeds BaseEvent and base64 encodes Payload
  • Subject format is "aggregateType.aggregateID.eventType", convenient for precise filtering and routing
  • Supports configuration items such as maximum message age, stream size, message size

JetStream Subscriber

  • Based on persistent consumer (Durable), explicit acknowledgment (AckExplicit)
  • Filter subject is "aggregateType.*.eventType", supports delivery from earliest message and immediate replay
  • Provides graceful shutdown: cancels consumption through context, waits for processing to complete, supports timeout
  • Sends negative acknowledgment (NAK) when message processing exception occurs, triggers retry

JetStream Event Reader

  • Adopts ephemeral consumer (non-persistent) mode, avoids control plane pressure from frequent creation/destruction
  • Supports full replay, replay by version, replay by offset
  • Sorts by event version ascending then applies to aggregate root, ensures determinism of state rebuild

Event Stream Hub

  • Hub aggregates subscription registration, unified start/close
  • AddSub method registers handlers to internal subscriber collection, distributes by "aggregateType + eventType" dimension

Event Publisher

  • Event publisher converts domain events to generic events, subject named "serviceName.aggregateType.eventType"
  • Publishes through traditional event bus, adapts to non-JetStream scenarios

Dependency Analysis

  • Configuration layer provides NATS server address, event stream name, maximum retention time, etc. for application layer
  • Application layer is responsible for creating NATS connection, and injecting connection into publisher/subscriber/reader
  • Publisher/subscriber/reader all depend on JetStream client; subscriber also depends on persistent consumer
  • Event stream Hub aggregates subscription registration, unified lifecycle management

Performance Considerations

Connection and Reconnection

  • Traditional NATS event bus uses infinite reconnection and fixed wait interval, suitable for short connection/lightweight scenarios
  • JetStream publisher/subscriber depend on connection provided by application layer, recommend unified management of connection lifecycle and reconnection strategy at application layer

Stream Configuration

  • Using Limits strategy is suitable as event storage; adjust maximum message age, stream size, message size according to needs
  • Subject adopts "aggregateType.>" pattern, convenient for expansion and isolation

Consumption and Acknowledgment

  • Subscriber uses explicit acknowledgment, ensures reliability; sends negative acknowledgment to trigger retry when exception occurs
  • Ephemeral consumer mode reduces control plane pressure, suitable for one-time replay/reading

Timeout and Graceful Shutdown

  • Subscriber Stop supports timeout control, avoids long-term blocking; reader Fetch sets timeout context

Serialization and Payload

  • Serializes domain events to JSON during publishing, Payload undergoes base64 encoding, convenient for cross-language transmission and storage

Troubleshooting Guide

Connection Failure

  • Check NATS server address and network connectivity
  • View connection error information in application logs

Stream Does Not Exist

  • Publisher will automatically create stream during first publish; if creation fails, check permissions and configuration

Message Cannot Be Delivered/Processed

  • Subscriber will send negative acknowledgment when handler fails, check handler logs and event payload
  • Confirm if subject filtering is correct (aggregateType.*.eventType)

Graceful Shutdown Stuck

  • Stop will wait if processing is not complete; check if handler is blocking or not returning
  • Adjust timeout time or optimize handler logic

Replay Failure

  • Ephemeral consumer creation failure or message acquisition exception, check if stream exists and consumer configuration

Conclusion

This project's NATS integration provides two paths:

  • Traditional NATS Event Bus: Simple and easy to use, suitable for lightweight scenarios
  • JetStream Event Stream: Has persistence, reliable delivery, consumer groups and explicit acknowledgment features, suitable for event sourcing and high reliability scenarios

Through unified configuration, clear interfaces and complete lifecycle management, developers can flexibly choose and extend NATS integration solutions in microservices architecture.

Appendix

NATS Server Configuration Points

  • Server Address: Read from configuration, default local address
  • Event Stream Name: Service name is event stream name, convenient for isolation by service
  • Maximum Retention Time: In days, publisher will convert to nanoseconds

Subject Naming Conventions

  • Publisher Subject: aggregateType.aggregateID.eventType
  • Subscriber Filter: aggregateType.*.eventType
  • Traditional Event Bus: Event type is subject

Message Serialization

  • Publisher serializes domain events to JSON, and base64 encodes original JSON as Payload
  • Subscriber and reader first deserialize to generic BaseEvent, then restore to specific event type through strong type decoding