mirror of
https://github.com/taigrr/nats.docs
synced 2025-01-18 04:03:23 -08:00
fix folder structure from gitbook import
This commit is contained in:
8
developing-with-nats/reconnect/README.md
Normal file
8
developing-with-nats/reconnect/README.md
Normal file
@@ -0,0 +1,8 @@
|
||||
# Automatic Reconnections
|
||||
|
||||
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.
|
||||
|
||||
66
developing-with-nats/reconnect/buffer.md
Normal file
66
developing-with-nats/reconnect/buffer.md
Normal file
@@ -0,0 +1,66 @@
|
||||
# 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.
|
||||
|
||||
{% tabs %}
|
||||
{% tab title="Go" %}
|
||||
```go
|
||||
// Set reconnect buffer size in bytes (5 MB)
|
||||
nc, err := nats.Connect("demo.nats.io", nats.ReconnectBufSize(5*1024*1024))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer nc.Close()
|
||||
|
||||
// Do something with the connection
|
||||
```
|
||||
{% endtab %}
|
||||
|
||||
{% tab title="Java" %}
|
||||
```java
|
||||
Options options = new Options.Builder().
|
||||
server("nats://demo.nats.io:4222").
|
||||
reconnectBufferSize(5 * 1024 * 1024). // Set buffer in bytes
|
||||
build();
|
||||
Connection nc = Nats.connect(options);
|
||||
|
||||
// Do something with the connection
|
||||
|
||||
nc.close();
|
||||
```
|
||||
{% endtab %}
|
||||
|
||||
{% tab title="JavaScript" %}
|
||||
```javascript
|
||||
// Reconnect buffer size is not configurable on NATS Javascript client
|
||||
```
|
||||
{% endtab %}
|
||||
|
||||
{% tab title="Python" %}
|
||||
```python
|
||||
# Asyncio NATS client currently does not implement a reconnect buffer
|
||||
```
|
||||
{% endtab %}
|
||||
|
||||
{% tab title="Ruby" %}
|
||||
```ruby
|
||||
# There is currently no reconnect pending buffer as part of the Ruby NATS client
|
||||
```
|
||||
{% endtab %}
|
||||
|
||||
{% tab title="TypeScript" %}
|
||||
```typescript
|
||||
// Reconnect buffer size is not configurable on NATS Typescript client
|
||||
|
||||
```
|
||||
{% endtab %}
|
||||
{% endtabs %}
|
||||
|
||||
> _As mentioned throughout this document, each client library may behave slightly differently. Please check the documentation for the library you are using._
|
||||
|
||||
84
developing-with-nats/reconnect/disable.md
Normal file
84
developing-with-nats/reconnect/disable.md
Normal file
@@ -0,0 +1,84 @@
|
||||
# Disabling Reconnect
|
||||
|
||||
You can disable automatic reconnect with connection options:
|
||||
|
||||
{% tabs %}
|
||||
{% tab title="Go" %}
|
||||
```go
|
||||
// Disable reconnect attempts
|
||||
nc, err := nats.Connect("demo.nats.io", nats.NoReconnect())
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer nc.Close()
|
||||
|
||||
// Do something with the connection
|
||||
```
|
||||
{% endtab %}
|
||||
|
||||
{% tab title="Java" %}
|
||||
```java
|
||||
Options options = new Options.Builder().
|
||||
server("nats://demo.nats.io:4222").
|
||||
noReconnect(). // Disable reconnect attempts
|
||||
build();
|
||||
Connection nc = Nats.connect(options);
|
||||
|
||||
// Do something with the connection
|
||||
|
||||
nc.close();
|
||||
```
|
||||
{% endtab %}
|
||||
|
||||
{% tab title="JavaScript" %}
|
||||
```javascript
|
||||
llet nc = NATS.connect({
|
||||
reconnect: false,
|
||||
servers: ["nats://demo.nats.io:4222"]
|
||||
});
|
||||
```
|
||||
{% endtab %}
|
||||
|
||||
{% tab title="Python" %}
|
||||
```python
|
||||
nc = NATS()
|
||||
await nc.connect(
|
||||
servers=[
|
||||
"nats://demo.nats.io:1222",
|
||||
"nats://demo.nats.io:1223",
|
||||
"nats://demo.nats.io:1224"
|
||||
],
|
||||
allow_reconnect=False,
|
||||
)
|
||||
|
||||
# Do something with the connection
|
||||
|
||||
await nc.close()
|
||||
```
|
||||
{% endtab %}
|
||||
|
||||
{% tab title="Ruby" %}
|
||||
```ruby
|
||||
require 'nats/client'
|
||||
|
||||
NATS.start(servers: ["nats://127.0.0.1:1222", "nats://127.0.0.1:1223", "nats://127.0.0.1:1224"], reconnect: false) do |nc|
|
||||
# Do something with the connection
|
||||
|
||||
# Close the connection
|
||||
nc.close
|
||||
end
|
||||
```
|
||||
{% endtab %}
|
||||
|
||||
{% tab title="TypeScript" %}
|
||||
```typescript
|
||||
// will throw an exception if connection fails
|
||||
let nc = await connect({
|
||||
reconnect: false,
|
||||
servers: ["nats://demo.nats.io:4222"]
|
||||
});
|
||||
nc.close();
|
||||
```
|
||||
{% endtab %}
|
||||
{% endtabs %}
|
||||
|
||||
116
developing-with-nats/reconnect/events.md
Normal file
116
developing-with-nats/reconnect/events.md
Normal file
@@ -0,0 +1,116 @@
|
||||
# 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.
|
||||
|
||||
{% tabs %}
|
||||
{% tab title="Go" %}
|
||||
```go
|
||||
// Connection event handlers are invoked asynchronously
|
||||
// and the state of the connection may have changed when
|
||||
// the callback is invoked.
|
||||
nc, err := nats.Connect("demo.nats.io",
|
||||
nats.DisconnectHandler(func(nc *nats.Conn) {
|
||||
// handle disconnect event
|
||||
}),
|
||||
nats.ReconnectHandler(func(nc *nats.Conn) {
|
||||
// handle reconnect event
|
||||
}))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer nc.Close()
|
||||
|
||||
// Do something with the connection
|
||||
```
|
||||
{% endtab %}
|
||||
|
||||
{% tab title="Java" %}
|
||||
```java
|
||||
Options options = new Options.Builder().
|
||||
server("nats://demo.nats.io:4222").
|
||||
connectionListener((conn, type) -> {
|
||||
if (type == Events.RECONNECTED) {
|
||||
// handle reconnected
|
||||
} else if (type == Events.DISCONNECTED) {
|
||||
// handle disconnected, wait for reconnect
|
||||
}
|
||||
}).
|
||||
build();
|
||||
Connection nc = Nats.connect(options);
|
||||
|
||||
// Do something with the connection
|
||||
|
||||
nc.close();
|
||||
```
|
||||
{% endtab %}
|
||||
|
||||
{% tab title="JavaScript" %}
|
||||
```javascript
|
||||
let nc = NATS.connect({
|
||||
maxReconnectAttempts: 10,
|
||||
servers: ["nats://demo.nats.io:4222"]
|
||||
});
|
||||
|
||||
nc.on('reconnect', (c) => {
|
||||
console.log('reconnected');
|
||||
});
|
||||
```
|
||||
{% endtab %}
|
||||
|
||||
{% tab title="Python" %}
|
||||
```python
|
||||
nc = NATS()
|
||||
|
||||
async def disconnected_cb():
|
||||
print("Got disconnected!")
|
||||
|
||||
async def reconnected_cb():
|
||||
# See who we are connected to on reconnect.
|
||||
print("Got reconnected to {url}".format(url=nc.connected_url.netloc))
|
||||
|
||||
await nc.connect(
|
||||
servers=["nats://demo.nats.io:4222"],
|
||||
reconnect_time_wait=10,
|
||||
reconnected_cb=reconnected_cb,
|
||||
disconnected_cb=disconnected_cb,
|
||||
)
|
||||
|
||||
# Do something with the connection.
|
||||
```
|
||||
{% endtab %}
|
||||
|
||||
{% tab title="Ruby" %}
|
||||
```ruby
|
||||
require 'nats/client'
|
||||
|
||||
NATS.start(servers: ["nats://127.0.0.1:1222", "nats://127.0.0.1:1223", "nats://127.0.0.1:1224"]) do |nc|
|
||||
# Do something with the connection
|
||||
nc.on_reconnect do
|
||||
puts "Got reconnected to #{nc.connected_server}"
|
||||
end
|
||||
|
||||
nc.on_disconnect do |reason|
|
||||
puts "Got disconnected! #{reason}"
|
||||
end
|
||||
end
|
||||
```
|
||||
{% endtab %}
|
||||
|
||||
{% tab title="TypeScript" %}
|
||||
```typescript
|
||||
// will throw an exception if connection fails
|
||||
let nc = await connect({
|
||||
maxReconnectAttempts: 10,
|
||||
servers: ["nats://demo.nats.io:4222"]
|
||||
});
|
||||
// first argument is the connection (same as nc in this case)
|
||||
// second argument is the url of the server where the client
|
||||
// connected
|
||||
nc.on('reconnect', (conn, server) => {
|
||||
console.log('reconnected to', server);
|
||||
});
|
||||
nc.close();
|
||||
```
|
||||
{% endtab %}
|
||||
{% endtabs %}
|
||||
|
||||
80
developing-with-nats/reconnect/max.md
Normal file
80
developing-with-nats/reconnect/max.md
Normal file
@@ -0,0 +1,80 @@
|
||||
# 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.
|
||||
|
||||
{% tabs %}
|
||||
{% tab title="Go" %}
|
||||
```go
|
||||
// Set max reconnects attempts
|
||||
nc, err := nats.Connect("demo.nats.io", nats.MaxReconnects(10))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer nc.Close()
|
||||
|
||||
// Do something with the connection
|
||||
```
|
||||
{% endtab %}
|
||||
|
||||
{% tab title="Java" %}
|
||||
```java
|
||||
Options options = new Options.Builder().
|
||||
server("nats://demo.nats.io:4222").
|
||||
maxReconnects(10). // Set max reconnect attempts
|
||||
build();
|
||||
Connection nc = Nats.connect(options);
|
||||
|
||||
// Do something with the connection
|
||||
|
||||
nc.close();
|
||||
```
|
||||
{% endtab %}
|
||||
|
||||
{% tab title="JavaScript" %}
|
||||
```javascript
|
||||
let nc = NATS.connect({
|
||||
maxReconnectAttempts: 10,
|
||||
servers: ["nats://demo.nats.io:4222"]
|
||||
});
|
||||
```
|
||||
{% endtab %}
|
||||
|
||||
{% tab title="Python" %}
|
||||
```python
|
||||
nc = NATS()
|
||||
await nc.connect(
|
||||
servers=["nats://demo.nats.io:4222"],
|
||||
max_reconnect_attempts=10,
|
||||
)
|
||||
|
||||
# Do something with the connection
|
||||
|
||||
await nc.close()
|
||||
```
|
||||
{% endtab %}
|
||||
|
||||
{% tab title="Ruby" %}
|
||||
```ruby
|
||||
require 'nats/client'
|
||||
|
||||
NATS.start(servers: ["nats://127.0.0.1:1222", "nats://127.0.0.1:1223", "nats://127.0.0.1:1224"], max_reconnect_attempts: 10) do |nc|
|
||||
# Do something with the connection
|
||||
|
||||
# Close the connection
|
||||
nc.close
|
||||
end
|
||||
```
|
||||
{% endtab %}
|
||||
|
||||
{% tab title="TypeScript" %}
|
||||
```typescript
|
||||
// will throw an exception if connection fails
|
||||
let nc = await connect({
|
||||
maxReconnectAttempts: 10,
|
||||
servers: ["nats://demo.nats.io:4222"]
|
||||
});
|
||||
nc.close();
|
||||
```
|
||||
{% endtab %}
|
||||
{% endtabs %}
|
||||
|
||||
94
developing-with-nats/reconnect/random.md
Normal file
94
developing-with-nats/reconnect/random.md
Normal file
@@ -0,0 +1,94 @@
|
||||
# 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:
|
||||
|
||||
{% tabs %}
|
||||
{% tab title="Go" %}
|
||||
```go
|
||||
servers := []string{"nats://127.0.0.1:1222",
|
||||
"nats://127.0.0.1:1223",
|
||||
"nats://127.0.0.1:1224",
|
||||
}
|
||||
|
||||
nc, err := nats.Connect(strings.Join(servers, ","), nats.DontRandomize())
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer nc.Close()
|
||||
|
||||
// Do something with the connection
|
||||
```
|
||||
{% endtab %}
|
||||
|
||||
{% tab title="Java" %}
|
||||
```java
|
||||
Options options = new Options.Builder().
|
||||
server("nats://demo.nats.io:4222").
|
||||
noRandomize(). // Disable reconnect shuffle
|
||||
build();
|
||||
Connection nc = Nats.connect(options);
|
||||
|
||||
// Do something with the connection
|
||||
|
||||
nc.close();
|
||||
```
|
||||
{% endtab %}
|
||||
|
||||
{% tab title="JavaScript" %}
|
||||
```javascript
|
||||
let nc = NATS.connect({
|
||||
noRandomize: false,
|
||||
servers: ["nats://127.0.0.1:4443",
|
||||
"nats://demo.nats.io:4222"
|
||||
]
|
||||
});
|
||||
```
|
||||
{% endtab %}
|
||||
|
||||
{% tab title="Python" %}
|
||||
```python
|
||||
nc = NATS()
|
||||
await nc.connect(
|
||||
servers=[
|
||||
"nats://demo.nats.io:1222",
|
||||
"nats://demo.nats.io:1223",
|
||||
"nats://demo.nats.io:1224"
|
||||
],
|
||||
dont_randomize=True,
|
||||
)
|
||||
|
||||
# Do something with the connection
|
||||
|
||||
await nc.close()
|
||||
```
|
||||
{% endtab %}
|
||||
|
||||
{% tab title="Ruby" %}
|
||||
```ruby
|
||||
require 'nats/client'
|
||||
|
||||
NATS.start(servers: ["nats://127.0.0.1:1222", "nats://127.0.0.1:1223", "nats://127.0.0.1:1224"], dont_randomize_servers: true) do |nc|
|
||||
# Do something with the connection
|
||||
|
||||
# Close the connection
|
||||
nc.close
|
||||
end
|
||||
```
|
||||
{% endtab %}
|
||||
|
||||
{% tab title="TypeScript" %}
|
||||
```typescript
|
||||
// will throw an exception if connection fails
|
||||
let nc = await connect({
|
||||
noRandomize: false,
|
||||
servers: ["nats://127.0.0.1:4443",
|
||||
"nats://demo.nats.io:4222"
|
||||
]
|
||||
});
|
||||
nc.close();
|
||||
```
|
||||
{% endtab %}
|
||||
{% endtabs %}
|
||||
|
||||
80
developing-with-nats/reconnect/wait.md
Normal file
80
developing-with-nats/reconnect/wait.md
Normal file
@@ -0,0 +1,80 @@
|
||||
# Pausing Between Reconnect Attempts
|
||||
|
||||
It doesn’t 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 doesn’t 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.
|
||||
|
||||
{% tabs %}
|
||||
{% tab title="Go" %}
|
||||
```go
|
||||
// Set reconnect interval to 10 seconds
|
||||
nc, err := nats.Connect("demo.nats.io", nats.ReconnectWait(10*time.Second))
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer nc.Close()
|
||||
|
||||
// Do something with the connection
|
||||
```
|
||||
{% endtab %}
|
||||
|
||||
{% tab title="Java" %}
|
||||
```java
|
||||
Options options = new Options.Builder().
|
||||
server("nats://demo.nats.io:4222").
|
||||
reconnectWait(Duration.ofSeconds(10)). // Set Reconnect Wait
|
||||
build();
|
||||
Connection nc = Nats.connect(options);
|
||||
|
||||
// Do something with the connection
|
||||
|
||||
nc.close();
|
||||
```
|
||||
{% endtab %}
|
||||
|
||||
{% tab title="JavaScript" %}
|
||||
```javascript
|
||||
let nc = NATS.connect({
|
||||
reconnectTimeWait: 10 * 1000, //10s
|
||||
servers: ["nats://demo.nats.io:4222"]
|
||||
});
|
||||
```
|
||||
{% endtab %}
|
||||
|
||||
{% tab title="Python" %}
|
||||
```python
|
||||
nc = NATS()
|
||||
await nc.connect(
|
||||
servers=["nats://demo.nats.io:4222"],
|
||||
reconnect_time_wait=10,
|
||||
)
|
||||
|
||||
# Do something with the connection
|
||||
|
||||
await nc.close()
|
||||
```
|
||||
{% endtab %}
|
||||
|
||||
{% tab title="Ruby" %}
|
||||
```ruby
|
||||
require 'nats/client'
|
||||
|
||||
NATS.start(servers: ["nats://127.0.0.1:1222", "nats://127.0.0.1:1223", "nats://127.0.0.1:1224"], reconnect_time_wait: 10) do |nc|
|
||||
# Do something with the connection
|
||||
|
||||
# Close the connection
|
||||
nc.close
|
||||
end
|
||||
```
|
||||
{% endtab %}
|
||||
|
||||
{% tab title="TypeScript" %}
|
||||
```typescript
|
||||
// will throw an exception if connection fails
|
||||
let nc = await connect({
|
||||
reconnectTimeWait: 10*1000, //10s
|
||||
servers: ["nats://demo.nats.io:4222"]
|
||||
});
|
||||
nc.close();
|
||||
```
|
||||
{% endtab %}
|
||||
{% endtabs %}
|
||||
|
||||
Reference in New Issue
Block a user