Nats io

INTRODUCTION

NATS (pronounced "nats") is a lightweight and high-performance messaging system designed for building distributed and scalable applications. It follows a publish-subscribe (pub/sub) and request-reply messaging pattern and is known for its simplicity, speed, and reliability.

NATS.io is a connective technology for distributed systems and is a perfect fit to connect devices, edge, cloud or hybrid deployments. True multi-tenancy makes NATS ideal for SaaS and self-healing and scaling technology allows for topology changes anytime with zero downtime.

What is NATS

Software applications and services need to exchange data. NATS is an infrastructure that allows such data exchange, segmented in the form of messages. We call this a "message-oriented middleware".

Cloud Native Messaging System

Performance, simplicity , security and availability

Multiple communication patterns

30-client language support

With NATS, application developers can:

  • Effortlessly build distributed and scalable client-server applications.

  • Store and distribute data in real time in a general manner. This can flexibly be achieved across various environments, languages, cloud providers and on-premises systems.

NATS Client Applications

Developers use one of the NATS client libraries in their application code to allow them to publish, subscribe, request and reply between instances of the application or between completely separate applications. Those applications are generally referred to as 'client applications' or sometimes just as 'clients' throughout this manual (since from the point of view of the NATS server, they are clients).

NATS Service Infrastructure

The NATS services are provided by one or more NATS server processes that are configured to interconnect with each other and provide a NATS service infrastructure. The NATS service infrastructure can scale from a single NATS server process running on an end device (the nats-server process is less than 20 MB in size!) all the way to a public global super-cluster of many clusters spanning all major cloud providers and all regions of the world such as Synadia's NGS.

Connecting NATS Client applications to the NATS servers

To connect a NATS client application with a NATS service, and then subscribe or publish messages to subjects, it only needs to be configured with:

  1. 1.URL: A 'NATS URL'. This is a string (in a URL format) that specifies the IP address and port where the NATS server(s) can be reached, and what kind of connection to establish (plain TCP, TLS, or Websocket).

  2. 2.Authentication (if needed): Authentication details for the application to identify itself with the NATS server(s). NATS supports multiple authentication schemes (username/password, decentralized JWT, token, TLS certificates and Nkey with challenge).

Simple messaging design

NATS makes it easy for applications to communicate by sending and receiving messages. These messages are addressed and identified by subject strings, and do not depend on network location.

Data is encoded and framed as a message and sent by a publisher. The message is received, decoded, and processed by one or more subscribers.

With this simple design, NATS lets programs share common message-handling code, isolate resources and interdependencies, and scale by easily handling an increase in message volume, whether those are service requests or stream data.

How to use .

Nats io have different way of installation of server according to your need

But in this post we use nats cli.

Nats CLI

A command line utility to interact with and manage NATS.

This utility replaces various past tools that were named in the form nats-sub and nats-pub, adds several new capabilities and support full JetStream management.

Features

  • Simplicity

  • Wild card subscribers

  • Fanout

  • Load Balanced

  • Request /Reply

  • Publish / Subscribe

  • Selfish optimzation -protect against slow consumers

  • Self healing server-client connections - tone

  • publisher rate limiting

  • Streams

  • JetStream management

  • JetStream data and configuration backup

  • Message publish and subscribe

  • Service requests and creation

  • Benchmarking and Latency testing

  • Super Cluster observation

  • Configuration context maintenance

  • NATS eco system schema registry

Installation

For Mac os brew can be used

brew tap nats-io/nats-tools
brew install nats-io/nats-tools/nats

For windows or other operating system

Just download nats-0.0.34-windows-amd64.zip from natscli release page and extract nats.exe wherever you want.

Lets Start with quick start nats server

Lets publish a message with topic name

  • pub: This is a subcommand or argument to the nats command, indicating that you want to publish (send) a message.

  • hello.world: This is the subject or topic to which you want to publish the message. In NATS, subjects are used to categorize and route messages to subscribers. In this case, you are publishing the message to the "hello.world" subject.

  • "hello": This is the message payload or content that you want to publish. It's the actual data you are sending to the "hello.world" subject.

  • sub: This is a subcommand or argument to the nats command, indicating that you want to subscribe to (receive) messages from a specific subject.

  • here is the more details of subject based messaging SBM

Wildcards

NATS provides two wildcards that can take the place of one or more elements in a dot-separated subject. Subscribers can use these wildcards to listen to multiple subjects with a single subscription but Publishers will always use a fully specified subject, without the wildcard.

