1
0
mirror of https://github.com/taigrr/nats.docs synced 2025-01-18 04:03:23 -08:00
Signed-off-by: Derek Collison <derek@nats.io>
This commit is contained in:
Derek Collison 2019-06-06 15:42:25 -07:00
parent d7c6b1ebcf
commit 99da6d13d0
20 changed files with 180 additions and 271 deletions

View File

@ -3,14 +3,10 @@
</a>
# The Importance of Messaging
Developing and deploying applications that communicate in distributed systems
can be complex and difficult. A communication infrastructure should provide
features to make this easier, including multiple messaging patterns bundled
into one technology, location transparency, the decoupling of data producers
and consumers, and asynchronous communications to build event driven
applications. This can drive services/micro-services based workloads and take
the place of things like a service mesh, and also drive observability, all
from the same technology.
Developing and deploying applications and services that communicate in distributed systems
can be complex and difficult. However there are two basic patterns, request/reply or RPC for services,
and event and data streams. A modern technology should provide
features to make this easier, scalable, secure, location independent and observable.
## Distributed Computing Needs of Today
@ -20,10 +16,10 @@ multi-tenancy for a truly shared infrastructure. A modern system needs to includ
* Secure by default communications for microservices, edge platforms and devices
* Secure multi-tenancy in a single distributed communication technology
* Decoupled from IP for addressing and security
* Resiliency with an emphasis on the health of the system as a whole
* Transparent location addressing and discovery
* Resiliency with an emphasis on the overall health of the system
* Ease of use for agile development, CI/CD, and operations, at scale
* Highly scalable with built-in load balancing and no config auto-scaling
* Highly scalable and performant with built-in load balancing and dynamic auto-scaling
* Consistent identity and security mechanisms from edge devices to backend services
## NATS
@ -37,8 +33,8 @@ about a distributed communication system.
* High-Performance
* Always on and available
* Extremely lightweight
* At Most Once (NATS) or At Least Once Delivery (NATS Streaming)
* Common Messaging Pattern Support (Scalable Services, Event/Data Streams)
* At Most Once and At Least Once Delivery
* Support for Observable and Scalable Services and Event/Data Streams
* Client support for over 30 different programming languages
* Cloud Native, a CNCF project with Kubernetes and Prometheus integrations

View File

