1
0
mirror of https://github.com/taigrr/nats.docs synced 2025-01-18 04:03:23 -08:00

Cleaned up developer doc

Proof'd everything and improved flow
Renamed advanced to events
Reordered sending/receiving
Added text type to languages for prism plugin
This commit is contained in:
Stephen Asbury 2019-05-16 13:06:37 -07:00
parent e02ebdf16e
commit cc850776b8
35 changed files with 230 additions and 74 deletions

View File

@ -70,12 +70,6 @@
* [Authenticating with a Token](developer/security/token.md)
* [Encrypting Connections with TLS](developer/security/tls.md)
* [Sending Messages](developer/sending/intro.md)
* [Including a Reply Subject](developer/sending/replyto.md)
* [Request-Reply Semantics](developer/sending/request_reply.md)
* [Caches, Flush and Ping](developer/sending/caches.md)
* [Sending Structured Data](developer/sending/structure.md)
* [Receiving Messages](developer/receiving/intro.md)
* [Synchronous Subscriptions](developer/receiving/sync.md)
* [Asynchronous Subscriptions](developer/receiving/async.md)
@ -87,10 +81,15 @@
* [Draining Messages Before Disconnect](developer/receiving/drain.md)
* [Structured Data](developer/receiving/structure.md)
* [Advanced Topics](developer/advanced/intro.md)
* [Getting the Connection Status](developer/advanced/server_status.md)
* [Listen for Connection Events](developer/advanced/events.md)
* [Slow Consumers](developer/advanced/slow.md)
* [Sending Messages](developer/sending/intro.md)
* [Including a Reply Subject](developer/sending/replyto.md)
* [Request-Reply Semantics](developer/sending/request_reply.md)
* [Caches, Flush and Ping](developer/sending/caches.md)
* [Sending Structured Data](developer/sending/structure.md)
* [Monitoring the Connection](developer/events/intro.md)
* [Listen for Connection Events](developer/events/events.md)
* [Slow Consumers](developer/events/slow.md)
* [Tutorials](developer/tutorials/intro.md)
* [Explore NATS Pub/Sub](developer/tutorials/pubsub.md)

View File

@ -11,7 +11,8 @@
"pluginsConfig": {
"prism": {
"lang": {
"ascii": "markup"
"ascii": "markup",
"text": "markup"
}
}
}

View File

