NATS故事
2022 年 01 月 15 日 星期六 上午
1. 0
NATS是Neural Automatic Transport System的缩写,翻译成中文是神经自动传 输系统。
2. 1
本节译自Publish Subscribe。
NATS 实现了一个分布式、一对多的、消息发布订阅通讯模型。发布者 Publisher) 发送一个消息到一个主题(Subject),任何监听在这个主题的活跃的订阅者 (Subscriber)收到这个消息。订阅者也可以关注通配符匹配的主题,这有一点 点像正则表达式的意思。如下图示:
+----------+
+-----msg1-->|Subscriber|
| +----------+
|
|
+---------+ +-------+ | +----------+
|Publisher+-----msg1---->|Subject+---+-----msg1-->|Subscriber|
+---------+ +-------+ | +----------+
|
|
| +----------+
+-----msg1-->|Subscriber|
+----------+
这种一对多的模式有时候也叫扇出(Fan-Out)。
3. 2
以下译自https://derekcollison.net:
Connect Everything
连接所有
以下译自About Synadia:
在 Synadia,我们相信有一个机会,创建第一个去中心化的,安全的全球公共 服务,并由 NATS.io 所加持,来连接所有数字系统,服务和设备。
4. 3
上节大略勾画 NATS 志向,要:
连接所有
何谓所有(Everything)?
- 所有数字系统,
- 所有服务,
- 所有设备。
所有的数字系统是指:
- IaaS 云,包括中心云和边缘云,
- PaaS 云,比如一个 K8S 集群,或者一个 LXD 集群,包括中心的和边缘的,
- 操作系统,包括虚机,物理机,系统容器,
- 一组服务的集合。
所有服务是指:
- 云原生服务,
- 非云原生传统服务,
- 运行在物理机上的服务,运行在虚机上的服务,运行在容器里的服务,
- 跑在嵌入式设备里的服务,
- 有状态服务,无状态可以扩容的服务,
- http 服务,grpc 服务,tcp 服务,udp 服务。
所有设备:
- 手机,
- 嵌入设备,
- PC,
- 虚机,物理机,等。
5. 4
本节翻译,缩写自In Depth JWT Guide。
什么是 Account? Account 是 NATS 的隔离上下文。
这个简明的论断无疑是正确的,也可能是准确的,但是不容易理解的。我们按这 个思路来理解,可能会好一些。首先问,NATS 的资源是什么?显然是 Subject, 因为 NATS 的一切围绕 Subject 展开。那 Account 就是 NATS 里 Subject 的 名字空间(Namespace)。假设有两个 Account,A 和 B。在 A 和 B 里,可以 各自有一套 Subject,即使彼此重名,也可以并行通信无误。如下,Account A 和 Account B,在 Account A 里,有 Subject a 和 Subject b,在 Account B 里,有 Subject c 和 Subject d:
.
├── A
│ ├── a
│ └── b
└── B
├── c
└── d
账户 A 里的用户只能访问到 Subject a 和 Subject b,账户 B 里的用户只能 访问到Subject c 和 Subject d。那这就是隔离。那如果 B 账户里的用户希望 访问到 A 账户里 Subject 怎么办呢?那就需要 A 账户把 Subject Export 出 来,这样 B 账户可以Import 进来使用。比如:
accounts: {
A: {
exports: [
{stream: a},
{service: b},
]
}
}
如上, Account A 把自己的 Subject a 以 stream 的形式暴露出来,把 Subject b 以service 形式暴露出来。 这样 Account B 可以 Import:
accounts: {
B: {
imports: [
{stream: {account: A, subject: a}},
{service: {account: A, subject: b}},
]
}
}
因为在 Account B 里没有名为 a 和 b 的 Subject,因此可以直接以 Subject 的原名引入。 对以 Stream 形式引入的 Subject a,Account B 里用户只可以 订阅。对以Service 形式引入的 Subject b,Account B 里的用户既可以订阅, 也可以发布,还可以执行请求回复操作,简直和用自己 Account 里的 Subject 一样。
6. 5
译自Virtualization and containerization considerations。
嗯你当然可以用容器编排系统,诸如 Kubernetes,Nomad 或 Docker Swarm 来 部署你的 NATS 服务器基础设施,的确也有非常多的人如是做,我们的推荐是, 对NATS 服务基础设施只是:基础设施。意思是它最好运行在和你的容器同等的 基础设施上,而不是在容器里。
因为每一层的虚拟化,容器化和重导向1都可能是问题之源,都可能导致延 迟,并且容器编排系统在那去提供服务(例如,检测进程是一直在运行还是没有, 重导向相应网络流量以提供高可用的形式),这些已经更好,更快地实现在了 NATS 自己里。
问自己这个问题,如果你想得到最优性能,最大可靠性,最快速的容错倒换,你 会在容器里运行你的数据库服务吗,并且用 Kubernetes/Nomad/Swarm 编排?还 是直接在虚拟机里,在尽可能接近裸机的环境里运行他们?
NATS 服务器是高效地‘消息路由器'。他们持续从网络得到数据,通过网络发送 数据。如果 JetStream 启用的话还会持续读写文件。他们高度优化有很多,诸 如内置心跳,故障转移和流控机制。在 NATS 服务器进程,网络和磁盘之间的层 级数越小,它就工作的越快,并且这些多出的层级还有可能破坏或者放置比如一 些配置错误。并且你并不依赖代理呀,端口映射呀或者 DNS 一些伎俩,只是为 了让你的客户端应用能连上 NATS 服务器实例,因为你的容器编排系统把他们挪 到一边去了,如果运行在虚机里,他们只需简单地重启,客户端继续用相同已知 IP 地址或者别名。
7. 6
现在我们看看代理消息队列。
![]()
咋一看,代理消息队列比无代理消息队列吞吐量引人注目地减少,大部分降好几 个数量级。半数代理消息队列的吞吐量在 25,000 消息/秒以下。Redis 数字也 许有点误导。尽管提供了发布订阅的功能,Redis 也不是真为一个鲁棒的消息队 列而设计。与 ZeroMQ 类似风格,Redis 断连慢客户端,重要的是,它也不能可 靠处理这类消息。因此,我们踢它出局。Kafka 和 ruby-nats 性能与 Redis 类 似,但在没有间歇失败情况下可以可靠处理消息。NATS 的 Go 实现, gnatsd2,作为一个代理消息队列,吞吐量表现杰出。
不考虑特殊情况,我们看到代理消息队列吞吐量相当一致。不像无代理库,发送 和接受有少到几乎没有的不一致,基本都差不多。