@ -1,38 +1,38 @@
<div class="tab-wrap">
<input type="radio" id="publish_bytes_go" name="publish_bytes" class="tab" checked>
<label for="publish_bytes_go" class="api-lang" data-language="go">Go</label>
<input type="radio" id="publish_bytes_java" name="publish_bytes" class="tab">
<label for="publish_bytes_java" class="api-lang" data-language="java">Java</label>
<input type="radio" id="publish_bytes_js" name="publish_bytes" class="tab">
<label for="publish_bytes_js" class="api-lang" data-language="js">JavaScript</label>
<input type="radio" id="publish_bytes_py" name="publish_bytes" class="tab">
<label for="publish_bytes_py" class="api-lang" data-language="py">Python</label>
<input type="radio" id="publish_bytes_ruby" name="publish_bytes" class="tab">
<label for="publish_bytes_ruby" class="api-lang" data-language="ruby">Ruby</label>
<input type="radio" id="publish_bytes_ts" name="publish_bytes" class="tab">
<label for="publish_bytes_ts" class="api-lang" data-language="ts">TypeScript</label>
<input type="radio" id="publish_bytes_go" name="publish_bytes" class="tab" checked>
<label for="publish_bytes_go" class="api-lang" data-language="go">Go</label>
<input type="radio" id="publish_bytes_java" name="publish_bytes" class="tab">
<label for="publish_bytes_java" class="api-lang" data-language="java">Java</label>
<input type="radio" id="publish_bytes_js" name="publish_bytes" class="tab">
<label for="publish_bytes_js" class="api-lang" data-language="js">JavaScript</label>
<input type="radio" id="publish_bytes_py" name="publish_bytes" class="tab">
<label for="publish_bytes_py" class="api-lang" data-language="py">Python</label>
<input type="radio" id="publish_bytes_ruby" name="publish_bytes" class="tab">
<label for="publish_bytes_ruby" class="api-lang" data-language="ruby">Ruby</label>
<input type="radio" id="publish_bytes_ts" name="publish_bytes" class="tab">
<label for="publish_bytes_ts" class="api-lang" data-language="ts">TypeScript</label>
<div class="tab__content">
<pre id="publish_bytes_go_content"><a class="toolbar-icons pull-right" target="_blank" href="https://github.com/nats-io/go-nats-examples/blob/master/api-examples/publish_bytes/main.go#L10-22"><i class="mdi mdi-github-circle" title="View on GitHub"></i></a><a class="toolbar-icons pull-right"><i class="mdi mdi-content-copy js-copy" title="Copy to Clipboard"></i></a><span class="copy-msg pull-right"></span><code class="language-go">nc, err := nats.Connect(&#34;demo.nats.io&#34;)
if err != nil {
@ -43,11 +43,9 @@ defer nc.Close()
if err := nc.Publish(&#34;updates&#34;, []byte(&#34;All is Well&#34;)); err != nil {
log.Fatal(err)
}
// Make sure the message goes through before we close
nc.Flush()
</code></pre>
</div>
<div class="tab__content">
<pre id="publish_bytes_java_content"><a class="toolbar-icons pull-right" target="_blank" href="https://github.com/nats-io/java-nats-examples/blob/master/src/main/java/io/nats/examples/PublishBytes.java#L13-21"><i class="mdi mdi-github-circle" title="View on GitHub"></i></a><a class="toolbar-icons pull-right"><i class="mdi mdi-content-copy js-copy" title="Copy to Clipboard"></i></a><span class="copy-msg pull-right"></span><code class="language-java">Connection nc = Nats.connect(&#34;nats://demo.nats.io:4222&#34;);
@ -58,13 +56,13 @@ nc.flush(Duration.ZERO);
nc.close();
</code></pre>
</div>
<div class="tab__content">
<pre id="publish_bytes_js_content"><a class="toolbar-icons pull-right" target="_blank" href="https://github.com/nats-io/node-nats-examples/blob/master/src/publisher_samples.js#L8-11"><i class="mdi mdi-github-circle" title="View on GitHub"></i></a><a class="toolbar-icons pull-right"><i class="mdi mdi-content-copy js-copy" title="Copy to Clipboard"></i></a><span class="copy-msg pull-right"></span><code class="language-javascript">let nc = NATS.connect({url: &#34;nats://demo.nats.io:4222&#34;});
nc.publish(&#39;updates&#39;, &#34;All is Well&#34;);
</code></pre>
</div>
<div class="tab__content">
<pre id="publish_bytes_py_content"><a class="toolbar-icons pull-right" target="_blank" href="https://github.com/nats-io/asyncio-nats-examples/blob/master/publish_bytes.py#L6-13"><i class="mdi mdi-github-circle" title="View on GitHub"></i></a><a class="toolbar-icons pull-right"><i class="mdi mdi-content-copy js-copy" title="Copy to Clipboard"></i></a><span class="copy-msg pull-right"></span><code class="language-python">nc = NATS()
@ -74,7 +72,7 @@ await nc.publish(&#34;updates&#34;, b&#39;All is Well&#39;)
</code></pre>
</div>
<div class="tab__content">
<pre id="publish_bytes_ruby_content"><a class="toolbar-icons pull-right" target="_blank" href="https://github.com/nats-io/ruby-nats-examples/blob/master/publish_bytes.rb#L1-7"><i class="mdi mdi-github-circle" title="View on GitHub"></i></a><a class="toolbar-icons pull-right"><i class="mdi mdi-content-copy js-copy" title="Copy to Clipboard"></i></a><span class="copy-msg pull-right"></span><code class="language-ruby">require &#39;nats/client&#39;
@ -83,7 +81,7 @@ NATS.start(servers:[&#34;nats://127.0.0.1:4222&#34;]) do |nc|
end
</code></pre>
</div>
<div class="tab__content">
<pre id="publish_bytes_ts_content"><a class="toolbar-icons pull-right" target="_blank" href="https://github.com/nats-io/ts-nats-examples/blob/master/src/publisher_samples.ts#L6-12"><i class="mdi mdi-github-circle" title="View on GitHub"></i></a><a class="toolbar-icons pull-right"><i class="mdi mdi-content-copy js-copy" title="Copy to Clipboard"></i></a><span class="copy-msg pull-right"></span><code class="language-javascript">let nc = await connect({
url: &#34;nats://demo.nats.io:4222&#34;,
@ -92,5 +90,5 @@ end
nc.publish(&#39;updates&#39;, &#39;All is Well&#39;);
</code></pre>
</div>
</div>

View File

@ -1,38 +1,38 @@
<div class="tab-wrap">
<input type="radio" id="subscribe_w_reply_go" name="subscribe_w_reply" class="tab" checked>
<label for="subscribe_w_reply_go" class="api-lang" data-language="go">Go</label>
<input type="radio" id="subscribe_w_reply_java" name="subscribe_w_reply" class="tab">
<label for="subscribe_w_reply_java" class="api-lang" data-language="java">Java</label>
<input type="radio" id="subscribe_w_reply_js" name="subscribe_w_reply" class="tab">
<label for="subscribe_w_reply_js" class="api-lang" data-language="js">JavaScript</label>
<input type="radio" id="subscribe_w_reply_py" name="subscribe_w_reply" class="tab">
<label for="subscribe_w_reply_py" class="api-lang" data-language="py">Python</label>
<input type="radio" id="subscribe_w_reply_ruby" name="subscribe_w_reply" class="tab">
<label for="subscribe_w_reply_ruby" class="api-lang" data-language="ruby">Ruby</label>
<input type="radio" id="subscribe_w_reply_ts" name="subscribe_w_reply" class="tab">
<label for="subscribe_w_reply_ts" class="api-lang" data-language="ts">TypeScript</label>
<input type="radio" id="subscribe_w_reply_go" name="subscribe_w_reply" class="tab" checked>
<label for="subscribe_w_reply_go" class="api-lang" data-language="go">Go</label>
<input type="radio" id="subscribe_w_reply_java" name="subscribe_w_reply" class="tab">
<label for="subscribe_w_reply_java" class="api-lang" data-language="java">Java</label>
<input type="radio" id="subscribe_w_reply_js" name="subscribe_w_reply" class="tab">
<label for="subscribe_w_reply_js" class="api-lang" data-language="js">JavaScript</label>
<input type="radio" id="subscribe_w_reply_py" name="subscribe_w_reply" class="tab">
<label for="subscribe_w_reply_py" class="api-lang" data-language="py">Python</label>
<input type="radio" id="subscribe_w_reply_ruby" name="subscribe_w_reply" class="tab">
<label for="subscribe_w_reply_ruby" class="api-lang" data-language="ruby">Ruby</label>
<input type="radio" id="subscribe_w_reply_ts" name="subscribe_w_reply" class="tab">
<label for="subscribe_w_reply_ts" class="api-lang" data-language="ts">TypeScript</label>
<div class="tab__content">
<pre id="subscribe_w_reply_go_content"><a class="toolbar-icons pull-right" target="_blank" href="https://github.com/nats-io/go-nats-examples/blob/master/api-examples/subscribe_w_reply/main.go#L11-39"><i class="mdi mdi-github-circle" title="View on GitHub"></i></a><a class="toolbar-icons pull-right"><i class="mdi mdi-content-copy js-copy" title="Copy to Clipboard"></i></a><span class="copy-msg pull-right"></span><code class="language-go">nc, err := nats.Connect(&#34;demo.nats.io&#34;)
if err != nil {
@ -58,12 +58,10 @@ timeAsBytes := []byte(time.Now().String())
// Send the time
nc.Publish(msg.Reply, timeAsBytes)
// Flush and close the connection
nc.Flush()
nc.Close()
// We will close the connection from the above defer
</code></pre>
</div>
<div class="tab__content">
<pre id="subscribe_w_reply_java_content"><a class="toolbar-icons pull-right" target="_blank" href="https://github.com/nats-io/java-nats-examples/blob/master/src/main/java/io/nats/examples/SubscribeWithReply.java#L17-37"><i class="mdi mdi-github-circle" title="View on GitHub"></i></a><a class="toolbar-icons pull-right"><i class="mdi mdi-content-copy js-copy" title="Copy to Clipboard"></i></a><span class="copy-msg pull-right"></span><code class="language-java">Connection nc = Nats.connect(&#34;nats://demo.nats.io:4222&#34;);
@ -86,7 +84,7 @@ nc.flush(Duration.ZERO);
nc.close();
</code></pre>
</div>
<div class="tab__content">
<pre id="subscribe_w_reply_js_content"><a class="toolbar-icons pull-right" target="_blank" href="https://github.com/nats-io/node-nats-examples/blob/master/src/subscriber_samples.js#L28-35"><i class="mdi mdi-github-circle" title="View on GitHub"></i></a><a class="toolbar-icons pull-right"><i class="mdi mdi-content-copy js-copy" title="Copy to Clipboard"></i></a><span class="copy-msg pull-right"></span><code class="language-javascript">// set up a subscription to process a request
nc.subscribe(&#39;time&#39;, (msg, reply) =&gt; {
@ -96,7 +94,7 @@ nc.subscribe(&#39;time&#39;, (msg, reply) =&gt; {
});
</code></pre>
</div>
<div class="tab__content">
<pre id="subscribe_w_reply_py_content"><a class="toolbar-icons pull-right" target="_blank" href="https://github.com/nats-io/asyncio-nats-examples/blob/master/subscribe_w_reply.py#L8-31"><i class="mdi mdi-github-circle" title="View on GitHub"></i></a><a class="toolbar-icons pull-right"><i class="mdi mdi-content-copy js-copy" title="Copy to Clipboard"></i></a><span class="copy-msg pull-right"></span><code class="language-python">nc = NATS()
@ -122,7 +120,7 @@ await nc.publish(msg.reply, time_as_bytes)
</code></pre>
</div>
<div class="tab__content">
<pre id="subscribe_w_reply_ruby_content"><a class="toolbar-icons pull-right" target="_blank" href="https://github.com/nats-io/ruby-nats-examples/blob/master/subscribe_w_reply.rb#L1-22"><i class="mdi mdi-github-circle" title="View on GitHub"></i></a><a class="toolbar-icons pull-right"><i class="mdi mdi-content-copy js-copy" title="Copy to Clipboard"></i></a><span class="copy-msg pull-right"></span><code class="language-ruby">require &#39;nats/client&#39;
require &#39;fiber&#39;
@ -146,7 +144,7 @@ end
</code></pre>
</div>
<div class="tab__content">
<pre id="subscribe_w_reply_ts_content"><a class="toolbar-icons pull-right" target="_blank" href="https://github.com/nats-io/ts-nats-examples/blob/master/src/subscriber_samples.ts#L29-38"><i class="mdi mdi-github-circle" title="View on GitHub"></i></a><a class="toolbar-icons pull-right"><i class="mdi mdi-content-copy js-copy" title="Copy to Clipboard"></i></a><span class="copy-msg pull-right"></span><code class="language-javascript">// set up a subscription to process a request
await nc.subscribe(&#39;time&#39;, (err, msg) =&gt; {
@ -158,5 +156,5 @@ await nc.subscribe(&#39;time&#39;, (err, msg) =&gt; {
});
</code></pre>
</div>
</div>

View File

@ -1,6 +1,6 @@
# Acknowledgements
In a system with at-most-once semantics, there are times when messages are lost. If your application is doing request-reply then it can simply use timeouts to handle network and application failures. When you are using one-way messaging the easiest way to insure message delivery is to turn it into a request-reply with the concept of an acknowledgement message, or ACKS. In NATS an ACK can simply be an empty message, a message with no body.
In a system with at-most-once semantics, there are times when messages can be lost. If your application is doing request-reply it should use timeouts to handle any network or application failures. It is always a good idea to place a timeout on a requests and have code that deals with timeouts. When you are publishing an event or data stream, one way to insure message delivery is to turn it into a request-reply with the concept of an acknowledgement message, or ACKs. In NATS an ACK can simply be an empty message, a message with no payload.
<div class="graphviz"><code data-viz="dot">
digraph nats_request_reply {
@ -28,4 +28,4 @@ digraph nats_request_reply {
}
</code></div>
Because the ACK can be empty it can take up very little network bandwidth, but the idea of the ACK turns a simple fire-and-forget into a fire-and-know world where the sender can be sure that the message was received by the other side, or with [scatter-gather](reqreply.md), several other sides.
Because the ACK can be empty it can take up very little network bandwidth, but the idea of the ACK turns a simple fire-and-forget into a fire-and-know world where the sender can be sure that the message was received by the other side, or with a [scatter-gather pattern](reqreply.md), several other sides.

View File

@ -1,8 +1,8 @@
# What is NATS
NATS messaging involves the electronic exchange of data among computer applications and provides a layer between the application and the underlying physical network. Application data is encoded as a message and sent by a publisher. The message is received, decoded, and processed by one or more subscribers.
NATS messaging enables the exchange of data that is segmented into messages among computer applications and services. These messages are addressed by subjects and do not depend on network location. This provides an abstraction layer between the application or service and the underlying physical network. 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.
By providing a scalable service via a single URL, NATS makes it easy for programs to communicate across different environments, languages, and systems. All clients have to do is connect to the broker, subscribe or publish to a subject and process messages. 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.
NATS makes it easy for programs to communicate across different environments, languages, cloud providers and on-premise systems. Clients connect to the NATS system, usually via a single URL, and then subscribe or publish messages to subjects. 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.
<div class="graphviz"><code data-viz="dot">
graph nats {
@ -10,13 +10,13 @@ graph nats {
publisher [shape="record", label="{Application 1 | <nats> NATS Publisher}"];
application [shape="record", label="{Application 3 | <nats> }"];
gnatsd [shape="box", label="", width=4, height=0, penwidth=1];
nats-server [shape="box", label="", width=4, height=0, penwidth=1];
subscriber [shape="record", label="{<nats> NATS Subscriber | Application 2}"];
publisher:nats -- gnatsd [penwidth=2];
application:nats -- gnatsd;
gnatsd -- subscriber:nats [penwidth=2, dir="forward"];
publisher:nats -- nats-server [penwidth=2];
application:nats -- nats-server;
nats-server -- subscriber:nats [penwidth=2, dir="forward"];
}
</code></div>
NATS core offers an **at most once** quality of service. If a subscriber is not listening on the subject (no subject match), or is not active when the message is sent, the message is not received. This is the same level of guarantee that TCP/IP provides. By default, NATS is a fire-and-forget messaging system. If you need higher levels of service, you can either use [NATS Streaming](/nats_streaming/intro.md), or build the additional reliability into your client(s) yourself.
NATS core offers an **at most once** quality of service. If a subscriber is not listening on the subject (no subject match), or is not active when the message is sent, the message is not received. This is the same level of guarantee that TCP/IP provides. By default, NATS is a fire-and-forget messaging system. If you need higher levels of service, you can use [NATS Streaming](/nats_streaming/intro.md) or build additional reliability into your client applications with proven and scalable reference designs.

View File

@ -1,12 +1,13 @@
# Queue Subscribers & Sharing Work
# Queue Subscribers & Scalability
NATS provides a load balancing feature called queue subscriptions. Using queue subscribers will load balance message delivery across a group of subscribers which can be used to provide application fault tolerance and scale workload processing.
NATS provides a builtin load balancing feature called distributed queues. Using queue subscribers will balance message delivery across a group of subscribers which can be used to provide application fault tolerance and scale workload processing.
To create a queue subscription, subscribers register a queue name. All subscribers with the same queue name form the queue group. As messages on the registered subject are published, one member of the group is chosen randomly to receive the message. Although queue groups have multiple subscribers, each message is consumed by only one.
To create a queue subscription, subscribers register a queue name. All subscribers with the same queue name form the queue group. This requires no configuration. As messages on the registered subject are published, one member of the group is chosen randomly to receive the message. Although queue groups have multiple subscribers, each message is consumed by only one.
One of the great features of NATS is that queue groups are defined by the subscribers, not on the server. Applications can create new queue groups without any server change.
One of the great features of NATS is that queue groups are defined by the application and their queue subscribers, not on the server configuration.
Queue subscribers are ideal for auto scaling as you can add or remove them anytime, without any configuration changes or restarting the server or clients.
Queue subscribers are ideal for scaling services. Scale up is as simple as running another application, scale down is terminating the application with a signal that drains the in flight requests.
This flexibility and lack of any configuration changes makes NATS an excellent service communication technology that can work with all platform technologies.
<div class="graphviz"><code data-viz="dot">
digraph nats_queues {

View File

@ -1,10 +1,15 @@
# Request-Reply and Scatter-Gather
# Request-Reply
NATS supports two flavors of request reply messaging: point-to-point or one-to-many. Point-to-point involves the fastest or first to respond. In a one-to-many exchange, you can set a limit on the number of responses the requestor may receive or use a timeout to limit on the speed of the response. One-to-many request reply is sometimes called *scatter gather*.
Request-Reply is a common pattern in modern distributed systems. A request is sent and the application either waits on the response with a certain timeout or receives a response asynchronously.
The increased complexity of modern systems requires features such as location transparency, scale up and scale down, observability and more. Many technologies need additional components, sidecars and proxies to accomplish the complete feature set.
In a request-response exchange the publish request operation publishes a message with a reply subject expecting a response on that reply subject. Many libraries allow you to use a function that will automatically wait for a response with a timeout. You can also handle that waiting process yourself.
NATS supports this pattern with its core communication mechanism, publish and subscribe. A request is published on a given subject with a reply subject, and responders listen on that subject and send responses to the reply subject. Reply subjects
are usually a subject called and _INBOX that will be directed back to the requestor dynamically, regardless of location of either party.
The common pattern used by the libraries is that the request creates a unique inbox and performs a request call with the inbox reply and returns the first reply received. This is optimized in the case of multiple responses by ignoring later responses automatically.
NATS allows multiple responders to run and form dynamic queue groups for transparent scale up. The ability for NATS applications to drain before exiting allows scale down with no requests being dropped. And since NATS is based on publish-subscribe,
observability is as simple as running another application that can view requests and responses to measure latency, watch for anomalies, direct scalability and more.
The power of NATS even allows multiple responses where the first response is utilized and the system efficiently discards the additional ones. This allows for a sophisticated pattern to have multiple responders reduce response latency and jitter.
<div class="graphviz"><code data-viz="dot">
digraph nats_request_reply {

View File

@ -1,6 +1,7 @@
# Sequence Numbers
A common problem for one-to-many messages is that a message can get lost or dropped due to a network failure. A simple pattern for resolving this situation is to include a sequence id with the message. Receivers can check the sequence id to see if they miss anything.
A common problem for one-to-many messages is that a message can get lost or dropped due to a network failure. A simple pattern for resolving this situation is to include a sequence id with the message. Receivers can check the sequence id to see if they have missed anything.
Sequence numbers combined with heartbeats in the absence of new data form a powerful and resilient pattern to detect loss. Systems that store and persist messages can also solve this problem, but sometimes are overkill for the problem at hand and usually cause additional management and operational cost.
<div class="graphviz"><code data-viz="dot">
digraph nats_pub_sub {
@ -22,4 +23,5 @@ In order to really leverage sequence ids there are a few things to keep in mind:
* Each sender will have to use their own sequence
* If possible, receivers should be able to ask for missing messages by id
With NATS you can embed sequence ids in the message, or you can include them in the subject. For example, a sender can send messages to `updates.1`, `updates.2`, etc... and the subscribers can listen to `updates.*` and optionally parse the subject to determine the sequence id.
With NATS you can embed sequence ids in the message or include them as a token in the subject. For example, a sender can send messages to `updates.1`, `updates.2`, etc... and the subscribers can listen to `updates.*` and parse the subject to determine the sequence id.
Placing a sequence token into the subject may be desireable if the payload is unknown or embedding additional data such as a sequence number in the payload is not possible.

View File

@ -1,9 +1,7 @@
# Connecting to NATS
Most client libraries provide several ways to connect to the NATS server. The server itself is identified by a standard URL with the `nats` protocol. Throughout these examples we will rely on a test server, provided by [nats.io](https://nats.io), at `nats://demo.nats.io:4222`, where `4222` is the default port for NATS.
A NATS system is usually identified by a standard URL with the `nats` or `tls` protocol, e.g. nats://demo.nats.io. A NATS system can be a single server, a small cluster or a global super cluster. Throughout these examples we will rely on a single test server, provided by [nats.io](https://nats.io), at `nats://demo.nats.io`, where `4222` is the default port for NATS.
NATS clients also support the `tls` protocol to indicate that the client wants to use TLS. So in the previous example we can replace `nats` with `tls` to get `tls://demo.nats.io:4222`.
The protocol requirement is being removed from many libraries, so that you can use `demo.nats.io:4222` as the URL and let the client and server resolve whether or not TLS is required.
NATS also supports secure connectivity using TLS via the `tls` protocol. Most clients support auto-detection of a secure connection using the URL protocol `tls`. There is also a demo server running TLS at `tls://demo.nats.io:4443`. The protocol requirement is being made optional for many client libraries, so that you can use `demo.nats.io:4222` as the URL and let the client and server resolve whether or not TLS is required.
There are numerous options for a NATS connections ranging from timeouts to reconnect settings.

View File

@ -1,6 +1,8 @@
# Turning Off Echo'd Messages
By default the server will echo messages. This means that if a publisher on a connection sends a message to a subject any subscribers on that same connection will receive the message. Turning off echo is a fairly new feature for the NATS server, but some of the clients already support it.
By default a NATS connection will echo messages if the connection also has interest in the published subject. This means that if a publisher on a connection sends a message to a subject any subscribers on that same connection will receive the message. Clients can opt to turn off this behavior, such that regardless of interest the message will not be delivered to subscribers on the same connection.
The NoEcho option can be useful in BUS patterns where all applications subsribe and publish to the same subject. Usually a publish represents a state change that the application already knows about, so in the case that the application opublishes an updated it does not need to process the update itself.
<div class="graphviz"><code data-viz="dot">
digraph {

View File

@ -1,26 +1,28 @@
# Draining Connections and Subscriptions
A feature recently added across the NATS client libraries is the ability to drain connections or subscriptions. Closing a connection, or unsubscribing from a subscription are generally considered immediate requests. When you close or unsubscribe the library will halt messages in any pending queue or cache for subscribers. When you drain a subscription or connection, it will process any cached/pending messages before closing.
A feature recently added across the NATS client libraries is the ability to drain connections or subscriptions. Closing a connection, or unsubscribing from a subscription., are generally considered immediate requests. When you close or unsubscribe the library will halt messages in any pending queue or cache for subscribers. When you drain a subscription or connection, it will process any inflight and cached/pending messages before closing.
Drain provides clients that use queue subscriptions with a way to bring down applications without losing any messages. A client can bring up a new queue member, drain and shut down the old queue member, all without losing messages sent to the old client. Without drain, there is the possibility of lost messages due to queue timing.
Drain provides clients that use queue subscriptions with a way to bring down applications without losing any messages. A client can bring up a new queue member, drain and shut down the old queue member, all without losing messages sent to the old client. Without drain, there is the possibility of lost messages due to delivery timing.
The libraries can provide drain on a connection or on a subscriber, or both.
For a connection the process is essentially:
1. Drain subscriptions
1. Drain all subscriptions
2. Stop new messages from being published
3. Flush any remaining messages
3. Flush any remaining published messages
4. Close
The API for drain can generally be used instead of close:
As an example of draining a connection:
!INCLUDE "../../_examples/drain_conn.html"
The mechanics of drain for a subscription are simpler:
1. Unsubscribe at the server
2. Process known messages
1. Unsubscribe
2. Process all cached or inflight messages
3. Clean up
The API for drain can generally be used instead of unsubscribe:

View File

@ -1,9 +1,9 @@
# Receiving Messages
Receiving messages with NATS can be very library dependent.
In general, applications can receive messages asynchronously or synchronously. Receiving messages with NATS can be library dependent.
Some languages, like Go or Java, provide synchronous and asynchronous APIs, while others may only support one type of subscription.
In all cases, the process of subscribing involves having the client library tell the NATS server that an application is interested in a particular subject.
In all cases, the process of subscribing involves having the client library tell the NATS system that an application is interested in a particular subject.
Under the covers, the client library will assign a unique id to each subscription. This id is used when the server sends messages to a specific subscription. Each subscription gets a unique id, so if the same connection is used multiple times for the same subject, the server will send multiple copies of the same message. When an application is done with a subscription it unsubscribes which tells the server to stop sending messages.
Under the covers, the client library will assign a unique id to each subscription. This id is used as a closure when the server sends messages to a specific subscription. Each subscription gets a unique id, so if the same connection is used multiple times for the same subject, the server will send multiple copies of the same message. When an application is done with a subscription it unsubscribes which tells the server to stop sending messages.

View File

@ -1,6 +1,6 @@
# Receiving Structured Data
Client libraries may provide tools to help receive structured data, like JSON. The core traffic to the NATS server will always be byte arrays. For libraries that don't provide helpers, you can always encode and decode data before sending the associated bytes to the NATS client.
Client libraries may provide tools to help receive structured data, like JSON. The core traffic to the NATS server will always be opaque byte arrays. The server does not process message payloads in any form. For libraries that don't provide helpers, you can always encode and decode data before sending the associated bytes to the NATS client.
For example, to receive JSON you could do:

View File

@ -1,7 +1,7 @@
# Synchronous Subscriptions
Synchronous subscriptions require the application to poll for messages. This type of subscription is easy to set-up and use, but requires the application to deal with looping if multiple messages are expected. For situations where a single message is expected, synchronous subscriptions are sometimes easier to manage, depending on the language.
Synchronous subscriptions require the application to wait for messages. This type of subscription is easy to set-up and use, but requires the application to deal with looping if multiple messages are expected. For situations where a single message is expected, synchronous subscriptions are sometimes easier to manage, depending on the language.
For example, to subscribe to the subject `updates` and receive a single message you could do:

View File

@ -1,9 +1,7 @@
# Reconnecting
Most, if not all, of the client libraries will reconnect to the server if they are disconnected due to a network problem. The reconnect logic can differ by library, so check your client library's documentation.
Most, if not all, of the client libraries will reconnect to the NATS system if they are disconnected for any reason. The reconnect logic can differ by library, so check your client library's documentation.
In general, the client will try to connect to all of the servers it knows about, either through the URLs provided in `connect` or the URLs provided by its most recent server. The library may have several options to help control reconnect behavior.
In general, the client will try to connect to all of the servers it knows about, either through the URLs provided in the `connect` call or the URLs provided by the NATS system itself. The NATS system will inform clients of new endpoints that can be used to reconnect. The library may have several options to help control reconnect behavior.
The list of servers used during reconnect is library dependent, but generally is constructed from the list of servers passed to the connect function/options and the list of servers provided by the most recent connected server.
One, sometimes important, detail is that the server URLs provided to clients by servers will use addresses, while the URLs provided to the connect function will usually be host names. As a result, it is possible, on reconnect, for the same server to be tried multiple times without the client knowing about the match.
The list of servers used during reconnect is library dependent, but generally is constructed from connect function/options and the list of servers provided by the NATS system itself. This feature allows NATS applications and the NATS system itself to self heal and reconfigure itself with no additional configuration or intervention.

View File

@ -1,5 +1,5 @@
# Securing Connections
NATS provides several forms of security for your messages. First, you can turn on authorization which limits access to the NATS server. Second, access to specific subjects can be controlled. Third, you can use TLS to encrypt traffic between clients and the server. Finally, TLS can be used to verify client identities using certificates. By combining all of these methods you can protect access to data and data in motion.
NATS provides several forms of security, authentication, authorization and isolation. You can turn on authentication which limits access to the NATS system. Accounts allow for isolation of a subject space and groups of applications. Authorization can be used to limit individual users access to specific subjects for publish and subscribe operations. TLS can be used to encrypt all traffic between clients and the NATS system. Finally, TLS can be used to verify client identities using client certificates. By combining all of these methods you can protect access the system and to all message flows.
The client doesn't have control over access controls, but clients do provide the configurations required to authenticate with the server and to turn on TLS.
The client doesn't have control over access controls, but clients do provide the configurations required to authenticate with the system, bind to an account, and to require TLS.

View File

@ -1,6 +1,6 @@
# Encrypting Connections with TLS
While authentication limits which clients can connect, TLS can be used to check the servers identity and the clients identity and will encrypt the traffic between the two. The most secure version of TLS with NATS is to use verified client certificates. In this mode, the client can check that it trusts the certificate sent by `nats-server` but the server will also check that it trusts the certificate sent by the client. From an application's perspective connecting to a server that does not verify client certificates may appear identical. Under the covers, disabling TLS verification removes the server side check on the clients certificate. When started in TLS mode, `nats-server` will require all clients to connect with TLS. Moreover, if configured to connect with TLS, client libraries will fail to connect to a server without TLS.
While authentication limits which clients can connect, TLS can be used to check the servers identity and optionally the clients identity and will encrypt all traffic between the two. The most secure version of TLS with NATS is to use verified client certificates. In this mode, the client can check that it trusts the certificate sent by NATS system but the individual server will also check that it trusts the certificate sent by the client. From an application's perspective connecting to a server that does not verify client certificates may appear identical. Under the covers, disabling TLS verification removes the server side check on the clients certificate. When started in TLS mode, a `nats-server` will require all clients to connect with TLS. Moreover, if configured to connect with TLS, client libraries will fail to connect to a server without TLS.
The [Java examples repository](https://github.com/nats-io/java-nats-examples/tree/master/src/main/resources) contains certificates for starting the server in TLS mode.
@ -12,7 +12,8 @@ The [Java examples repository](https://github.com/nats-io/java-nats-examples/tre
## Connecting with TLS
Connecting to a server with TLS is primarily an exercise in setting up the certificate and trust managers. For example:
Connecting to a server with TLS is straightforward. Most clients will automatically use TLS when connected to a NATS system using TLS. Setting up a NATS system to use TLS is primarily an exercise in setting up the certificate and trust managers.
Clients may also need additional information, for example:
!INCLUDE "../../_examples/connect_tls.html"

View File

@ -1,5 +1,5 @@
# Including a Reply Subject
The optional reply-to field when publishing a message can be used on the receiving side to respond. The reply-to subject is often called an _inbox_, and some libraries may provide a method for generating unique inbox subjects. For example to send a request to the subject `time`, with no content for the messages, you might:
The optional reply-to field when publishing a message can be used on the receiving side to respond. The reply-to subject is often called an _inbox_, and most libraries may provide a method for generating unique inbox subjects. Most libraries also provide for the request-reply pattern with a single call. For example to send a request to the subject `time`, with no content for the messages, you might:
!INCLUDE "../../_examples/publish_with_reply.html"

View File

@ -1,6 +1,6 @@
# Explore NATS Pub/Sub
NATS is a publish subscribe messaging system. Subscribers listening on a subject name receive messages on that subject. If the subscriber is not actively listening on the subject, the message is not received. Subscribers can use the wildcard subjects `*` to match a single token to match the tail of a subject.
NATS is a publish subscribe messaging system. Subscribers listening on a subject receive messages on that subject. If the subscriber is not actively listening on the subject, the message is not received. Subscribers can use the wildcard tokens such as `*` and `>` to match a single token or to match the tail of a subject.
<div class="graphviz"><code data-viz="dot">
digraph nats_pub_sub {
@ -9,13 +9,13 @@ digraph nats_pub_sub {
sub1 [shape="box", label="SUB\ncom.msg.one"];
pub1 [shape="box", label="PUB\ncom.msg.one"];
non_active [shape="box", label="Non-Active\nSubscriber"];
{
rank=same
pub1 sub1 non_active
}
gnatsd [shape="box", label="NATS", width=8];
nats-server [shape="box", label="NATS", width=8];
sub2 [shape="box", label="SUB\ncom.msg.one"];
sub3 [shape="box", label="SUB\ncom.msg.two"];
@ -26,19 +26,19 @@ digraph nats_pub_sub {
sub2 sub3 sub4
}
pub1 -> gnatsd [penwidth=2];
gnatsd -> sub1 [penwidth=2];
gnatsd -> non_active [style=dashed color=red arrowhead="none"];
pub1 -> nats-server [penwidth=2];
nats-server -> sub1 [penwidth=2];
nats-server -> non_active [style=dashed color=red arrowhead="none"];
gnatsd -> sub2 [penwidth=2];
gnatsd -> sub3 [style=dashed color=red arrowhead="none"];
gnatsd -> sub4 [penwidth=2];
nats-server -> sub2 [penwidth=2];
nats-server -> sub3 [style=dashed color=red arrowhead="none"];
nats-server -> sub4 [penwidth=2];
}
</code></div>
## Prerequisites
Go and the NATS server should be installed.
Go and the NATS server should be installed. optionally you can use the demo server located at `nats://demo.nats.io`
### 1. Start the NATS server

View File

@ -1,6 +1,6 @@
## NATS Cluster Protocol
The NATS server clustering protocol describes the messages passed between NATS servers within a [cluster](/nats_server/clustering.md) to share subscription state, forward messages, and share cluster topology. It is a simple, text-based publish/subscribe style protocol. Servers communicate with each other through a regular TCP/IP socket using a small set of protocol operations that are terminated by newline.
The NATS server clustering protocol describes the protocols passed between NATS servers within a [cluster](/nats_server/clustering.md) to share accounts, subscriptions, forward messages, and share cluster topology regarding new servers. It is a simple text-based protocol. Servers communicate with each other through a regular TCP/IP or TLS socket using a small set of protocol operations that are terminated by newline.
The NATS server implements a [zero allocation byte parser](https://youtu.be/ylRKac5kSOk?t=10m46s) that is fast and efficient.
@ -8,12 +8,12 @@ The NATS cluster protocol is very similar to that of the NATS client protocol.
## NATS Cluster protocol conventions
**Subject names and wildcards**: The NATS cluster protocol has the same features and restrictions as the client with respect to subject names and wildcards, with one addition - a server can publish subjects prefixed with `_SYS.`, which is reserved for messages that are internally generated by a server.
**Subject names and wildcards**: The NATS cluster protocol has the same features and restrictions as the client with respect to subject names and wildcards. Clients are bound to a single account, however the cluster protocol handles all accounts.
**Field Delimiters**: The fields of NATS protocol messages are delimited by whitespace characters '` `' (space) or `\t` (tab).
Multiple whitespace characters will be treated as a single field delimiter.
**Newlines**: Like other text-based protocols, NATS uses `CR` followed by `LF` (`CR+LF`, `\r\n`, `0x0D0A`) to terminate protocol messages. This newline sequence is also used to mark the beginning of the actual message payload in a `PUB` or `MSG` protocol message.
**Newlines**: Like other text-based protocols, NATS uses `CR` followed by `LF` (`CR+LF`, `\r\n`, `0x0D0A`) to terminate protocol messages. This newline sequence is also used to mark the beginning of the actual message payload in a `RMSG` protocol message.
## NATS Cluster protocol messages
@ -27,13 +27,12 @@ Click the name to see more detailed information, including syntax:
| -------------------- |:-----------------|:--------------------------------------------
| [`INFO`](#INFO) | All Servers | Sent after initial TCP/IP connection and to update cluster knowledge
| [`CONNECT`](#CONNECT)| All Servers | Sent to establish a route
| [`PUB`](#PUB) | Sending Server | Sent when a message is published by a client.
| [`SUB`](#SUB) | All Servers | Subscribes to a subject on behalf of interested clients.
| [`UNSUB`](#UNSUB) | All Servers | Unsubscribe (or auto-unsubscribe) from subject.
| [`MSG`](#MSG) | Receiving Server | Delivers a message payload to a subscriber on the local server.
| [`RS+`](#SUB) | All Servers | Subscribes to a subject for a given account on behalf of interested clients.
| [`RS-`](#UNSUB) | All Servers | Unsubscribe (or auto-unsubscribe) from subject for a given account.
| [`RMSG`](#MSG) | Origin Server | Delivers a message for a given subject and account to another server.
| [`PING`](#PINGPONG) | All Servers | PING keep-alive message
| [`PONG`](#PINGPONG) | All Servers | PONG keep-alive response
| [`+OK/-ERR`](#OKERR) | All Servers | Indicates a protocol error. Will cause the server to disconnect.
| [`-ERR`](#ERR) | All Servers | Indicates a protocol error. May cause the remote server to disconnect.
The following sections explain each protocol message.
@ -83,8 +82,6 @@ The `CONNECT` message is analogous to the `INFO` message. Once the NATS server h
The valid options are as follows:
* `verbose`: Turns on [`+OK`](#OKERR) protocol acknowledgements.
* `pedantic`: Turns on additional strict format checking, e.g. for properly formed subjects
* `tls_required`: Indicates whether the server requires an SSL connection.
* `auth_token`: Authorization token
* `user`: Connection username (if `auth_required` is set)
@ -97,126 +94,61 @@ The valid options are as follows:
Here is an example from the default string from a server.
`CONNECT {"verbose":false,"pedantic":false,"tls_required":false,"name":"wt0vffeQyoDGMVBC2aKX0b"}\r\n`
`CONNECT {"tls_required":false,"name":"wt0vffeQyoDGMVBC2aKX0b"}\r\n`
Servers should set `verbose` to `false` by default. This means that other routed servers will not be sending an `+OK` payload back after the remote server ingested the message.
## <a name="PUB"></a>PUB
#### Description
The `PUB` message publishes the message payload to the given subject name, optionally supplying a reply subject, to another server. If a reply subject is supplied, it will be delivered to eligible subscribers along with the supplied payload. Note that the payload itself is optional. To omit the payload, set the payload size to 0.
#### Syntax
`PUB <subject> [reply-to] <#bytes>\r\n[payload]\r\n`
where:
* `subject`: The destination subject to publish to
* `reply-to`: The reply inbox subject that subscribers can use to send a response back to the publisher/requestor
* `#bytes`: The payload size in bytes
* `payload`: The message payload data
#### Example
To publish the string message payload "Hello NATS!" to subject FOO:
`PUB FOO 11\r\nHello NATS!\r\n`
To publish a request message "Knock Knock" to subject FRONT.DOOR with reply subject INBOX.22:
`PUB FRONT.DOOR INBOX.22 11\r\nKnock Knock\r\n`
To publish an empty message to subject NOTIFY:
`PUB NOTIFY 0\r\n\r\n`
## <a name="SUB"></a>SUB
## <a name="SUB"></a>RS+
#### Description
`SUB` initiates a subscription to a subject, optionally joining a distributed queue group.
`RS+` initiates a subscription to a subject on on a given account, optionally with a distributed queue group name and weighting factor.
Note that queue subscriptions will use RS+ for increases and descreases to queue weight except when the weighting factor is 0.
#### Syntax
**Basic Subscription**: `SUB <subject> RSID:<cid>:<sid>\r\n`
**Subscription**: `RS+ <account> <subject>\r\n`
**Queue Subscription**: `SUB <subject> <queue> QRSID:<cid>:<sid>\r\n`
**Queue Subscription**: `RS+ <account> <subject> <queue> <weight>\r\n`
where:
* `subject`: The subject name to subscribe to
* `queue`: If specified, the subscriber will join this queue group
* `cid`: A 64bit unsigned integer representing the client connection
* `sid`: A unique alphanumeric subscription ID representing the server's subscription
* `account`: The account associated with the subject interest
* `subject`: The subject
* `queue`: Optional queue group name
* `weight`: Optional queue group weight representing how much interest/subscribers
#### Example
To subscribe to the subject `FOO` with the local unique subject identifier of `1`, and the connection-unique subject identifier (sid) `1`:
`SUB FOO RSID:1:1\r\n`
To subscribe the current connection to the subject `BAR` as part of distribution queue group `G1` with local sid of `14`, and a client sid `44`:
`SUB BAR G1 QRSID:14:44\r\n`
## <a name="UNSUB"></a>UNSUB
## <a name="UNSUB"></a>RS-
#### Description
`UNSUB` unsubcribes the connection from the specified subject, or auto-unsubscribes after the specified number of messages has been received. It is sent by a server when one of it's clients unsubscribes.
`RS-` unsubcribes from the specified subject on the given account. It is sent by a server when it no longer has interest in a given subject.
#### Syntax
**Basic Subscription**: `UNSUB <sid> RSID:<cid>:<sid> [max_msgs]\r\n`
**Queue Subscription**: `UNSUB <sid> QRSID:<cid>:<sid> [max_msgs]\r\n`
**Subscription**: `RS- <account> <subject>\r\n`
where:
* `sid`: The unique alphanumeric subscription ID of the subject to unsubscribe from
* `max_msgs`: Number of messages to wait for before automatically unsubscribing
* `cid`: A 64bit unsigned integer representing the client connection
* `sid`: A unique alphanumeric subscription ID representing the server's subscription
* `account`: The account associated with the subject interest
* `subject`: The subject
#### Example
The following examples concern subject `FOO` which has been assigned an internal subscriber id of `5`, and a client sid of `1`. To unsubscribe from `FOO`:
`UNSUB RSID:5:1\r\n`
To auto-unsubscribe from `FOO` after 5 messages have been received:
`UNSUB RSID:1:1 5\r\n`
## <a name="MSG"></a>MSG
## <a name="MSG"></a>RMSG
#### Description
The `MSG` protocol message delivers a message from another server.
The `RMSG` protocol message delivers a message to another server.
#### Syntax
`MSG <subject> <sid> [reply-to] <#bytes>\r\n[payload]\r\n`
`RMSG <account> <subject> [reply-to] <#bytes>\r\n[payload]\r\n`
where:
* `account`: The account associated with the subject interest
* `subject`: Subject name this message was received on
* `sid`: The unique alphanumeric subscription ID of the subject
* `reply-to`: The inbox subject on which the publisher is listening for responses
* `reply-to`: The optional reply subject
* `#bytes`: Size of the payload in bytes
* `payload`: The message payload data
#### Example
The following message delivers a message from subject `FOO.BAR`:
`MSG FOO.BAR 9 11\r\nHello World\r\n`
Deliver the same message along with a reply inbox:
`MSG FOO.BAR 9 INBOX.34 11\r\nHello World\r\n`
## <a name="PINGPONG"></a>PING/PONG
#### Description
@ -230,32 +162,8 @@ If the another server sends a ping request, a server will reply with a pong mess
`PING\r\n`
`PONG\r\n`
## <a name="OKERR"></a>+OK/ERR
## <a name="ERR"></a>-ERR
#### Description
When the `verbose` connection option is set to `true` (the default value), the server acknowledges each well-formed protocol message with a `+OK` message. NATS servers set the `verbose` option to `false` using the [CONNECT](#CONNECT) message
The `-ERR` message is used by the server indicate a protocol, authorization, or other runtime connection error to another server. Most of these errors result in the server closing the connection.
Handling of these errors usually has to be done asynchronously.
#### Syntax
`+OK`
`-ERR <error message>`
Protocol error messages which close the connection:
- `-ERR 'Unknown Protocol Operation'`: Unknown protocol error
- `-ERR 'Authorization Violation'`: Server failed to authenticate to another server with credentials specified in the [CONNECT](#CONNECT) message.
- `-ERR 'Authorization Timeout'`: Server took too long to authenticate to another server after establishing a connection (default 1 second)
- `-ERR 'Parser Error'`: Cannot parse the protocol message sent by another server
- `-ERR 'Stale Connection'`: PING/PONG interval expired.
- `-ERR 'Slow Consumer'`: The other server's pending data size for the route connection has been exceeded. The default limit is time based, where data cannot be flushed within a two second write deadline.
- `-ERR 'Maximum Payload Exceeded'`: Server attempted to publish a message with a payload size that exceeds the `max_payload` size configured on another server.
Protocol error messages which do not close the connection:
- `-ERR 'Invalid Subject'`: Server sent a malformed subject (e.g. `sub foo. 90`)
The `-ERR` message is used by the server indicate a protocol, authorization, or other runtime connection error to another server. Most of these errors result in the remote server closing the connection.