@ -6,6 +6,8 @@ Before doing anything else, install the legacy command line for gitbook:
npm install -g gitbook-cli
```
Docs are available as separate items in https://github.com/GitbookIO/gitbook/tree/6efbb70c3298a9106cb2083648624fd1b7af51c0/docs. All of the links go to the new site so you have to poke around manually.
The build uses https://github.com/Bandwidth/gitbook-plugin-include-html to include html directly for code examples as well as the prism plugin, https://github.com/gaearon/gitbook-plugin-prism, to handle code highlighting. CSS for code highlighting seems to get mucked up sometimes if you don't use the default them, this is something to work on in the future. We are also using https://github.com/poojan/gitbook-plugin-toggle-chapters, tried https://github.com/rtCamp/gitbook-plugin-collapsible-menu but it messed up the HTML.
Icons for dev examples are from https://cdn.materialdesignicons.com/3.6.95/.

View File

@ -1,17 +0,0 @@
# Listen for Connection Events
While the 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,3 +0,0 @@
# Advanced Topics
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.

View File

@ -1,5 +0,0 @@
# Get the Connection Status
The client library may provide a mechanism to get the connection's current status.
!INCLUDE "../../_examples/connect_status.html"

View File

@ -1,6 +1,6 @@
# NATS Messaging Concepts
NATS messaging involves the electronic exchange of data among computer applications and provides a layer between the application and the underlying physical network. Application data is encoded as a message and sent by a publisher. The message is received, decoded, and processed by one or more subscribers. A subscriber can process a NATS message synchronously or asynchronously, depending on the client library used.
NATS messaging involves the electronic exchange of data among computer applications and provides a layer between the application and the underlying physical network. Application data is encoded as a message and sent by a publisher. The message is received, decoded, and processed by one or more subscribers. A subscriber can process a NATS message synchronously or asynchronously, depending on the client library used.
<div class="graphviz"><code data-viz="dot">
graph nats {

View File

@ -1,6 +1,6 @@
# Publish Subscribe
NATS implements a publish subscribe message distribution model as a 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. NATS and NATS Streaming combine to offer two qualities of service:
NATS implements a publish subscribe message distribution model as a 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). NATS and NATS Streaming combine to offer two qualities of service:
- **At Most Once Delivery (NATS w/TCP reliability)** - In the basic NATS platform, 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. NATS is a fire-and-forget messaging system. If you need higher levels of service, you can either use NATS Streaming, or build the additional reliability into your client(s) yourself.

View File

@ -4,7 +4,7 @@ NATS provides a load balancing feature called queue subscriptions. Using queue s
To create a queue subscription, subscribers register a queue name. All subscribers with the same queue name form the queue group. As messages on the registered subject are published, one member of the group is chosen randomly to receive the message. Although queue groups have multiple subscribers, each message is consumed by only one.
Queue subscribers can be asynchronous, in which case the message handler callback function processes the delivered message. Synchronous queue subscribers must build in logic to process the message. Queue subscribers are ideal for auto scaling as you can add or remove them anytime, without any configuration changes or restarting the server or clients.
Queue subscribers are ideal for auto scaling as you can add or remove them anytime, without any configuration changes or restarting the server or clients.
<div class="graphviz"><code data-viz="dot">
digraph nats_queues {

View File

@ -1,10 +1,10 @@
# Request Reply
NATS supports two flavors of request reply messaging: point-to-point or one-to-many. Point-to-point involves the fastest or first to respond. In a one-to-many exchange, you set a limit on the number of responses the requestor may receive.
NATS supports two flavors of request reply messaging: point-to-point or one-to-many. Point-to-point involves the fastest or first to respond. In a one-to-many exchange, you can set a limit on the number of responses the requestor may receive or use a timeout to limit on the speed of the response.
In a request-response exchange, publish request operation publishes a message with a reply subject expecting a response on that reply subject. You can request to automatically wait for a response inline.
In a request-response exchange the publish request operation publishes a message with a reply subject expecting a response on that reply subject. Many libraries allow you to use a function that will automatically wait for a response with a timeout. You can also handle that waiting process yourself.
The request creates an inbox and performs a request call with the inbox reply and returns the first reply received. This is optimized in the case of multiple responses.
The common pattern used by the libraries is that the request creates a unique inbox and performs a request call with the inbox reply and returns the first reply received. This is optimized in the case of multiple responses by ignoring later responses automatically.
<div class="graphviz"><code data-viz="dot">
digraph nats_request_reply {

View File

@ -7,6 +7,14 @@ When connecting to a cluster, there are a few things to think about.
* The reconnect algorithm (discussed later)
* Server provided URLs
When 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. However, the initial connection cannot depend on these additional servers. Rather, the additional connection will try to connect to each of the URLs provided in the connect call and will fail if it is unable to connect to any of them. *Note, failure behavior is library dependent, please check the documentation for your client library on information about what happens if the connect fails.*
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 +1,5 @@
# Setting a Connect Timeout
Each library has its own, language preferred way, to pass connection options. For example, to set the maximum time to connect to a server to 10 seconds:
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 +1,9 @@
# Connecting to NATS
Most client libraries provide several ways to connect to the NATS server, gnatsd recently updated to nats-server. The server itself is identified by a standard URL with the `nats` protocol. Throughout these examples we will rely on a test server, provided by [nats.io](https://nats.io), at `nats://demo.nats.io:4222`, where `4222` is the default port for NATS.
Most client libraries provide several ways to connect to the NATS server. The server itself is identified by a standard URL with the `nats` protocol. Throughout these examples we will rely on a test server, provided by [nats.io](https://nats.io), at `nats://demo.nats.io:4222`, where `4222` is the default port for NATS.
There are numerous options for a NATS connections.
NATS clients also support the `tls` protocol to indicate that the client wants to use TLS. So in the previous example we can replace `nats` with `tls` to get `tls://demo.nats.io:4222`.
The protocol requirement is being removed from many libraries, so that you can use `demo.nats.io:4222` as the URL and let the client and server resolve whether or not TLS is required.
There are numerous options for a NATS connections ranging from timeouts to reconnect settings.

View File

@ -4,7 +4,7 @@ The protocol between the client and the server is fairly simple and relies on a
## Set the Maximum Control Line Size
Some clients will try to limit the control line size on themselves 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.
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:

View File

@ -1,5 +1,9 @@
# Connecting to a Specific Server
For example, to connect to the demo server with a URL:
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

@ -0,0 +1,21 @@
# 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

@ -0,0 +1,7 @@
# 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,12 +1,14 @@
# 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. 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.
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/cache messages with something like NATS streaming
* 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.
@ -22,6 +24,8 @@ The first way that the incoming queue can be limited is by message count. The se
## 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.
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,5 +1,7 @@
# 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 by the library. Check your libraries documentation for any resource usage associated with asynchronous subscriptions. The following example is the same as the previous one only with asynchronous code:
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,6 +1,10 @@
# Draining Connections and Subscriptions
A new feature in 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. Which means the library will halt messages in any pending queue or cache for subscribers. When you drain a subscription or connection, it will process any cached/pending messages before closing.
A new feature being added across the NATS client libraries is the ability to drain connections or subscriptions. Closing a connection, or unsubscribing from a subscription are generally considered immediate requests. When you close or unsubscribe the library will halt messages in any pending queue or cache for subscribers. When you drain a subscription or connection, it will process any cached/pending messages before closing.
Drain provides clients that use queue subscriptions with a way to bring down applications without losing any messages. A client can bring up a new queue member, drain and shut down the old queue member, all without losing messages sent to the old client. Without drain, there is the possibility of lost messages due to queue timing.
The libraries can provide drain on a connection or on a subscriber, or both.
For a connection the process is essentially:
@ -9,9 +13,9 @@ For a connection the process is essentially:
3. Flush any remaining messages
4. Close
!INCLUDE "../../_examples/drain_conn.html"
As an example of draining a connection:
Drain provides clients that use queue subscriptions with a way to bring down applications without losing any messages. A client can bring up a new queue member, drain and shut down the old queue member, all without losing messages sent to the old client. Without drain, there is the possibility of lost messages due to queue timing.
!INCLUDE "../../_examples/drain_conn.html"
The mechanics of drain for a subscription are simpler:

View File

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

View File

@ -1,6 +1,8 @@
# Queue Subscriptions
Using queues, from a subscription standpoint, is super easy. The application simply includes a queue name with the subscription.
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.
<div class="graphviz"><code data-viz="dot">
digraph g {
@ -18,7 +20,7 @@ digraph g {
}
</code></div>
For example, to subscribe to the queue `workers` with the subject `updates`:
As an example, to subscribe to the queue `workers` with the subject `updates`:
!INCLUDE "../../_examples/subscribe_queue.html"

View File

@ -1,5 +1,7 @@
# 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. In the publishing examples we sent a request for the current time. The following code will listen for that request and respond with the time.
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,5 +1,7 @@
# Receiving Structured Data
In the publishing examples, we showed how to send JSON through NATS but you can receive encoded data as well. Each client library may provide tools to help with this encoding. The core traffic to the NATS server will always be byte arrays.
Client libraries may provide tools to help receive structured data, like JSON. The core traffic to the NATS server will always be byte arrays. For libraries that don't provide helpers, you can always encode and decode data before sending the associated bytes to the NATS client.
For example, to receive JSON you could do:
!INCLUDE "../../_examples/subscribe_json.html"

View File

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

View File

@ -1,10 +1,12 @@
# 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. There are a few important things to know about auto unsubscribe. First, 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. Or 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.
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.
Second, 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.
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.

View File

@ -1,5 +1,7 @@
# 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.
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,6 +1,8 @@
# Wildcards
There is no special code to subscribe with a wildcard subject. The main technique that may come in to play is to use the subject provided with the incoming message to determine what to do with the message.
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.

View File

@ -1,6 +1,12 @@
# Buffering Messages During Reconnect Attempts
There is another setting that comes in to play during reconnection. This setting controls how much memory the client library will hold in the form of outgoing messages while it is disconnected. During a short reconnect, the client will generally allow applications to publish messages but 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.
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 insure 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"

View File

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

View File

@ -2,4 +2,6 @@
When a server goes down, there is a possible anti-pattern called the *Thundering Herd* where all of the clients try to reconnect immediately 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 +1,5 @@
# 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 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.
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,9 +1,13 @@
# 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. 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.
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, in this case, the library 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.
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,5 +1,7 @@
# 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:
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,9 +1,94 @@
# 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 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.
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 provide a way to set the timeout. For example, updating the previous publish example we may request `time` with a one second timeout:
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 also build your own request-reply using publish-subscribe if you need a different semantic or timing.
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()
```