1
0
mirror of https://github.com/taigrr/nats.docs synced 2026-04-15 05:10:53 -07:00

GitBook: [master] 326 pages and 16 assets modified

This commit is contained in:
Ginger Collison
2019-10-04 17:48:52 +00:00
committed by gitbook-bot
parent 8b7ba5c3bb
commit fb0d5c8355
203 changed files with 4640 additions and 3107 deletions

View File

@@ -1,13 +0,0 @@
# Developing with NATS
Developing with NATS is a combination of distributed application techniques, common NATS features and library specific syntax. As well as using this book for guidance, some of the libraries contain language-familiar formats of their API. For example, the Go library has godoc, and the Java library has javadoc.
| Library | Doc Link |
| ------------- | ------------- |
| [nats.go](https://github.com/nats-io/nats.go) | [godoc](http://godoc.org/github.com/nats-io/nats.go) |
| [nats.java](https://github.com/nats-io/nats.java) | [javadoc](https://javadoc.io/doc/io.nats/jnats) |
| [nats.net](https://github.com/nats-io/nats.net) | [doxygen](http://nats-io.github.io/nats.net/) |
| [nats.rb](https://github.com/nats-io/nats.rb) | [yard](https://www.rubydoc.info/gems/nats) |
| [nats.ts](https://github.com/nats-io/nats.ts) | [ts-doc](https://nats-io.github.io/nats.ts) |
Not all libraries contain this separate doc, depending on the language community, but be sure to check out the client libraries README for more information.

View File

@@ -1,7 +0,0 @@
# Acknowledgements
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 ensure 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.
![](/assets/images/acks.svg)
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,9 +0,0 @@
# What is NATS
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.
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.
![](/assets/images/intro.svg)
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,7 +0,0 @@
# Publish-Subscribe
NATS implements a publish-subscribe message distribution model for one-to-many communication. A publisher sends a message on a subject and any active subscriber listening on that subject receives the message. Subscribers can also register interest in wildcard subjects that work a bit like a regular expression (but only a bit). This one-to-many pattern is sometimes called fan-out.
![](/assets/images/pubsub.svg)
Try NATS publish subscribe on your own, using a live server by walking through the [pub-sub tutorial](../tutorials/pubsub.md).

View File

@@ -1,14 +0,0 @@
# Queue Subscribers & Scalability
NATS provides a built-in 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. 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 application and their queue subscribers, not on the server configuration.
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.
![](/assets/images/queue.svg)
Try NATS queue subscriptions on your own, using a live server by walking through the [queueing tutorial](../tutorials/queues.md).

View File

@@ -1,15 +0,0 @@
# Request-Reply
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.
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 an \_INBOX that will be directed back to the requestor dynamically, regardless of location of either party.
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.
![](/assets/images/reqrepl.svg)
Try NATS request reply on your own, using a live server by walking through the [request/reply tutorial](../tutorials/reqreply.md).

View File

@@ -1,14 +0,0 @@
# 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 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.
![](/assets/images/seqno.svg)
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 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,39 +0,0 @@
# Subject-based Messaging
Fundamentally NATS is about publishing and listening for messages. Both of these depend heavily on _Subjects_ which scope messages into streams or topics. At its simplest, a subject is just a string of characters that form a name the publisher and subscriber can use to find each other.
![](/assets/images/subjects1.svg)
The NATS server reserves a few characters as special, and the specification says that only "alpha-numeric" characters plus the "." should be used in subject names. Subjects are case-sensitive and cannot contain whitespace. For safety across clients, ASCII characters should be used, although this is subject to change in the future.
## Subject Hierarchies
The `.` character is used to create a subject hierarchy. For example, a world clock application might define the following to logically group related subjects:
```markup
time.us
time.us.east
time.us.east.atlanta
time.eu.east
time.eu.warsaw
```
## 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`.
![](/assets/images/subjects2.svg)
### 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.
![](/assets/images/subjects3.svg)
### Monitoring and Wire Taps
Subject to your security configuration, wildcards can be used for monitoring by creating something sometimes called a *wire tap*. In the simplest case you can create a subscriber for `>`. This application will receive all messages -- again, subject to security settings -- sent on your NATS cluster.

View File

@@ -1,20 +0,0 @@
# Connecting to a Cluster
When connecting to a cluster, there are a few things to think about.
* Passing a URL for each cluster member (semi-optional)
* The connection algorithm
* The reconnect algorithm (discussed later)
* Server provided URLs
When a client library first tries to connect it will use the list of URLs provided to the connection options or function. These URLs are checked, usually in order, and the first successful connection is used.
After a client connects to the server, the server may provide a list of URLs for additional known servers. This allows a client to connect to one server and still have other servers available during reconnect.
To insure the initial connection, your code should include a list of reasonable _front line_ servers. Those servers may know about other members of the cluster, and may tell the client about those members. But you don't have to configure the client to pass every valid member of the cluster in the connect method.
By providing the ability to pass multiple connect options NATS can handle the possibility of a machine going down or being unavailable to a client. By adding the ability of the server to feed clients a list of known servers as part of the client-server protocol the mesh created by a cluster can grow and change organically while the clients are running.
*Note, failure behavior is library dependent, please check the documentation for your client library on information about what happens if the connect fails.*
!INCLUDE "../../_examples/connect_multiple.html"

View File

@@ -1,5 +0,0 @@
# Setting a Connect Timeout
Each library has its own, language preferred way, to pass connection options. One of the most common options is a connection timeout. To set the maximum time to connect to a server to 10 seconds:
!INCLUDE "../../_examples/connect_options.html"

View File

@@ -1,5 +0,0 @@
# Connecting to the Default Server
Some libraries also provide a special way to connect to a *default* url, which is generally `nats://localhost:4222`:
!INCLUDE "../../_examples/connect_default.html"

View File

@@ -1,7 +0,0 @@
# Connecting to 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 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 connection ranging from timeouts to reconnect settings.

View File

@@ -1,11 +0,0 @@
# Turning Off Echo'd Messages
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 subscribe and publish to the same subject. Usually a publish represents a state change that the application already knows about, so in the case where the application publishes an update it does not need to process the update itself.
![](/assets/images/noecho.svg)
Keep in mind that each connection will have to turn off echo, and that it is per connection, not per application. Also, turning echo on and off can result in a major change to your applications communications protocol since messages will flow or stop flowing based on this setting and the subscribing code won't have any indication as to why.
!INCLUDE "../../_examples/no_echo.html"

View File

@@ -1,19 +0,0 @@
# Ping/Pong Protocol
The client and server use a simple PING/PONG protocol to check that they are both still connected. The client will ping the server on a regular, configured interval so that the server usually doesn't have to initiate the PING/PONG interaction.
![](/assets/images/pingpong.svg)
## Set the Ping Interval
If you have a connection that is going to be open a long time with few messages traveling on it, setting this PING interval can control how quickly the client will be notified of a problem. However on connections with a lot of traffic, the client will often figure out there is a problem between PINGS, and as a result the default PING interval is often on the order of minutes. To set the interval to 20s:
!INCLUDE "../../_examples/ping_20s.html"
## Limit Outgoing Pings
The PING/PONG interaction is also used by most of the clients as a way to flush the connection to the server. Clients that cache outgoing messages provide a flush call that will run a PING/PONG. The flush will wait for the PONG to return, telling it that all cached messages have been processed, including the PING. The number of cached PING requests can be limited in most clients to insure that traffic problems are identified early. This configuration for _max outgoing pings_ or similar will usually default to a small number and should only be increased if you are worried about fast flush traffic, perhaps in multiple threads.
For example, to set the maximum number of outgoing pings to 5:
!INCLUDE "../../_examples/ping_5.html"

View File

@@ -1,29 +0,0 @@
# Controlling the Client/Server Protocol
The protocol between the client and the server is fairly simple and relies on a control line and sometimes a body. The control line contains the operations being sent, like PING or PONG, followed by a carriage return and line feed, CRLF or "\r\n". The server has a setting that can limit the maximum size of a control line. For PING and PONG this doesn't come into play, but for messages that contain subject names, the control line length can be important. The server is also configured with a maximum payload size, which limits the size of a message body. The server sends the maximum payload size to the client at connect time but doesn't currently tell the client the maximum control line size.
## Set the Maximum Control Line Size
Some clients will try to limit the control line size internally to prevent an error from the server. These clients may or may not allow you to set the size being used, but if they do, the size should be set to match the server configuration.
For example, to set the maximum control line size to 2k:
!INCLUDE "../../_examples/control_2k.html"
## Get the Maximum Payload Size
While the client can't control the maximum payload size, clients may provide a way for applications to get the size after the connection is made. This will allow the application to chunk or limit data as needed to pass through the server.
!INCLUDE "../../_examples/max_payload.html"
## Turn On Pedantic Mode
The NATS server provides a _pedantic_ mode that does extra checks on the protocol. By default, this setting is off but you can turn it on:
!INCLUDE "../../_examples/connect_pedantic.html"
## Turn On/Off Verbose Mode
The NATS server also provide a _verbose_ mode. By default, verbose mode is enabled and the server will reply to every message from the client with either a +OK or a -ERR. Most clients turn off verbose mode, which disables all of the +OK traffic. Errors are rarely subject to verbose mode and client libraries handle them as documented. To turn on verbose mode, likely for testing:
!INCLUDE "../../_examples/connect_verbose.html"

View File

@@ -1,9 +0,0 @@
# Connecting to a Specific Server
The NATS client libraries can take a full URL, `nats://demo.nats.io:4222`, to specify a specific server host and port to connect to.
Libraries are removing the requirement for an explicit protocol and may allow `nats://demo.nats.io:4222` or just `demo.nats.io:4222`. Check with your specific client library's documentation to see what URL formats are supported.
For example, to connect to the demo server with a URL you can use:
!INCLUDE "../../_examples/connect_url.html"

View File

@@ -1,21 +0,0 @@
# Listen for Connection Events
While the connection status is interesting, it is perhaps more interesting to know when the status changes. Most, if not all, of the NATS client libraries provide a way to listen for events related to the connection and its status.
The actual API for these listeners is language dependent, but the following examples show a few of the more common use cases. See the API documentation for the client library you are using for more specific instructions.
Connection events may include the connection being closed, disconnected or reconnected. Reconnecting involves a disconnect and connect, but depending on the library implementation may also include multiple disconnects as the client tries to find a server, or the server is rebooted.
!INCLUDE "../../_examples/connection_listener.html"
## Listen for New Servers
When working with a cluster, servers may be added or changed. Some of the clients allow you to listen for this notification:
!INCLUDE "../../_examples/servers_added.html"
## Listen for Errors
The client library may separate server-to-client errors from events. Many server events are not handled by application code and result in the connection being closed. Listening for the errors can be very useful for debugging problems.
!INCLUDE "../../_examples/error_listener.html"

View File

@@ -1,7 +0,0 @@
# Monitoring the Connection
Managing the interaction with the server is primarily the job of the client library but most of the libraries also provide some insight into what is happening under the covers.
For example, the client library may provide a mechanism to get the connection's current status:
!INCLUDE "../../_examples/connect_status.html"

View File

@@ -1,31 +0,0 @@
# Slow Consumers
NATS is designed to move messages through the server quickly. As a result, NATS depends on the applications to consider and respond to changing message rates. The server will do a bit of impedance matching, but if a client is too slow the server will eventually cut them off. These cut off connections are called _slow consumers_.
One way some of the libraries deal with bursty message traffic is to cache incoming messages for a subscription. So if an application can handle 10 messages per second and sometimes receives 20 messages per second, the library may hold the extra 10 to give the application time to catch up. To the server, the application will appear to be handling the messages and consider the connection healthy. It is up to the client library to decide what to do when the cache is too big, but most client libraries will drop incoming messages.
Receiving and dropping messages from the server keeps the connection to the server healthy, but creates an application requirement. There are several common patterns:
* Use request/reply to throttle the sender and prevent overloading the subscriber
* Use a queue with multiple subscribers splitting the work
* Persist messages with something like NATS streaming
Libraries that cache incoming messages may provide two controls on the incoming queue, or pending messages. These are useful if the problem is bursty publishers and not a continuous performance mismatch. Disabling these limits can be dangerous in production and although setting these limits to 0 may help find problems, it is also a dangerous proposition in production.
> Check your libraries documentation for the default settings, and support for disabling these limits.
The incoming cache is usually per subscriber, but again, check the specific documentation for your client library.
## Limiting Incoming/Pending Messages by Count and Bytes
The first way that the incoming queue can be limited is by message count. The second way to limit the incoming queue is by total size. For example, to limit the incoming cache to 1,000 messages or 5mb whichever comes first:
!INCLUDE "../../_examples/slow_pending_limits.html"
## Detect a Slow Consumer and Check for Dropped Messages
When a slow consumer is detected and messages are about to be dropped, the library may notify the application. This process may be similar to other errors or may involve a custom callback.
Some libraries, like Java, will not send this notification on every dropped message because that could be noisy. Rather the notification may be sent once per time the subscriber gets behind. Libraries may also provide a way to get a count of dropped messages so that applications can at least detect a problem is occurring.
!INCLUDE "../../_examples/slow_listener.html"

View File

@@ -1,7 +0,0 @@
# Asynchronous Subscriptions
Asynchronous subscriptions use callbacks of some form to notify an application when a message arrives. These subscriptions are usually easier to work with, but do represent some form of internal work and resource usage, i.e. threads, by the library. Check your library's documentation for any resource usage associated with asynchronous subscriptions.
The following example subscribes to the subject `updates` and handles the incoming messages:
!INCLUDE "../../_examples/subscribe_async.html"

View File

@@ -1,32 +0,0 @@
# 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 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 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 all subscriptions
2. Stop new messages from being published
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
2. Process all cached or inflight messages
3. Clean up
The API for drain can generally be used instead of unsubscribe:
!INCLUDE "../../_examples/drain_sub.html"
Because draining can involve messages flowing to the server, for a flush and asynchronous message processing, the timeout for drain should generally be higher than the timeout for a simple message request/reply or similar.

View File

@@ -1,9 +0,0 @@
# Receiving Messages
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 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 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,13 +0,0 @@
# Queue Subscriptions
Subscribing to a queue group is only slightly different than subscribing to a subject alone. The application simply includes a queue name with the subscription. The effect of including the group is fairly major, since the server will now load balance messages between the members of the queue group, but the code differences are minimal.
Keep in mind that the queue groups in NATS are dynamic and do not require any server configuration. You can almost think of a regular subscription as a queue group of 1, but it is probably not worth thinking too much about that.
![](/assets/images/queues.svg)
As an example, to subscribe to the queue `workers` with the subject `updates`:
!INCLUDE "../../_examples/subscribe_queue.html"
If you run this example with the publish examples that send to `updates`, you will see that one of the instances gets a message while the others you run won't. But the instance that receives the message will change.

View File

@@ -1,7 +0,0 @@
# Replying to a Message
Incoming messages have an optional reply-to field. If that field is set, it will contain a subject to which a reply is expected.
For example, the following code will listen for that request and respond with the time.
!INCLUDE "../../_examples/subscribe_w_reply.html"

View File

@@ -1,7 +0,0 @@
# 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 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:
!INCLUDE "../../_examples/subscribe_json.html"

View File

@@ -1,8 +0,0 @@
# Synchronous Subscriptions
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:
!INCLUDE "../../_examples/subscribe_sync.html"

View File

@@ -1,15 +0,0 @@
# Unsubscribing After a Specified Number of Messages
NATS provides a special form of unsubscribe that is configured with a message count and takes effect when that many messages are sent to a subscriber. This mechanism is very useful if only a single message is expected.
The message count you provide is the total message count for a subscriber. So if you unsubscribe with a count of 1, the server will stop sending messages to that subscription after it has received one message. If the subscriber has already received one or more messages, the unsubscribe will be immediate. This action based on history can be confusing if you try to auto unsubscribe on a long running subscription, but is logical for a new one.
> Auto unsubscribe is based on the total messages sent to a subscriber, not just the new ones.
Auto unsubscribe can also result in some tricky edge cases if a server cluster is used. The client will tell the server of the unsubscribe count when the application requests it. But if the client disconnects before the count is reached, it may have to tell another server of the remaining count. This dance between previous server notifications and new notifications on reconnect can result in unplanned behavior.
Finally, most of the client libraries also track the max message count after an auto unsubscribe request. Which means that the client will stop allowing messages to flow even if the server has miscounted due to reconnects or some other failure in the client library.
The following example shows unsubscribe after a single message:
!INCLUDE "../../_examples/unsubscribe_auto.html"

View File

@@ -1,7 +0,0 @@
# Unsubscribing
The client libraries provide a means to unsubscribe a previous subscription request.
This process requires an interaction with the server, so for an asynchronous subscription there may be a small window of time where a message comes through as the unsubscribe is processed by the library. Ignoring that slight edge case, the client library will clean up any outstanding messages and tell the server that the subscription is no longer used.
!INCLUDE "../../_examples/unsubscribe.html"

View File

@@ -1,17 +0,0 @@
# Wildcards
There is no special code to subscribe with a wildcard subject. Wildcards are a normal part of the subject name.
However, there is a common technique that may come in to play when you use wildcards. This technique is to use the subject provided with the incoming message to determine what to do with the message.
For example, you can subscribe using `*` and then act based on the actual subject.
!INCLUDE "../../_examples/subscribe_star.html"
or do something similar with `>`:
!INCLUDE "../../_examples/subscribe_arrow.html"
The following example can be used to test these two subscribers. The `*` subscriber should receive at most 2 messages, while the `>` subscriber receives 4. More importantly the `time.*.east` subscriber won't receive on `time.us.east.atlanta` because that won't match.
!INCLUDE "../../_examples/wildcard_tester.html"

View File

@@ -1,13 +0,0 @@
# Buffering Messages During Reconnect Attempts
The NATS client libraries try as much as possible to be fire and forget. One of the features that may be included in the library you are using is the ability to buffer outgoing messages when the connection is down.
During a short reconnect, these client can allow applications to publish messages that, because the server is offline, will be cached in the client. The library will then send those messages on reconnect. When the maximum reconnect buffer is reached, messages will no longer be publishable by the client.
Be aware, while the message appears to be sent to the application it is possible that it is never sent because the connection is never remade. Your applications should use patterns like acknowledgements to ensure delivery.
For clients that support this feature, you are able to configure the size of this buffer with bytes, messages or both.
!INCLUDE "../../_examples/reconnect_5mb.html"
> *As mentioned throughout this document, each client library may behave slightly differently. Please check the documentation for the library you are using.*

View File

@@ -1,5 +0,0 @@
# Disable Reconnect
You can disable automatic reconnect with connection options:
!INCLUDE "../../_examples/reconnect_none.html"

View File

@@ -1,5 +0,0 @@
# Listening for Reconnect Events
Because reconnect is primarily under the covers many libraries provide an event listener you can use to be notified of reconnect events. This event can be especially important for applications sending a lot of messages.
!INCLUDE "../../_examples/reconnect_event.html"

View File

@@ -1,7 +0,0 @@
# Reconnecting
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 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 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 +0,0 @@
# Set the Number of Reconnect Attempts
Applications can set the maximum reconnect attempts. Generally, this will limit the actual number of attempts total, but check your library documentation. For example, in Java, if the client knows about 3 servers and the maximum reconnects is set to 2, it will not try all of the servers. On the other hand, if the maximum is set to 6 it will try all of the servers twice before considering the reconnect a failure and closing.
!INCLUDE "../../_examples/reconnect_10x.html"

View File

@@ -1,7 +0,0 @@
# Avoiding the Thundering Herd
When a server goes down, there is a possible anti-pattern called the *Thundering Herd* where all of the clients try to reconnect immediately, thus creating a denial of service attack. In order to prevent this, most NATS client libraries randomize the servers they attempt to connect to. This setting has no effect if only a single server is used, but in the case of a cluster, randomization, or shuffling, will ensure that no one server bears the brunt of the client reconnect attempts.
However, if you want to disable the randomization process, so that servers are always checked in the same order, you can do that in most libraries with a connection options:
!INCLUDE "../../_examples/reconnect_no_random.html"

View File

@@ -1,5 +0,0 @@
# Pausing Between Reconnect Attempts
It doesnt make much sense to try to connect to the same server over and over. To prevent this sort of thrashing, and wasted reconnect attempts, libraries provide a wait setting. This setting will pause the reconnect logic if the same server is being tried multiple times **in a row**. In the previous example, if you have 3 servers and 6 attempts, the Java library would loop over the three servers. If none were connectable, it will then try all three again. However, the Java client doesnt wait between each attempt, only when trying the same server again, so in that example the library may never wait. If on the other hand, you only provide a single server URL and 6 attempts, the library will wait between each attempt.
!INCLUDE "../../_examples/reconnect_10s.html"

View File

@@ -1,23 +0,0 @@
# Authenticating with User Credentials File
The 2.0 version of NATS server introduced the idea of JWT-based authentication. Clients interact with this new scheme using a user JWT and the private key from an NKey pair. To help make connecting with a JWT easier, the client libraries support the concept of a credentials file. This file contains both the private key and the JWT and can be generated with the `nsc` tool. The contents will look like the following and should be protected because it contains a private key. This creds file is unused and only for example purposes.
```ascii
-----BEGIN NATS USER JWT-----
eyJ0eXAiOiJqd3QiLCJhbGciOiJlZDI1NTE5In0.eyJqdGkiOiJUVlNNTEtTWkJBN01VWDNYQUxNUVQzTjRISUw1UkZGQU9YNUtaUFhEU0oyWlAzNkVMNVJBIiwiaWF0IjoxNTU4MDQ1NTYyLCJpc3MiOiJBQlZTQk0zVTQ1REdZRVVFQ0tYUVM3QkVOSFdHN0tGUVVEUlRFSEFKQVNPUlBWV0JaNEhPSUtDSCIsIm5hbWUiOiJvbWVnYSIsInN1YiI6IlVEWEIyVk1MWFBBU0FKN1pEVEtZTlE3UU9DRldTR0I0Rk9NWVFRMjVIUVdTQUY3WlFKRUJTUVNXIiwidHlwZSI6InVzZXIiLCJuYXRzIjp7InB1YiI6e30sInN1YiI6e319fQ.6TQ2ilCDb6m2ZDiJuj_D_OePGXFyN3Ap2DEm3ipcU5AhrWrNvneJryWrpgi_yuVWKo1UoD5s8bxlmwypWVGFAA
------END NATS USER JWT------
************************* IMPORTANT *************************
NKEY Seed printed below can be used to sign and prove identity.
NKEYs are sensitive and should be treated as secrets.
-----BEGIN USER NKEY SEED-----
SUAOY5JZ2WJKVR4UO2KJ2P3SW6FZFNWEOIMAXF4WZEUNVQXXUOKGM55CYE
------END USER NKEY SEED------
*************************************************************
```
Given a creds file, a client can authenticate as a specific user belonging to a specific account:
!INCLUDE "../../_examples/connect_creds.html"

View File

@@ -1,5 +0,0 @@
# Securing Connections
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 to 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 system, bind to an account, and to require TLS.

View File

@@ -1,7 +0,0 @@
# Authenticating with an NKey
The 2.0 version of NATS server introduces a new challenge response authentication option. This challenge response is based on a wrapper we call NKeys which uses [Ed25519](https://ed25519.cr.yp.to/) signing. The server can use these keys in several ways for authentication. The simplest is for the server to be configured with a list of known public keys and for the clients to respond to the challenge by signing it with its private key. This challenge-response ensures security by ensuring that the client has the private key, but also protects the private key from the server which never has to actually see it.
Handling challenge response may require more than just a setting in the connection options, depending on the client library.
!INCLUDE "../../_examples/connect_nkey.html"

View File

@@ -1,24 +0,0 @@
# Encrypting Connections with 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.
```sh
> nats-server -c /src/main/resources/tls.conf
or
> nats-server -c /src/main/resources/tls_verify.conf
```
## Connecting with TLS
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"
## Connecting with the TLS Protocol
Some clients may support the `tls` protocol as well as a manual setting to turn on TLS. However, in that case there is likely some form of default or environmental settings to allow the TLS libraries to find certificate and trust stores.
!INCLUDE "../../_examples/connect_tls_url.html"

View File

@@ -1,26 +0,0 @@
# Authenticating with a Token
Tokens are basically random strings, much like a password, and can provide a simple authentication mechanism in some situations. However, tokens are only as safe as they are secret so other authentication schemes can provide more security in large installations.
For this example, start the server using:
```sh
> nats-server --auth mytoken
```
The code uses localhost:4222 so that you can start the server on your machine to try them out.
## Connecting with a Token
!INCLUDE "../../_examples/connect_token.html"
## Connecting with a Token in the URL
Some client libraries will allow you to pass the token as part of the server URL using the form:
> nats://_token_@server:port
Again, once you construct this URL you can connect as if this was a normal URL.
!INCLUDE "../../_examples/connect_token_url.html"

View File

@@ -1,35 +0,0 @@
# Authenticating with a User and Password
For this example, start the server using:
```sh
> nats-server --user myname --pass password
```
You can encrypt passwords to pass to `nats-server` using a simple tool provided by the server:
```sh
> go run mkpasswd.go -p
> password: password
> bcrypt hash: $2a$11$1oJy/wZYNTxr9jNwMNwS3eUGhBpHT3On8CL9o7ey89mpgo88VG6ba
```
and use the hashed password in the server config. The client still uses the plain text version.
The code uses localhost:4222 so that you can start the server on your machine to try them out.
## Connecting with a User/Password
When logging in with a password `nats-server` will take either a plain text password or an encrypted password.
!INCLUDE "../../_examples/connect_userpass.html"
## Connecting with a User/Password in the URL
Most clients make it easy to pass the user name and password by accepting them in the URL for the server. This standard format is:
> nats://_user_:_password_@server:port
Using this format, you can connect to a server using authentication as easily as you connected with a URL:
!INCLUDE "../../_examples/connect_userpass_url.html"

View File

@@ -1,13 +0,0 @@
# Caches, Flush and Ping
For performance reasons, most if not all, of the client libraries will cache outgoing data so that bigger chunks can be written to the network at one time. This may be as simple as a byte buffer that stores up a few messages before being pushed to the network.
These buffers do not hold messages forever, generally they are designed to hold messages in high throughput scenarios, while still providing good latency in low throughput situations.
It is the libraries job to make sure messages flow in a high performance manner. But there may be times when an application needs to know that a message has "hit the wire." In this case, applications can use a flush call to tell the library to move data through the system.
!INCLUDE "../../_examples/flush.html"
## Flush and Ping/Pong
Many of the client libraries use the PING/PONG interaction built into the NATS protocol to insure that flush pushed all of the cached messages to the server. When an application calls flush most libraries will put a PING on the outgoing queue of messages, and wait for the server to send PONG before saying that the flush was successful.

View File

@@ -1,7 +0,0 @@
# Sending Messages
NATS sends and receives messages using a protocol that includes a target subject, an optional reply subject and an array of bytes. Some libraries may provide helpers to convert other data formats to and from bytes, but the NATS server will treat all messages as opaque byte arrays.
All of the NATS clients are designed to make sending a message simple. For example, to send the string “All is Well” to the “updates” subject as a UTF-8 string of bytes you would do:
!INCLUDE "../../_examples/publish_bytes.html"

View File

@@ -1,5 +0,0 @@
# 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 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,94 +0,0 @@
# Request-Reply
The pattern of sending a message and receiving a response is encapsulated in most client libraries into a request method. Under the covers this method will publish a message with a unique reply-to subject and wait for the response before returning.
In the older versions of some libraries a completely new reply-to subject is created each time. In newer versions, a subject hierarchy is used so that a single subscriber in the client library listens for a wildcard, and requests are sent with a unique child subject of a single subject.
The primary difference between the request method and publishing with a reply-to is that the library is only going to accept one response, and in most libraries the request will be treated as a synchronous action. The library may even provide a way to set the timeout.
For example, updating the previous publish example we may request `time` with a one second timeout:
!INCLUDE "../../_examples/request_reply.html"
You can think of request-reply in the library as a subscribe, get one message, unsubscribe pattern. In Go this might look something like:
```go
sub, err := nc.SubscribeSync(replyTo)
if err != nil {
log.Fatal(err)
}
nc.Flush()
// Send the request
nc.PublishRequest(subject, replyTo, []byte(input))
// Wait for a single response
for {
msg, err := sub.NextMsg(1 * time.Second)
if err != nil {
log.Fatal(err)
}
response = string(msg.Data)
break
}
sub.Unsubscribe()
```
## Scatter-Gather
You can expand the request-reply pattern into something often called scatter-gather. To receive multiple messages, with a timeout, you could do something like the following, where the loop getting messages is using time as the limitation, not the receipt of a single message:
```go
sub, err := nc.SubscribeSync(replyTo)
if err != nil {
log.Fatal(err)
}
nc.Flush()
// Send the request
nc.PublishRequest(subject, replyTo, []byte(input))
// Wait for a single response
max := 100 * time.Millisecond
start := time.Now()
for time.Now().Sub(start) < max {
msg, err := sub.NextMsg(1 * time.Second)
if err != nil {
break
}
responses = append(responses, string(msg.Data))
}
sub.Unsubscribe()
```
Or, you can loop on a counter and a timeout to try to get _at least N_ responses:
```go
sub, err := nc.SubscribeSync(replyTo)
if err != nil {
log.Fatal(err)
}
nc.Flush()
// Send the request
nc.PublishRequest(subject, replyTo, []byte(input))
// Wait for a single response
max := 500 * time.Millisecond
start := time.Now()
for time.Now().Sub(start) < max {
msg, err := sub.NextMsg(1 * time.Second)
if err != nil {
break
}
responses = append(responses, string(msg.Data))
if len(responses) >= minResponses {
break
}
}
sub.Unsubscribe()
```

View File

@@ -1,7 +0,0 @@
# Sending Structured Data
Some client libraries provide helpers to send structured data while others depend on the application to perform any encoding and decoding and just take byte arrays for sending. The following example shows how to send JSON but this could easily be altered to send a protocol buffer, YAML or some other format. JSON is a text format so we also have to encode the string in most languages to bytes. We are using UTF-8, the JSON standard encoding.
Take a simple _stock ticker_ that sends the symbol and price of each stock:
!INCLUDE "../../_examples/publish_json.html"

View File

@@ -1,124 +0,0 @@
# NATS Streaming
## Deciding to Use At-Least-Once Delivery
The decision to use the at least once delivery through NATS streaming is
important. It will affect your deployment, usage, performance, and total
cost of ownership.
In modern systems applications can expose services or produce and consume data
streams. At a high level, if observability is required, applications need to
consume messages in the future, need to come consume at their own pace, or
need all messages, then at-least-once semantics (NATS streaming) makes sense. If
observation needs to be realtime and the most recent message is the most important,
the use _At-Most-Once_ delivery semantics with core NATS.
Just be aware that using an a least once guarantee is the facet of messaging with the highest cost in terms of compute and storage. The NATS Maintainers highly recommend
a strategy of defaulting to core NATS using a service pattern (request/reply)
to guarantee delivery at the application level and using streaming only when necessary. This ultimately results in a more stable distributed system. Entire systems such as Cloud
Foundry have been built upon core NATS with no messaging persistence involved.
### When to use NATS Streaming
NATS streaming is ideal when:
* A historical record of a stream is required. This is when a replay of data
is required by a consumer.
* The last message produced on a stream is required for initialization and
the producer may be offline.
* A-priori knowledge of consumers is not available, but consumers must receive
messages. This is often a false assumption.
* Data producers and consumers are highly decoupled. They may be online at
different times and consumers must receive messages.
* The data in messages being sent have a lifespan beyond that of the
intended application lifespan.
* Applications need to consume data at their own pace.
Note that no assumptions should ever be made of who will receive and process
data in the future, or for what purpose.
### When to use Core NATS
Using core NATS is ideal for the fast request path for scalable services
where there is tolerance for message loss or when applications themselves handle
message delivery guarantees.
These include:
* Service patterns where there is a tightly coupled request/reply
* A request is made, and the application handles error cases upon timeout
(resends, errors, etc). __Relying on a messaging system to resend here is
considered an anti-pattern.__
* Where only the last message received is important and new messages will
be received frequently enough for applications to tolerate a lost message.
This might be a stock ticker stream, frequent exchange of messages in a
service control plane, or device telemetry.
* Message TTL is low, where the value of the data being transmitted degrades
or expires quickly.
* The expected consumer set for a message is available a-priori and consumers
are expected to be live. The request/reply pattern works well here or
consumers can send an application level acknowledgement.
We've found that core NATS is sufficient for most use cases. Also note
that nothing precludes the use of both core NATS and NATS streaming side
by side, leveraging the strengths of each to build a highly resilient
distributed system.
## NATS Streaming Overview
Where NATS provides at most once quality of service, streaming adds at least once. Streaming is implemented as a request-reply service on top of NATS. Streaming messages are encoded as protocol buffers, the streaming clients use NATS to talk to the streaming server. The streaming server organizes messages in channels and stores them in files and databases. ACKs are used to ensure delivery in both directions.
> Sometimes the maintainers will refer to NATS as "nats core" and streaming as "stan" or "streaming".
Messages to the streaming service are opaque byte arrays, just as they are with NATS. However, the streaming server protocol uses protocol buffers to wrap these byte arrays. So if you listen to the NATS traffic the messages will appear as protocol buffers, while the actual data sent and received will simply be byte arrays.
NATS streaming uses the concept of a channel to represent an ordered collection of messages. Clients send to and receive from channels instead of subjects. The subjects used by the streaming libraries and server are managed internally. Channels do not currently support wildcards. Channels arent raw subjects. Streaming isnt raw NATS. The streaming libraries hide some of the differences.
Think of channels as a First In First Out (FIFO) queue. Messages are added until the configured limit is reached. Old messages can be set to expire based on configuration, making room for new messages. Subscriptions dont affect channel content, that is, when a message is acknowledged, it is not removed from the channel.
Positions in the channel are specified in multiple ways:
* Sequence number - counting from 1
* Time
* Time delta (converted to time on client)
New subscriptions can also specify last received to indicate they only want new messages. Sequence numbers are persistent so when message #1 goes away, the oldest message is then message #2. If you try to go to a position before the oldest message, you will be moved to the oldest message.
## Subscription Types
NATS Streaming supports several types of subscriptions:
* Regular
* Durable
* Queue
* Durable/Queue
Regular subscriptions pick the location of their channel position on creation and it is stored while the subscriber is active. Durable subscriptions store their position in the streaming server. Queue subscriptions share a channel position. Durable/Queue subscriptions share a channel position stored in the server. All subscriptions can be configured with a starting position, but only new durable subscriptions and new regular subscriptions respect the request.
All subscriptions define their position on creation. Regular subscriptions lose their position if the application crashes, the app disconnects or they unsubscribe. Durable subscriptions maintain their position through disconnect, subscriber close, but not through unsubscribe. The position on reconnect comes from the server not the options in both cases. Queue subscriptions share a position. Regular queue subscriptions lose their position on the last disconnect/unsubscribe. Durable queue subscriptions maintain their position through disconnect, but not through the last unsubscribe. Positions provided in options are ignored after the position is set.
## Acknowledgements
In order to implement at least once delivery NATS streaming uses ACK messages for publishers and subscribers. Each message sent from the streaming server to the client must be acknowledged or it will be re-delivered. Developers must switch their mind set. The same message can arrive more than once. Messages should be idempotent. The client libraries can help with ACKs. Subscriptions can use manual or automatic ACKs. Manual ACKs are safer, since the program controls when they happen. An ACK wait setting is used to define the timeout before an ACK is considered missing.
> Ack wait = 10s means that the server wont redeliver for at least 10s
Using ACKs for each message sent can be a performance hit - round trip per message. NATS streaming allows subscriptions to set a max in flight value. Max in flight determines how many unacknowledged messages can be sent to the client. Ack Wait is used to decide when the ACK for a message has failed and it needs to be redelivered. New and redelivered messages are sent upon availability, in order.
Messages are sent in order, when they are available:
* Max inflight = 2
* Send msg 1 and msg 2
* ACK 2
* Message 3 arrives at the server
* Send message 3 (since it is available)
* When Ack wait expires, msg 1 is available
* Send msg 1 (1 and 3 are in flight)
The streaming server sends available messages in order, but 1 isnt available until its Ack wait expires. If max in flight = 1 then only 1 message is on the wire at a time, it will be re-sent until it is acknowledged. Re-delivered messages will not come out of order in this situation.
Setting max in flight to a number greater than 1 requires some thought and foresight to deal with redelivery scenarios.
Max in flight is a per-subscription setting. In the case of queue subscribers, each client can set the value. Normally, each client will use the same value but this is not a requirement.
NATS streaming uses acknowledgements on the sending side as well as the subscribing side. The streaming server acknowledges messages it receives and has persisted. A maximum in flight setting is used for publishers. No more than max in flight can be on their way to the server at one time. The library may provide various mechanisms to handle publisher ACKs. **The application must manage redelivery to the server**.

View File

@@ -1,25 +0,0 @@
# Acknowledgements
Subscribers can use auto-ack or manual-ack. Auto-ack is the default for most clients and is sent by the library when the message callback returns. Manual ack provides more control. The subscription options provide flags to:
* Set manual acks to true
* Set the ack wait used by the server for messages to this subscription
The ack wait is the time the server will wait before resending a message.
```go
sub, err := sc.Subscribe("foo",
func(m *stan.Msg) {
m.Ack()
}, stan.SetManualAckMode(), stan.AckWait(aw))
```
# Max In Flight
Subscribers can set max in flight to rate limit incoming messages. The server will send at most “max in flight” messages before receiving an acknowledgement. Setting max in flight to 1 insures every message is processed in order.
```go
sc.Subscribe("foo", func(m *stan.Msg) {...},
stan.SetManualAckMode(),
stan.MaxInflight(25))
```

View File

@@ -1,26 +0,0 @@
# Connecting to NATS Streaming
First, it is recommended to understand the relation between Streaming and core NATS. You should familiarize yourself with the [concept](/nats_streaming/relation-to-nats.md).
NATS Streaming is a service on top of NATS. To connect to the service you first connect to NATS and then use the client library to communicate with the server over your NATS connection. Most of the libraries provide a convenience mechanism for connecting in a single step. These convenience methods will take some NATS options, like the cluster ID, and perform the NATS connection first, then run the protocol to connect to the streaming server.
Connecting to a streaming server requires a cluster id, defined by the server configuration, and a client ID defined by the client.
*Client ID should contain only alphanumeric characters, `-` or `_`*
Connecting to a server running locally on the default port is as simple as this:
```go
sc, err := stan.Connect(clusterID, clientID)
```
If the server runs on port `1234`:
```go
sc, err := stan.Connect(clusterID, clientID, stan.NatsURL(nats://localhost:1234))
```
Sometimes you may want to provide NATS settings that aren't available in the streaming libraries connect method. Or, you may want to reuse a NATS connection instead of creating a new one. In this case the libraries generally provide a way to connect to streaming with an existing NATS connection:
```go
sc, err := stan.Connect(clusterID, clientID, stan.NatsConn(nc))
```

View File

@@ -1,13 +0,0 @@
# Durable Subscriptions
Regular subscriptions remember their position while the client is connected. If the client disconnects the position is lost. Durable subscriptions remember their position even if the client is disconnected.
Durable subscriptions identify themselves with a name. Connect and disconnect wont affect the durable subscriptions position in the channel.
```go
sc.Subscribe("foo", func(m *stan.Msg) {...}, stan.DurableName("my-durable"))
```
Unsubscribe will cause the server to completely remove the durable subscription.
Check the [concepts](/nats_streaming/channels/subscriptions/durable.md) section for more information.

View File

@@ -1,111 +0,0 @@
# Embedding NATS Streaming
Embedding a NATS Streaming Server in your own code is easy. Simply import:
```
stand "github.com/nats-io/nats-streaming-server/server"
```
(Note: we chose `stand` here, but you don't have to use that name)
Then if you want to use default options, it is as simple as doing:
```
s, err := stand.RunServer("mystreamingserver")
```
If you want a more advance configuration, then you need to pass options. For instance, let's start the server with a file store instead of memory.
First import the stores package so we have access to the store type.
```
stores "github.com/nats-io/nats-streaming-server/stores"
```
Then get the default options and override some of them:
```
opts := stand.GetDefaultOptions()
opts.StoreType = stores.TypeFile
opts.FilestoreDir = "datastore"
s, err := stand.RunServerWithOpts(opts, nil)
```
However, since the NATS Streaming Server project vendors NATS Server that is uses as the communication layer with its clients and other servers in the cluster, there are some limitations.
If you were to import `github.com/nats-io/nats-server/server`, instantiate a NATS `Options` structure, configure it and pass it to the second argument of `RunServerWithOpts`, you would get a compiler error. For instance doing this does not work:
```
import (
natsd "github.com/nats-io/nats-server/server"
stand "github.com/nats-io/nats-streaming-server/server"
stores "github.com/nats-io/nats-streaming-server/stores"
)
(...)
nopts := &natsd.Options{}
nopts.Port = 4223
s, err := stand.RunServerWithOpts(nil, nopts)
```
You would get:
```
./myapp.go:36:35: cannot use nopts (type *"myapp/vendor/github.com/nats-io/nats-server/server".Options) as type *"myapp/vendor/github.com/nats-io/nats-streaming-server/vendor/github.com/nats-io/gnatsd/server".Options in argument to "myapp/vendor/github.com/nats-io/nats-streaming-server/server".RunServerWithOpts
```
To workaround this issue, the NATS Streaming Server package provides a function `NewNATSOptions()` that is suitable for this approach:
```
nopts := stand.NewNATSOptions()
nopts.Port = 4223
s, err := stand.RunServerWithOpts(nil, nopts)
```
That will work.
But, if you want to do advanced NATS configuration that requires types or interfaces that belong to the NATS Server package, then this approach won't work. In this case, you need to run the NATS Server independently and have the NATS Streaming Server connect to it.
```
// This configure the NATS Server using natsd package
nopts := &natsd.Options{}
nopts.HTTPPort = 8222
nopts.Port = 4223
// Setting a customer client authentication requires the NATS Server Authentication interface.
nopts.CustomClientAuthentication = &myCustomClientAuth{}
// Create the NATS Server
ns := natsd.New(nopts)
// Start it as a go routine
go ns.Start()
// Wait for it to be able to accept connections
if !ns.ReadyForConnections(10 * time.Second) {
panic("not able to start")
}
// Get NATS Streaming Server default options
opts := stand.GetDefaultOptions()
// Point to the NATS Server with host/port used above
opts.NATSServerURL = "nats://localhost:4223"
// Now we want to setup the monitoring port for NATS Streaming.
// We still need NATS Options to do so, so create NATS Options
// using the NewNATSOptions() from the streaming server package.
snopts := stand.NewNATSOptions()
snopts.HTTPPort = 8223
// Now run the server with the streaming and streaming/nats options.
s, err := stand.RunServerWithOpts(opts, snopts)
if err != nil {
panic(err)
}
```
The above process may seem involved, but only if you use very advanced NATS Server options.

View File

@@ -1,265 +0,0 @@
# Writing your own client library
You can find a list of all supported client libraries [here](https://nats.io/download/). There are also links to community contributed clients.
In the event you would want to write your own NATS Streaming library, you could have a look at existing libraries to understand the flow. But you need to use [Google Protocol Buffers](https://developers.google.com/protocol-buffers/) to exchange protocols between the client and the server.
## NATS Streaming Protocol
The NATS streaming protocol sits atop the core NATS protocol and uses [Google's Protocol Buffers](https://developers.google.com/protocol-buffers/). Protocol buffer messages are marshaled into bytes and published as NATS messages on specific subjects described below. In communicating with the NATS Streaming Server, the NATS request/reply pattern is used for all protocol messages that have a corresponding reply.
### NATS streaming protocol conventions
**Subject names**: Subject names, including reply subject (INBOX) names, are case-sensitive and must be non-empty alphanumeric strings with no embedded whitespace, and optionally token-delimited using the dot character (`.`), e.g.:
`FOO`, `BAR`, `foo.bar`, `foo.BAR`, `FOO.BAR` and `FOO.BAR.BAZ` are all valid subject names
`FOO. BAR`, `foo. .bar` and`foo..bar` are *not- valid subject names
**Wildcards**: NATS streaming does **not** support wildcards in subject subscriptions
**Protocol definition**: The fields of NATS streaming protocol messages are defined in the NATS streaming client [protocol file](https://github.com/nats-io/stan.go/blob/master/pb/protocol.proto).
### NATS streaming protocol messages
The following table briefly describes the NATS streaming protocol messages.
Click the name to see more detailed information, including usage:
#### Protocols
| Message Name | Sent By | Description
| ------------------------------------------------- |:--------|:--------------------------------------------
| [`ConnectRequest`](#connectrequest) | Client | Request to connect to the NATS Streaming Server
| [`ConnectResponse`](#connectresponse) | Server | Result of a connection request
| [`SubscriptionRequest`](#subscriptionrequest) | Client | Request sent to subscribe and retrieve data
| [`SubscriptionResponse`](#subscriptionresponse) | Server | Result of a subscription request
| [`UnsubscribeRequest`](#unsubscriberequest) | Client | Unsubscribe from a subject
| [`PubMsg`](#pubmsg) | Client | Publish a message to a subject
| [`PubAck`](#puback) | Server | An acknowledgement that a published message has been processed on the server
| [`MsgProto`](#msgproto) | Server | A message from the NATS Streaming Server to a subscribing client
| [`Ack`](#ack) | Client | Acknowledges that a message has been received
| [`Ping`](#ping) | Client | Ping sent to server to detect connection loss
| [`PingResponse`](#pingresponse) | Server | Result of a Ping
| [`CloseRequest`](#closerequest) | Client | Request sent to close the connection to the NATS Streaming Server
| [`CloseResp`](#closeresponse) | Server | Result of the close request
The following sections explain each protocol message.
#### ConnectRequest
##### Description
A connection request is sent when a streaming client connects to the NATS Streaming Server. The connection request contains a unique identifier representing the client, and an inbox subject the client will listen on for incoming heartbeats. The identifier **must** be unique; a connection attempt with an identifier currently in use will fail. The inbox subject is the subject where the client receives incoming heartbeats, and responds by publishing an empty NATS message to the reply subject, indicating it is alive. The NATS Streaming Server will return a [ConnectResponse](#connectresponse) message to the reply subject specified in the NATS request message.
More advanced libraries can set the protocol to 1 and send a connection ID which in combination with ping interval and ping max out allows the library to detect that the connection to the server is lost.
This request is published to a subject comprised of the `<discover-prefix>.cluster-id`. For example, if a NATS Streaming Server was started with a cluster-id of `mycluster`, and the default prefix was used, the client publishes to `_STAN.discover.mycluster`
##### Message Structure
- `clientID`: A unique identifier for a client
- `heartbeatInbox`: An inbox to which the NATS Streaming Server will send heartbeats for the client to process
- `protocol`: Protocol the client is at
- `connID`: Connection ID, a way to uniquely identify a connection (no connection should ever have the same)
- `pingInterval`: Interval at which client wishes to send PINGs (expressed in seconds)
- `pingMaxOut`: Maximum number of PINGs without a response after which the connection can be considered lost
[Back to table](#protocols)
#### ConnectResponse
##### Description
After a `ConnectRequest` is published, the NATS Streaming Server responds with this message on the reply subject of the underlying NATS request. The NATS Streaming Server requires the client to make requests and publish messages on certain subjects (described above), and when a connection is successful, the client saves the information returned to be used in sending other NATS streaming protocol messages. In the event the connection was not successful, an error is returned in the `error` field.
##### Message Structure
- `pubPrefix`: Prefix to use when publishing
- `subRequests`: Subject used for subscription requests
- `unsubRequests`: Subject used for unsubscribe requests
- `closeRequests`: Subject for closing a connection
- `error`: An error string, which will be empty/omitted upon success
- `subCloseRequests`: Subject to use for subscription close requests
- `pingRequests`: Subject to use for PING requests
- `pingInterval`: Interval at which client should send PINGs (expressed in seconds).
- `pingMaxOut`: Maximum number of PINGs without a response after which the connection can be considered lost
- `protocol`: Protocol version the server is at
- `publicKey`: Reserved for future use
[Back to table](#protocols)
#### SubscriptionRequest
##### Description
A `SubscriptionRequest` is published on the subject returned in the `subRequests` field of a [ConnectResponse](#connectresponse), and creates a subscription to a subject on the NATS Streaming Server. This will return a [SubscriptionResponse](#subscriptionresponse) message to the reply subject specified in the NATS protocol request message.
##### Message Structure
- `clientID`: Client ID originally provided in the [ConnectRequest](#connectrequest)
- `subject`: Formal subject to subscribe to, e.g. foo.bar
- `qGroup`: Optional queue group
- `inbox`: Inbox subject to deliver messages on
- `maxInFlight`: Maximum inflight messages without an acknowledgement allowed
- `ackWaitInSecs`: Timeout for receiving an acknowledgement from the client
- `durableName`: Optional durable name which survives client restarts
- `startPosition`: An enumerated type specifying the point in history to start replaying data
- `startSequence`: Optional start sequence number
- `startTimeDelta`: Optional start time
##### StartPosition enumeration
- `NewOnly`: Send only new messages
- `LastReceived`: Send only the last received message
- `TimeDeltaStart`: Send messages from duration specified in the `startTimeDelta` field.
- `SequenceStart`: Send messages starting from the sequence in the `startSequence` field.
- `First`: Send all available messages
[Back to table](#protocols)
#### SubscriptionResponse
##### Description
The `SubscriptionResponse` message is the response from the `SubscriptionRequest`. After a client has processed an incoming [MsgProto](#msgproto) message, it must send an acknowledgement to the `ackInbox` subject provided here.
##### Message Structure
- `ackInbox`: subject the client sends message acknowledgements to the NATS Streaming Server
- `error`: error string, empty/omitted if no error
[Back to table](#protocols)
#### UnsubscribeRequest
##### Description
The `UnsubscribeRequest` closes or unsubcribes the subscription from the specified subject. The inbox specified is the `inbox` returned from the NATS Streaming Server in the `SubscriptionResponse`. Depending on which subject this request is sent, the action will result in close (if sent to subject `subCloseRequests`) or unsubscribe (if sent to subject `unsubRequests`)
##### Message Structure
- `clientID`: Client ID originally provided in the [ConnectRequest](#connectrequest)
- `subject`: Subject for the subscription
- `inbox`: Inbox subject to identify subscription
- `durableName`: Optional durable name which survives client restarts
[Back to table](#protocols)
#### PubMsg
##### Description
The `PubMsg` protocol message is published from a client to the NATS Streaming Server. The GUID must be unique, and is returned in the [PubAck](#puback) message to correlate the success or failure of storing this particular message.
##### Message Structure
- `clientID`: Client ID originally provided in the [ConnectRequest](#connectrequest)
- `guid`: a guid generated for this particular message
- `subject`: subject
- `data`: payload
- `connID`: Connection ID. For servers that know about this field, clientID can be omitted
[Back to table](#protocols)
#### PubAck
##### Description
The `PubAck` message is an acknowledgement from the NATS Streaming Server that a message has been processed. The message arrives on the subject specified on the reply subject of the NATS message the `PubMsg` was published on. The GUID is the same GUID used in the `PubMsg` being acknowledged. If an error string is present, the message was not persisted by the NATS Streaming Server and no guarantees regarding persistence are honored. `PubAck` messages may be handled asynchronously from their corresponding `PubMsg` in the client.
##### Message Structure
- `guid`: GUID of the message being acknowledged by the NATS Streaming Server
- `error`: An error string, empty/omitted if no error
[Back to table](#protocols)
#### MsgProto
##### Description
The `MsgProto` message is received by client from the NATS Streaming Server, containing the payload of messages sent by a publisher. A `MsgProto` message that is not acknowledged with an [Ack](#ack) message within the duration specified by the `ackWaitInSecs` field of the subscription request will be redelivered.
##### Message Structure
- `sequence`: Globally ordered sequence number for the subject's channel
- `subject`: Subject
- `data`: Payload
- `timestamp`: Time the message was stored in the server.
- `redelivered`: Flag specifying if the message is being redelivered
[Back to table](#protocols)
#### Ack
##### Description
An `Ack` message is an acknowledgement from the client that a [MsgProto](#msgproto) message has been considered received. It is published to the `ackInbox` field of the [SubscriptionResponse](#subscriptionresponse).
##### Message Structure
- `subject`: Subject of the message being acknowledged
- `sequence`: Sequence of the message being acknowledged
[Back to table](#protocols)
#### Ping
##### Description
A `Ping` message is sent to the server at configured interval to check that the connection ID is still valid. This should be used only if client is at protocol 1, and has sent a `connID` in the [ConnectRequest](#connectrequest) protocol.
##### Message Structure
- `connID`: The connection ID
[Back to table](#protocols)
#### PingResponse
##### Description
This is a response from the server to a `Ping` from the client. If the content is not empty, it will be the error indicating to the client why the connection is no longer valid.
##### Message Structure
- `error`: Error string, empty/omitted if no error
[Back to table](#protocols)
#### CloseRequest
##### Description
A `CloseRequest` message is published on the `closeRequests` subject from the [ConnectResponse](#connectresponse), and notifies the NATS Streaming Server that the client connection is closing, allowing the server to free up resources. This message should **always** be sent when a client is finished using a connection.
##### Message Structure
- `clientID`: Client ID originally provided in the [ConnectRequest](#connectrequest)
[Back to table](#protocols)
#### CloseResponse
##### Description
The `CloseResponse` is sent by the NATS Streaming Server on the reply subject of the `CloseRequest` NATS message. This response contains any error that may have occurred with the corresponding close call.
##### Message Structure
- `error`: error string, empty/omitted if no error
[Back to table](#protocols)

View File

@@ -1,21 +0,0 @@
# Publishing to a Channel
The streaming client library can provide a method for publishing synchronously. These publish methods block until the ACK is returned by the server. An error or exception is used to indicate a timeout or other error.
```go
err := sc.Publish("foo", []byte("Hello World"))
```
Streaming libraries can also provide a way to publish asynchronously. An ACK callback of some kind is required. The library will publish the message and notify the callback on ACK or timeout. The global id associated with the message being sent is returned from publish so that the application can identify it on callback.
```go
ackHandler := func(ackedNuid string, err error){ ... }
nuid, err := sc.PublishAsync("foo", []byte("Hello World"), ackHandler)
```
Even in this mode, the call will still block if the library has a number of published messages without having received an ACK from the server. The default can be changed when creating the connection.
```go
sc, err := sc.Connect(clusterID, clientName, stan.MaxPubAcksInflight(1000))
```

View File

@@ -1,37 +0,0 @@
# Queue Subscriptions in NATS Streaming
Queue subscriptions are created like other subscriptions with the addition of a queue name.
```go
qsub1, _ := sc.QueueSubscribe(channelName,
queueName, func(m *stan.Msg) {...})
qsub2, _ := sc.QueueSubscribe(channelName,
queueName, func(m *stan.Msg) {...})
```
Multiple subscriptions using the same channel and queue name are members of the same queue group. That means that if a message is published on that channel, only one member of the group receives the message. Other subscriptions receive messages independently of the queue groups, that is, a message is delivered to all subscriptions and one member of each queue group.
To create a durable queue subscription, simply add a durable name:
```go
qsub, err := sc.QueueSubscribe(channelName,
queueName, func(m *stan.Msg) {...},
stan.DurableName("durable-name"))
```
Subscriptions options apply to each member independently, notably, the `AckWait` and `MaxInflight`. Those two members of the same queue group use different options for redelivery and max inflight.
```go
qsub1, _ := sc.QueueSubscribe(channelName,
queueName, func(m *stan.Msg) {...},
stan.AckWait(5*time.Second),
stan.MaxInflight(5))
qsub2, _ := sc.QueueSubscribe(channelName,
queueName, func(m *stan.Msg) {...},
stan.AckWait(20*time.Second),
stan.MaxInflight(10))
```
If the queue subscription is durable, only the last member calling `Unsubscribe()` will cause the durable queue group to be removed from the server.
Check the [concepts](/nats_streaming/channels/subscriptions/queue-group.md) section for more information.

View File

@@ -1,72 +0,0 @@
# Receiving Messages from a Channel
Clients subscribe to channels by name. Wildcards are not supported. Receiving messages is similar to core NATS. Messages in streaming use protocol buffers and will have a bit more structure than NATS opaque messages. Client messages are still presented and accepted as raw/opaque binary data. The use of protocol buffers is transparent.
Subscriptions come in several forms:
* Regular
* Durable
* Queue
* Queue/Durable
For more details on the various types, check the [concepts](/nats_streaming/channels/subscriptions/subscriptions.md) section.
***Note: message callbacks are invoked serially, one message at a time. If your application does not care about processing ordering and would prefer the messages to be dispatched concurrently, it is the application's responsibility to move them to some internal queue to be picked up by threads/go routines.***
Subscriptions set their starting position on creation using position or time. For example, in Go you can start at:
* The last message received
```go
sub, err := sc.Subscribe("foo",
func(m *stan.Msg) {...},
stan.StartWithLastReceived())
```
* The beginning of the channel
```go
sub, err := sc.Subscribe("foo",
func(m *stan.Msg) {...},
stan.DeliverAllAvailable())
```
* A specific message, indexing starts at 1
```go
sub, err := sc.Subscribe("foo",
func(m *stan.Msg) {...},
stan.StartAtSequence(22))
```
* A specific time the message arrived in the channel
```go
var startTime time.Time
...
sub, err := sc.Subscribe("foo",
func(m *stan.Msg) {...},
stan.StartAtTime(startTime))
```
To set the delay after which the server should attempt to redeliver a message for which it has not received an acknowledgment:
```go
sub, err := sc.Subscribe("foo",
func(m *stan.Msg) {...},
stan.AckWait(20*time.Second))
```
When an application wishes to stop receiving, but wants to maintain the connection opened, the subscription should be closed. There are two ways to stop a subscription, either "close" it, or "unsubscribe" it. For non durable subscriptions, this is equivalent since the subscription will be completely removed. For durable subscriptions, close means that the server will stop delivering, but remember the durable subscription. Unsubscribe, however, means that the server will remove the state of this subscription.
To simply close:
```go
err := sub.Close()
```
To unsubscribe:
```go
err := sub.Unsubscribe()
```
_Note: If a connection is closed without explicitly closing the subscriptions, the subscriptions are implicitly closed, not unsubscribed._

View File

@@ -1,132 +0,0 @@
# Advanced Connect and Custom Dialer in Go
The Go NATS client features a [CustomDialer](https://godoc.org/github.com/nats-io/go-nats#CustomDialer) option which allows you to customize
the connection logic against the NATS server without having to modify the internals
of the client. For example, let's say that you want to make the client use the `context`
package to use `DialContext` and be able to cancel connecting to NATS altogether with a deadline,
you could then do define a Dialer implementation as follows:
```go
package main
import (
"context"
"log"
"net"
"time"
"github.com/nats-io/nats.go"
)
type customDialer struct {
ctx context.Context
nc *nats.Conn
connectTimeout time.Duration
connectTimeWait time.Duration
}
func (cd *customDialer) Dial(network, address string) (net.Conn, error) {
ctx, cancel := context.WithTimeout(cd.ctx, cd.connectTimeout)
defer cancel()
for {
log.Println("Attempting to connect to", address)
if ctx.Err() != nil {
return nil, ctx.Err()
}
select {
case <-cd.ctx.Done():
return nil, cd.ctx.Err()
default:
d := &net.Dialer{}
if conn, err := d.DialContext(ctx, network, address); err == nil {
log.Println("Connected to NATS successfully")
return conn, nil
} else {
time.Sleep(cd.connectTimeWait)
}
}
}
}
```
With the dialer implementation above, the NATS client will retry a number of times to connect
to the NATS server until the context is no longer valid:
```go
func main() {
// Parent context cancels connecting/reconnecting altogether.
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
var err error
var nc *nats.Conn
cd := &customDialer{
ctx: ctx,
connectTimeout: 10 * time.Second,
connectTimeWait: 1 * time.Second,
}
opts := []nats.Option{
nats.SetCustomDialer(cd),
nats.ReconnectWait(2 * time.Second),
nats.ReconnectHandler(func(c *nats.Conn) {
log.Println("Reconnected to", c.ConnectedUrl())
}),
nats.DisconnectHandler(func(c *nats.Conn) {
log.Println("Disconnected from NATS")
}),
nats.ClosedHandler(func(c *nats.Conn) {
log.Println("NATS connection is closed.")
}),
nats.NoReconnect(),
}
go func() {
nc, err = nats.Connect("127.0.0.1:4222", opts...)
}()
WaitForEstablishedConnection:
for {
if err != nil {
log.Fatal(err)
}
// Wait for context to be canceled either by timeout
// or because of establishing a connection...
select {
case <-ctx.Done():
break WaitForEstablishedConnection
default:
}
if nc == nil || !nc.IsConnected() {
log.Println("Connection not ready")
time.Sleep(200 * time.Millisecond)
continue
}
break WaitForEstablishedConnection
}
if ctx.Err() != nil {
log.Fatal(ctx.Err())
}
for {
if nc.IsClosed() {
break
}
if err := nc.Publish("hello", []byte("world")); err != nil {
log.Println(err)
time.Sleep(1 * time.Second)
continue
}
log.Println("Published message")
time.Sleep(1 * time.Second)
}
// Disconnect and flush pending messages
if err := nc.Drain(); err != nil {
log.Println(err)
}
log.Println("Disconnected")
}
```

View File

@@ -1,8 +0,0 @@
# Tutorials
Tutorials are provided to give guidance on commonly used aspects of NATS.
* [Explore NATS Publish/Subscribe](pubsub.md)
* [Explore NATS Request/Reply](reqreply.md)
* [Explore NATS Queueing](queues.md)
* [Advanced Connect and Custom Dialer in Go](custom_dialer.md)

View File

@@ -1,153 +0,0 @@
# Explore NATS Pub/Sub
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.
![](/assets/images/pubsubtut.svg)
## Prerequisites
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
```sh
% nats-server
```
When the server starts successfully, you will see the following messages:
```sh
[1] 2019/31/05 15:18:22.301550 [INF] Starting nats-server version 2.0.0
[1] 2019/31/05 15:18:22.301762 [INF] Listening for client connections on 0.0.0.0:4222
[1] 2019/31/05 15:18:22.301769 [INF] nats-server is ready
```
The NATS server listens for client connections on TCP Port 4222.
### 2. Start a shell or command prompt session
You will use this session to run an example NATS client subscriber program.
### 3. CD to the Go client examples directory
```sh
% cd $GOPATH/src/github.com/nats-io/nats.go/examples
```
### 4. Run the client subscriber program
```sh
% go run nats-sub/main.go <subject>
```
Where `<subject>` is a subject to listen on. A valid subject is a string that is unique in the system.
For example:
```sh
% go run nats-sub/main.go msg.test
```
You should see the message: *Listening on [msg.test]*
### 5. Start another shell or command prompt session
You will use this session to run a NATS publisher client.
## 6. CD to the examples directory
```sh
% cd $GOPATH/src/github.com/nats-io/nats.go/examples
```
### 7. Publish a NATS message
```sh
% go run nats-pub/main.go <subject> <message>
```
Where `<subject>` is the subject name and `<message>` is the text to publish.
For example:
```sh
% go run nats-pub/main.go msg.test hello
```
or
```sh
% go run nats-pub/main.go msg.test "NATS MESSAGE"
```
### 8. Verify message publication and receipt
You should see that the publisher sends the message: *Published [msg.test] : 'NATS MESSAGE'*
And that the subscriber receives the message: *[#1] Received on [msg.test]: 'NATS MESSAGE'*
Note that if the receiver does not get the message, check that you are using the same subject name for the publisher and the subscriber.
### 9. Publish another message
```sh
% go run nats-pub/main.go msg.test "NATS MESSAGE 2"
```
You should see that the subscriber receive message 2. Note that the message count is incremented each time your subscribing client receives a message on that subject:
### 10. Start another shell or command prompt session
You will use this session to run a second NATS subscriber.
### 11. CD to the examples directory
```sh
% cd $GOPATH/src/github.com/nats-io/nats.go/examples
```
### 12. Subscribe to the message
```sh
% go run nats-sub/main.go msg.test
```
### 13. Publish another message using the publisher client
```sh
% go run nats-pub/main.go msg.test "NATS MESSAGE 3"
```
Verify that both subscribing clients receive the message.
### 14. Start another shell or command prompt session
You will use this session to run a third NATS subscriber.
### 15. CD to the examples directory
```sh
% cd $GOPATH/src/github.com/nats-io/nats.go/examples
```
### 16. Subscribe to a different message
```sh
% go run nats-sub/main.go msg.test.new
```
All the but last subscriber receives the message. Why? Because that subscriber is not listening on the message subject used by the publisher.
### 17. Update the last subscriber to use a wildcard
NATS supports the use of wildcard characters for message subscribers. You cannot publish a message using a wildcard subject.
Change the last subscriber the listen on msg.* and run it:
```sh
% go run nats-sub/main.go msg.*
```
### 18. Publish another message
This time, all three subscribing clients should receive the message.

View File

@@ -1,71 +0,0 @@
# Explore NATS Queueing
NATS supports a form of load balancing using queue groups. Subscribers register a queue group name. A single subscriber in the group is randomly selected to receive the message.
## Prerequisites
Go and the NATS server should be installed.
### 1. Start the NATS server
```sh
nats-server
```
### 2. Clone the repositories for each client examples
```sh
go get github.com/nats-io/nats.go
git clone https://github.com/nats-io/nats.js.git
git clone https://github.com/nats-io/nats.rb.git
```
### 3. Run the Go client subscriber with queue group name
```sh
cd $GOPATH/src/github.com/nats-io/nats.go/examples
go run nats-qsub/main.go foo my-queue
```
### 4. Install and run the Node client subscriber with queue group name
```sh
npm install nats
cd nats.js/examples
node node-sub --queue=my-queue foo
```
### 5. Install and run the Ruby client subscriber with queue group name
```sh
gem install nats
nats-queue foo my-queue &
```
### 6. Run another Go client subscriber *without* the queue group.
```sh
cd $GOPATH/src/github.com/nats-io/nats.go/examples
go run nats-sub/main.go foo
```
### 7. Publish a NATS message using the Go client
```sh
cd $GOPATH/src/github.com/nats-io/nats.go/examples
go run nats-pub/main.go foo "Hello NATS!"
```
### 8. Verify message publication and receipt
You should see that the publisher sends the message: *Published [foo] : 'Hello NATS!'*
You should see that only one of the my-queue group subscribers receives the message. In addition, the Go client subscriber not in the my-queue group should also receive the message.
### 9. Publish another message
```sh
go run nats-pub/main.go foo "Hello NATS Again!"
```
You should see that a different queue group subscriber receives the message this time, chosen at random among the 3 queue group members.

View File

@@ -1,41 +0,0 @@
# Explore NATS Request/Reply
NATS supports request/reply messaging. In this tutorial you explore how to exchange point-to-point messages using NATS.
## Prerequisites
Go and the NATS server should be installed.
### 1. Start the NATS server
```sh
% nats-server
```
### 2. Start two terminal sessions
You will use these sessions to run the NATS request and reply clients.
### 3. Change to the examples directory
```sh
% cd $GOPATH/src/github.com/nats-io/nats.go/examples
```
### 4. In one terminal, run the reply client listener
```sh
% go run nats-rply/main.go foo "this is my response"
```
You should see the message `Receiver is listening`, and that the NATS receiver client is listening on the "help.please" subject. The reply client acts as a receiver, listening for message requests. In NATS, the receiver is a subscriber.
### 5. In the other terminal, run the request client
```sh
% go run nats-req/main.go foo "request payload"
```
The NATS requestor client makes a request by sending the message "some message" on the “help.please” subject.
The NATS receiver client receives the message, formulates the reply ("OK, I CAN HELP!!!), and sends it to the inbox of the requester.