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 for connect and re-connect, so that servers are always checked in the same order, you can do that in most libraries with a connection option:

Go
Java
JavaScript
Python
Ruby
TypeScript
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
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();
JavaScript
let nc = NATS.connect({
noRandomize: true,
servers: ["nats://127.0.0.1:4443",
"nats://demo.nats.io:4222"
]
});
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()
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
TypeScript
// will throw an exception if connection fails
let nc = await connect({
noRandomize: true,
servers: ["nats://127.0.0.1:4443",
"nats://demo.nats.io:4222"
]
});
nc.close();
Edit on GitHub