Matching A Single Token

The first wildcard is * which will match a single token. For example, if an application wanted to listen for eastern time zones, they could subscribe to time.*.east, which would match time.us.east and time.eu.east.

Matching Multiple Tokens

The second wildcard is > which will match one or more tokens, and can only appear at the end of the subject. For example, time.us.> will match time.us.east and time.us.east.atlanta, while time.us.* would only match time.us.east since it can't match more than one token.

It will also act like a load balancer.

JetStream

NATS has a built-in distributed persistence system called JetStream which enables new functionalities and higher qualities of service on top of the base 'Core NATS' functionalities and qualities of service.

JetStream is built-in to nats-server and you only need 1 (or 3 or 5 if you want fault-tolerance against 1 or 2 simultaneous NATS server failures) of your NATS server(s) to be JetStream enabled for it to be available to all the client applications.

JetStream was created to solve the problems identified with streaming in technology today - complexity, fragility, and a lack of scalability. Some technologies address these better than others, but no current streaming technology is truly multi-tenant, horizontally scalable, and supports multiple deployment models. No other technology that we are aware of can scale from edge to cloud under the same security context while having complete deployment observability for operations.

Goals

JetStream was developed with the following goals in mind:

  • The system must be easy to configure and operate and be observable.

  • The system must be secure and operate well with NATS 2.0 security models.

  • The system must scale horizontally and be applicable to a high ingestion rate.

  • The system must support multiple use cases.

  • The system must self-heal and always be available.

  • The system must allow NATS messages to be part of a stream as desired.

  • The system must display payload agnostic behavior.

  • The system must not have third party dependencies.

Functionalities enabled by JetStream

Streaming: temporal decoupling between the publishers and subscribers

One of the tenets of basic publish/subscribe messaging is that there is a required temporal coupling between the publishers and the subscribers: subscribers only receive the messages that are published when they are actively connected to the messaging system (i.e. they do not receive messages that are published while they are not subscribing or not running or disconnected). The traditional way for messaging systems to provide temporal decoupling of the publishers and subscribers is through the 'durable subscriber' functionality or sometimes through 'queues', but neither one is perfect:

  • durable subscribers need to be created before the messages get published

  • queues are meant for workload distribution and consumption, not to be used as a mechanism for message replay.

Limits

You can impose the following limits on a stream

  • Maximum message age.

  • Maximum total stream size (in bytes).

  • Maximum number of messages in the stream.

  • Maximum individual message size.

  • You can also set limits on the number of consumers that can be defined for the stream at any given point in time

Read More for Jetstream here

Streams

Streams are 'message stores', each stream defines how messages are stored and what the limits (duration, size, interest) of the retention are. Streams consume normal NATS subjects, any message published on those subjects will be captured in the defined storage system. You can do a normal publish to the subject for unacknowledged delivery, though it's better to use the JetStream publish calls instead as the JetStream server will reply with an acknowledgement that it was successfully stored.

Lets Create Stream

  • You can check with command nats stream ls to show how many message is generated and status of stream

  • Messsage is stored.

More commands and functionalities can be used here is the link

Now lets discuss which is best in term of Distriubted Messaging System

NATS was originally built with Ruby and achieved a respectable 150k messages per second. The team rewrote it in Go, and now you can do an absurd 8–11 million messages per second. It works as a publish-subscribe engine, but you can also get synthetic queuing.

Pros:
Slogan: always on and available, dial tone
Concise design
Low CPU-consuming
Fast: Ahigh-velocity communication bus
High availability
High scalability
Light-weight: It’s tiny, just a 3MB Docker image!
Once deployment

Cons:
Fire and forget, no persistence: NATS doesn’t do persistent messaging; if you’re offline, you don’t get the message.
No transaction
No enhanced delivery modes
No enterprise queueing

Key Features:

  • Lightweight and high-performance pub/sub messaging system

  • Simplicity and ease of use with a small footprint and minimal configuration

  • At-least-once message delivery with NATS Streaming

  • Support for request-reply and point-to-point messaging patterns

  • Clustering and fault tolerance capabilities

Use Cases:

  • Real-time event streaming and notifications

  • Microservices and serverless communication

  • Cloud-native applications and container orchestration

  • IoT and edge computing

Performance Metrics:

  • Supports hundreds of thousands to millions of messages per second, depending on hardware and configuration

  • Average end-to-end latency in the microseconds to milliseconds range

