NATS - NATS介绍

回到顶部(go to top)

NATS优缺点

1.NATS优点

高性能 - broker收到数据后,直接推给subscriber

  • NATS因为publisher把数据发布给nats broker后,直接推给push给subscriber
  • 而kafka是subscriber主动从broker 拉取pull数据
  • 各中间件性能对比:

 

层次丰富的subject,以及通配符的支持

  • 字符.用于创建主题层次结构
    • time.us
    • time.us.east
    • time.us.east.atlanta
    • time.eu.east
    • time.eu.warsaw
  • NATS提供了两个通配符,可以取代点分隔主题中的一个或多个元素。订阅者可以使用这些通配符通过单个订阅来收听多个主题,但是发布者将始终使用完全指定的主题,而不使用通配符
    • 匹配单个令牌:第一个通配符是*,它将匹配单个标记 。例如,如果应用程序想要侦听东部时区,则可以订阅time.*.east,这将匹配time.us.east和time.eu.east。
    • 匹配多个令牌:第二个通配符是>将匹配一个或多个令牌,并且只能出现在主题的末尾。例如,time.us.>将匹配time.us.easttime.us.east.atlanta,而time.us. *只匹配time.us.east,因为它不能匹配多个令牌。

2.NATS缺点

没有持久化操作

  • 这里值得是core-nats不做持久化
  • 而nats-jetstream是基于 nats 的持久化消息队列

检测到slow consumer后,会丢消息

  • server服务端检测到后,会断开和client的connection,并清空服务端队列缓存的消息
  • client客户端检测到后,会清空客户端队列缓存的消息

 

回到顶部(go to top)

NATS的三种消息分发模式

1.Pub-Sub

作者注:这就是工作中常用的 发布client.publish() / 订阅client.subscribe()

可以采用通配符表达式的形式,订阅所有匹配的消息。

 

2.Request-Reply

作者注:这就是工作中常用的 请求client.request()

publisher和subscriber都要给replyTo属性赋值

为下图的Publisher,在发布消息msg1时,会同时带上一个replyTo的主题(一个UUID),并且订阅这个replyTo主题,

对应的订阅者收到之后,回复的Reply消息会以这个replyTo的主题发出,这样Publisher就能收到回复。

Publisher收到回复之后会自动取消replyTo的订阅,完成一次Request-Reply调用。

如果这里三个Subscriber都回复了,那么Nats只转发最早回复replyTo的消息,后面所回复的replyTo由于发起方Publisher已经取消订阅,不会再收到了。

3.Queue Groups

如果一个消息,有多个订阅者,那么会每个订阅者都收到并进行处理。

有时候我们想让一条消息只由一个订阅者处理,多个消费者之间可以实现负载均衡,这个时候可以使用Nats的Queue sub模式。

如下图,三条消息1,2,3会分发到三个Subscriber中,而不是每个Subscriber都收到1,2,3三条消息。值得注意的是,消息的分发是随机的,不支持按照固定规则分配。

 

 

回到顶部(go to top)

关于NATS的Slow Consumer

参考文献:https://docs.nats.io/running-a-nats-service/nats_admin/slow_consumers

1.Slow Consumer怎么识别

在client端里被识别

一旦client端识别出slow consumer, 会丢弃client端内存队列消息 

在client创建connection时,就创建error handler

复制代码
// Set the error handler when creating a connection.
nc, err := nats.Connect("nats://localhost:4222",
  nats.ErrorHandler(natsErrHandler))

func natsErrHandler(nc *nats.Conn, sub *nats.Subscription, natsErr error) {
    fmt.Printf("error: %v\n", natsErr)
    if natsErr == nats.ErrSlowConsumer {
        pendingMsgs, _, err := sub.Pending()
        if err != nil {
            fmt.Printf("couldn't get pending messages: %v", err)
            return
        }
        fmt.Printf("Falling behind with %d pending messages on subject %q.\n",
            pendingMsgs, sub.Subject)
        // Log error, notify operations...
    }
    // check for other errors
}
复制代码

当slow consumer发生时,将会打印出类似的log:

error: nats: slow consumer, messages dropped
Falling behind with 65536 pending messages on subject "foo".

 

在server端被识别

一旦server端识别出slow consumer, 会断掉和该client的connection,并丢弃server端内存队列消息 

当slow consumer发生时,将会打印出类似的log:

[54083] 2017/09/28 14:45:18.001357 [INF] ::1:63283 - cid:7 - Slow Consumer Detected

 

2.Slow Consumer怎么处理

扩大queue subscriber成员 -- 适用于不依赖消息顺序 

当你的订阅属于一个queue,那么增加queue成员,便能很方便的增加subscriber的处理能力

 

主题预设为可扩展的样式 -- 适用于依赖消息顺序

将所需数据,pub到四个主题中:

  • Sensors.North
  • Sensors.South
  • Sensors.East
  • Sensors.West

在期初数据压力不大时,一个订阅者只需要订阅主题 Sensors.> 即可获取到并处理所有四个主题数据。

在业务扩张后,一个订阅者处理不过来时,可以扩展为四个订阅者,分别订阅四个主题。

 

降低publisher的速率

保持和subscriber的一样的速率。

该方便不怎么推荐。

 

调整服务端/客户端 buffer队列的大小

该方便不怎么推荐。

因为该方法只是延缓了问题的发现,并不会处理问题。

 

回到顶部(go to top)

参考文献

http://wiki.htzq.htsc.com.cn/pages/viewpage.action?pageId=177762886 

https://docs.nats.io/running-a-nats-service/nats_admin/slow_consumers

https://blog.csdn.net/zhaicheng55/article/details/129390703

 

posted on   frank_cui  阅读(2136)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
历史上的今天:
2020-07-18 设计模式 - 模板方法模式 Template Method
2020-07-18 设计模式 - 委托模式
2020-07-18 设计模式 - 装饰模式Decorator
2020-07-18 Java 基础 - 父类子类初始化
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

levels of contents
点击右上角即可分享
微信分享提示