NATS中文开发文档:监控连接

管理与服务器的交互主要是客户机库的工作,但大多数库也提供了一些对幕后发生的事情的了解。
例如,客户端库可以提供一种机制来获取连接的当前状态:

nc, err := nats.Connect("demo.nats.io", nats.Name("API Example"))
if err != nil {
    log.Fatal(err)
}
defer nc.Close()

getStatusTxt := func(nc *nats.Conn) string {
    switch nc.Status() {
    case nats.CONNECTED:
        return "Connected"
    case nats.CLOSED:
        return "Closed"
    default:
        return "Other"
    }
}
log.Printf("The connection is %v\n", getStatusTxt(nc))

nc.Close()

log.Printf("The connection is %v\n", getStatusTxt(nc))

监听连接事件

如果对连接状态感兴趣,很可能对了解状态何时更改也有兴趣。大多数(如果不是全部的话)NATS客户端库提供了一种方法来监听与连接及其状态相关的事件。
这些侦听器的实际API依赖于语言,但以下示例显示了一些更常见的用例。有关更具体的说明,请参阅正在使用的客户端库的API文档。
连接事件可能包括正在关闭、断开或重新连接的连接。重新连接涉及断开连接和连接,但根据库的实现,在客户端尝试查找服务器或服务器重新启动时,还可能包括多个断开连接。

// There is not a single listener for connection events in the NATS Go Client.
// Instead, you can set individual event handlers using:
nc, err := nats.Connect("demo.nats.io",
    nats.DisconnectErrHandler(func(_ *nats.Conn, err error) {
        log.Printf("client disconnected: %v", err)
    }),
    nats.ReconnectHandler(func(_ *nats.Conn) {
        log.Printf("client reconnected")
    }),
    nats.ClosedHandler(func(_ *nats.Conn) {
        log.Printf("client closed")
    }))
if err != nil {
    log.Fatal(err)
}
defer nc.Close()

DisconnectHandler(cb ConnHandler)
ReconnectHandler(cb ConnHandler)
ClosedHandler(cb ConnHandler)
DiscoveredServersHandler(cb ConnHandler)
ErrorHandler(cb ErrHandler)
监听新服务器

使用群集时,可以添加或更改服务器。某些客户端允许您侦听此通知:

// Be notified if a new server joins the cluster.
// Print all the known servers and the only the ones that were discovered.
nc, err := nats.Connect("demo.nats.io",
    nats.DiscoveredServersHandler(func(nc *nats.Conn) {
        log.Printf("Known servers: %v\n", nc.Servers())
        log.Printf("Discovered servers: %v\n", nc.DiscoveredServers())
    }))
if err != nil {
    log.Fatal(err)
}
defer nc.Close()

// Do something with the connection
对错误监听

客户端库可以将服务器到客户端的错误与事件分开。许多服务器事件不由应用程序代码处理,导致连接关闭。监听错误对于调试问题非常有用。

// Set the callback that will be invoked when an asynchronous error occurs.
nc, err := nats.Connect("demo.nats.io",
    nats.ErrorHandler(func(_ *nats.Conn, _ *nats.Subscription, err error) {
        log.Printf("Error: %v", err)
    }))
if err != nil {
    log.Fatal(err)
}
defer nc.Close()

// Do something with the connection

Slow Consumers

NATS的设计目的是在服务器中快速移动消息。因此,NATS依赖于应用程序来考虑和响应不断变化的消息速率。服务器会进行一些阻抗匹配,但如果客户端速度太慢,服务器最终会通过关闭连接来切断它们。这些切断的连接被称为慢用户。

一些库处理突发消息通信的一种方法是缓冲订阅的传入消息。因此,如果一个应用程序每秒可以处理10条消息,并且有时每秒接收20条消息,则库可以保存额外的10条消息,以便给应用程序足够的时间来赶上。对于服务器,应用程序似乎正在处理消息并认为连接正常。大多数客户端库都会通知应用程序有一个SlowConsumer错误并丢弃消息。

从服务器接收和删除消息可以保持与服务器的连接正常,但会创建应用程序需求。有几种常见的模式:

  • 使用“请求/答复”来限制发件人并防止订阅服务器过载
  • 使用具有多个订阅者的队列来分割工作
  • 使用类似于NATS流的持久化消息

缓存传入消息的库可以在传入队列或挂起消息上提供两个控件。如果问题是突发的发布服务器,而不是持续的性能不匹配,则这些功能非常有用。在生产中禁用这些限制可能是危险的,尽管将这些限制设置为0可能有助于发现问题,但在生产中也是危险的。
检查库文档中的默认设置,并支持禁用这些限制。
传入的缓存通常是每个订阅服务器的缓存,但请再次检查客户端库的特定文档。

按计数和字节限制Incoming/Pending Messages

传入队列可以受到限制的第一种方式是消息计数。第二种限制传入队列的方法是按总大小。例如,要将传入缓存限制为1000条消息或5mb(以先到者为准):

nc, err := nats.Connect("demo.nats.io")
if err != nil {
    log.Fatal(err)
}
defer nc.Close()

// Subscribe
sub1, err := nc.Subscribe("updates", func(m *nats.Msg) {})
if err != nil {
    log.Fatal(err)
}

// Set limits of 1000 messages or 5MB, whichever comes first
sub1.SetPendingLimits(1000, 5*1024*1024)

// Subscribe
sub2, err := nc.Subscribe("updates", func(m *nats.Msg) {})
if err != nil {
    log.Fatal(err)
}

// Set no limits for this subscription
sub2.SetPendingLimits(-1, -1)

// Close the connection
nc.Close()
检测慢消息者并检查丢弃的消息

当检测到慢速使用者并且消息即将丢弃时,库可能会通知应用程序。此过程可能与其他错误类似,也可能涉及自定义回调。
有些库(如Java)不会在每个丢弃的消息上发送此通知,因为这可能会比较烦躁。相反,通知可能会在订户每次落后时发送一次。库还可以提供一种方法来获取丢弃消息的计数,以便应用程序至少可以检测到问题正在发生。

// Set the callback that will be invoked when an asynchronous error occurs.
nc, err := nats.Connect("demo.nats.io", nats.ErrorHandler(logSlowConsumer))
if err != nil {
    log.Fatal(err)
}
defer nc.Close()

// Do something with the connection
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值