In general, NATS and Redis are better suited to smaller messages (well below 1MB), in which latency tends to be sub-millisecond up to four nines.
NATS is not HTTP, it’s its own very simple text-based protocol, RPC-like. So it does not add any header to the message envelope.

RabbitMQ:

RabbitMQ is a messaging engine that follows the AMQP 0.9.1 definition of a broker. It follows a standard store-and-forward pattern where you have the option to store the data in RAM, on disk, or both. It supports a variety of message routing paradigms. RabbitMQ can be deployed in a clustered fashion for performance, and mirrored fashion for high availability. Consumers listen directly on queues, but publishers only know about “exchanges.” These exchanges are linked to queues via bindings, which specify the routing paradigm (among other things). RabbitMQ does persist messages to disk. https://www.rabbitmq.com/persistence-conf.html
Unlike
NATS, it’s a more traditional message queue in the sense that it supports binding queues and transactional-delivery semantics.
Consequently, RabbitMQ is a more “heavyweight” queuing solution and tends to pay an additional premium with.

Key Features:

  • Flexible and extensible message broker supporting multiple messaging protocols, including AMQP, STOMP, and MQTT

  • Supports various messaging patterns, such as pub/sub, request-reply, and point-to-point

  • Highly configurable and pluggable, with a rich plugin ecosystem

  • Advanced message routing capabilities with exchanges and queues

  • Clustering and high availability options

Use Cases:

  • Application integration and communication

  • Task distribution and workload balancing

  • Microservices communication and coordination

  • IoT and real-time applications

Performance Metrics:

  • Supports thousands to tens of thousands of messages per second, depending on hardware and configuration

  • Average end-to-end latency in the sub-millisecond to milliseconds range

Cons:
RabbitMQ’s high availability support is terrible. It’s a single point of failure no matter how you turn it because it cannot merge conflicting queues that result from a split-brain situation. Partitions can happen not just on network outage, but also in high-load situations.

Kafka

With Kafka, you can do both real-time and batch processing. Kafka runs on JVM (Scala to be specific). Ingest tons of data, route via publish-subscribe (or queuing). The broker barely knows anything about the consumer. All that’s really stored is an “offset” value that specifies where in the log the consumer left off.
Unlike many integration brokers that assume consumers are mostly online, Kafka can successfully persist a lot of data and supports “replay” scenarios.
The architecture is fairly unique; Topics are arranged in partitions (for parallelism), and partitions are replicated across nodes (for high availability).

Kafka is used by Unicorn startups, IOT, health, and large financial organizations ( LinkedIn, FB, Netflix, GE, Bank OF America, Fannie Mae, Chase Bank .. and so on…)
NATS is a very small infrastructure compared to Kafka. Kafka is more matured compared to Nats and performs very well with huge data streams.
NATS Server has a subset of the features in Kafka as it is focused on a narrower set of use cases.
NATS has been designed for scenarios where high performance and low latency are critical but losing some data is fine if needed in order to keep up with data-what the NATS documentation describes as “fire and forget”. Architecturally, that’s because NATS doesn’t have a persistence layer to use to store data durably.
While Kafka does have a persistence layer (using storage on the cluster).
To fully guarantee that a message won’t be lost, it looks like you need to declare the queue as durable + to mark your message as persistent + use publisher confirms. And this costs several hundreds of milliseconds of latency.

The only queue or pub/sub system that is relatively safe from partition errors is Kafka. Kafka is just a really solid piece of engineering when you need 5–50 servers. With that many servers, you can handle millions of messages per second that usually enough for a mid-size company.

Kafka is completely unsuitable for RPC, for several reasons. First, its data model shards queues into partitions, each of which can be consumed by just a single consumer. Assume we have partitions 1 and 2. P1 is empty, P2 has a ton of messages. You will now have one consumer C1 which is idle, while C2 is doing work. C1 can’t take any of C2’s work because it can only process its own partition. In other words: A single slow consumer can block a significant portion of the queue. Kafka is designed for fast (or at least evenly performant) consumers.

Key Features:

  • Distributed and highly-scalable pub/sub messaging system

  • Fault-tolerant and durable, with built-in replication and partitioning

  • High throughput and low-latency message processing

  • Stream processing capabilities with Kafka Streams

  • Strong durability guarantees with write-ahead logs

Use Cases:

  • Log aggregation and processing

  • Real-time data analytics and monitoring

  • Event sourcing and CQRS

  • Stream processing and data integration

