从 STAN 说起
去年本想水一篇关于 NATS JetStream 的博客,当时写了一部分,结果翻资料翻到一篇博客 淺談 NATS、STAN 和 JetStream 兩三事,把我想说的基本都提到了,所以我当时弃坑了。最近用上了 NATS 2.9 版本,所以想着把新了解到的概念和之前想聊的一些内容都整理一下。如果你对 NATS 了解不多,非常推荐先看看我前面提到的那篇文章。
在升到 NATS JetStream 之前,我一直在用 STAN(aka NATS Streaming)。STAN 是 NATS 上一代持久化方案,是一个独立的 Server,它内嵌了 NATS Server,在这之上构建了一个持久化层,并且支持集群,集群节点之间使用 Raft 算法。STAN 在使用上基本接近 NATS,但是有个别要注意的地方。
一个是客户端连接时要提供 Cluster ID 和 Client ID。可以把 NATS 抽象看作 STAN 的网络层,客户端连入的是 NATS 的网络,访问这个网络上的 STAN Server,那么连接这个网络上的 Cluster 需要说明;Client ID 必须是唯一的,STAN 用 Client ID 和 Durable Name 区分 Consumer 持久化视图。
还有一个比较重要的是断线重连问题,也是我们踩过的坑。基于前面提到的抽象理解,STAN 构建于 NATS 网络层之上,客户端实际上没有真正连接到 STAN Server,所以断线重连机制变得复杂。记得当时是阿里云网络波动,STAN 客户端集体掉线后没有恢复,造成了不小影响。后来我封装 stan.go 实现了一个支持重连的客户端,通过 SetConnectionLostHandler
在连接断开时创建新连接,并且支持在连接切换后恢复订阅。
不过这些都不重要了,STAN 已经被标记为 deprecated,只维护到 2023.6。
JetStream
JetStream 是 NATS 2.2 开始内置的持久化机制,满足 At-Least-Once 语义,也提供了一些机制支持 Exactly-Once 语义。目前发展到 2.9.15 版本,已经很好用了。