出于任何原因断开连接,大多数(如果不是全部)客户端库将重新连接到NATS系统。重新连接逻辑可能因库而异,因此请查看客户端库的文档。
通常,客户机将尝试通过connect调用中提供的url或NATS系统在早期连接期间提供的url,重新连接到它所知道的服务器。此功能允许NATS应用程序和NATS系统本身进行自我修复和重新配置,而无需其他配置或干预。该库可以有几个选项来帮助控制重新连接行为、通知重新连接状态和通知新服务器。
您可以使用连接选项禁用自动重新连接:
// 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
应用程序可以设置每台服务器的最大重新连接尝试次数。这包括提供给客户机连接调用的服务器,以及客户机通过另一台服务器发现的服务器。一旦重新连接到服务器的操作连续失败指定的次数,它将从连接列表中删除。成功重新连接到服务器后,客户端将重置服务器失败的重新连接尝试计数。如果服务器已从连接列表中删除,则可以在连接时重新发现它。这也有效地重置了连接尝试计数。如果客户端没有要重新连接的服务器,它将关闭连接并引发错误。
// 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
当服务器停机时,有一种可能的反模式称为惊群效应(Thundering Herd),所有客户端都试图立即重新连接,从而造成拒绝服务攻击。为了防止这种情况发生,大多数NATS客户机库会随机化它们试图连接到的服务器。如果仅使用一台服务器,此设置无效,但在群集、随机化或洗牌的情况下,将确保没有一台服务器承受客户端重新连接尝试的冲击。
但是,如果要禁用“连接”和“重新连接”的随机化过程,以便始终以相同的顺序检查服务器,则可以在大多数具有连接选项的库中执行此操作:
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
尝试一遍又一遍地连接到同一台服务器没有多大意义。为了防止这种抖动和浪费的重连,特别是在使用TLS时,库提供了等待设置。通常,客户机确保在两次尝试重新连接到同一服务器之间至少经过了一定的时间。具体实现取决于所使用的库。
此设置不仅可以防止浪费客户机资源,还可以在没有其他服务器可用时缓解惊群效应产生的情况。
// 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
因为reconnect被封装好了,所以许多库提供了一个事件侦听器,您可以使用它来接收重新连接事件的通知。对于发送大量消息的应用程序,此事件尤其重要。
// 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.DisconnectErrHandler(func(nc *nats.Conn, err error) {
// handle disconnect error event
}),
nats.ReconnectHandler(func(nc *nats.Conn) {
// handle reconnect event
}))
if err != nil {
log.Fatal(err)
}
defer nc.Close()
// Do something with the connection
NATS客户机库尽差不多都是即发即弃的(be fire and forget.)。您正在使用的库中可能包含的功能之一是在连接断开时缓冲传出消息的能力。
在短时间重新连接期间,客户端可以允许应用程序发布消息,因为服务器处于脱机状态,这些消息将缓存在客户端中。重新连接后,库将发送这些消息。当达到最大重新连接缓冲区时,客户端将不再发布消息,并返回错误。
请注意,虽然消息似乎已发送到应用程序,但它可能从未发送,因为连接从未重新生成。应用程序应该使用诸如确认之类的模式来确保交付。
对于支持此功能的客户端,可以使用字节、消息或两者来配置此缓冲区的大小。
// 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