Performance Metrics:

  • Supports millions of events per second, depending on hardware and configuration

  • Average end-to-end latency in the milliseconds range

NATS vs. Kafka

NATS recently joined CNCF (which hosts projects like Kubernetes, Prometheus etc. — look at the dominance of Golang here!)
Protocol — Kafka is binary over TCP as opposed to NATS being simple text (also over TCP)
Messaging patterns — Both support pub-sub and queues, but NATS supports request-reply as well (sync and async)
NATS has a concept of a queue (with a unique name of course) and all the subscribers hooked on the same queue end up being a part of the same queue group.
Only one of the (potentially multiple) subscribers gets the message. Multiple such queue groups would also receive the same set of messages. This makes it a hybrid pub-sub (one-to-many) and queue (point-to-point). The same thing is supported in Kafka via consumer groups which can pull data from one or more topics.
Stream processing — NATS does not support stream processing as a first-class feature like Kafka does with Kafka Streams
Kafka clients use a poll-based technique in order to extract messages as opposed to NATS where the server itself routes messages to clients (maintains an interest graph internally).
NATS can act pretty sensitive in the sense that it has the ability to cut off consumers who are not keeping pace with the rate of production as well as clients who don’t respond to heartbeat requests.
The consumer liveness check is executed by Kafka as well. This is done/initiated by the client itself & there are complex situations that can arise due to this (e.g. when you’re in a message processing loop and don’t poll ).
There are a bunch of configuration parameters/knobs to tune this behavior (on the client side)
Delivery semantic — NATS supports at most once (and at least once with NATS streaming) as opposed to Kafka which also supports exactly once (tough!)
NATS doesn’t seem to have a notion of partitioning/sharding messages like Kafka does
No external dependency in the case of NATS. Kafka requires Zookeeper
NATS Streaming seems to be similar to the Kafka feature set, but built using Go and looks to be easier to set up.
NATS does not support replication (or really any high availability settings) currently. Which is a major missing feature when comparing it to Kafka.

Kafka — Pros

Mature: very rich and useful JavaDoc
Kafka Streams
Mature & broad community
Simpler to operate in production — less components — broker node provides also storage
Transactions — atomic reads&writes within the topics
Offsets form a continuous sequence — consumer can easily seek to last message

Kafka — Cons

Consumer cannot acknowledge message from a different thread
No multitenancy
No robust Multi-DC replication — (offered in Confluent Enterprise)
Management in a cloud environment is difficult.

Apache Pulsar

It was designed at Yahoo as a high-performance, low latency, scalable, durable solution for both pub-sub messaging and message queuing.
Apache Pulsar combines high-performance streaming (which Apache Kafka pursues) and flexible traditional queuing (which RabbitMQ pursues) into a unified messaging model and API. Pulsar gives you one system for both streaming and queuing, with the same high performance, using a unified API. To sum up, Kafka aims for high throughput, Pulsar for low latency.

Pulsar — Pros

Feature rich — persistent/nonpersistent topics, multitenancy, ACLs, Multi-DC replication etc.
More flexible client API that is easier to use — including CompletableFutures, fluent interfaces etc.
Java client components are thread-safe — a consumer can acknowledge messages from different threads. Java client has Javadoc (https://pulsar.apache.org/api/client/)

Community — 8 stackoverflow questions currently and https://pulsar.apache.org/powered-by/

Pulsar — Cons

MessageId concept tied to BookKeeper — consumers cannot easily position itself on the topic compared to Kafka offset which is a continuous sequence of numbers.
A reader cannot easily read the last message on the topic — need to skim through all the messages to the end. Note on 20190106: It can position a reader on the latest message.
No transactions (20190106: Transaction support is planned for 2.6 release)
Higher operational complexity — Zookeeper + Broker nodes + BookKeeper — all clustered
Latency questionable — there is one extra remote call between Broker node and BookKeeper (compared to Kafka), so we can run broker and bookkeeper in the same node if required.

Conclusion

Selecting the right message broker for your event-driven architecture depends on your specific requirements, such as performance, scalability, durability, and messaging patterns. Apache Kafka is a great choice for large-scale, distributed systems that require high throughput and strong durability guarantees. RabbitMQ offers flexibility and advanced routing capabilities, making it suitable for a wide range of applications, including microservices and IoT. Finally, NATS is ideal for scenarios where simplicity, performance, and lightweight design are paramount, such as real-time applications and edge computing.

More compare Information are available here https://docs.nats.io/nats-concepts/overview/compare-nats