1、介绍:
NATS是
一个开源、轻量级、高性能的分布式消息中间件
,实现了高可伸缩性和优雅的Publish/Subscribe模型,使用Golang语言开发。NATS的开发哲学认为高质量的QoS应该在客户端构建。
故只建立了Request-Reply,不提供 1.持久化 2.事务处理 3.增强的交付模式 4.企业级队列。
2、NATS消息传递模型
NATS支持各种消息传递模型,包括:
-
发布订阅
(Publish Subscribe) -
请求回复
(Request Reply) -
队列订阅
(Queue Subscribers )
2.1、发布订阅(Publish Subscribe)
NATS将publish/subscribe消息分发模型实现为一对多通信,发布者在Subject上发送消息,并且监听该Subject在任何活动的订阅者都会收到该消息
2.2、请求响应(Request Reply)
NATS支持两种请求响应消息:点对点或多对多。点对点涉及最快或首先响应。在一对多的消息交换中,需要限制请求响应的限制。
在Request Reply过程中,发布请求发布带有响应主题的消息,期望对该subject做出响应操作
队列订阅&分享工作(Queue Subscribers & Sharing Work)
NATS提供称为队列订阅的负载均衡功能,虽然名字为queue(队列)但是并不是我们所认为的那样。他的主要功能是将具有相同queue名字的subject进行负载均衡。使用队列订阅功能消息发布者不需要做任何改动,消息接受者需要具有相同的对列名
3、NATS提供的功能
-
纯粹的发布订阅模型
(Pure pub-sub) -
服务器集群
(Cluster mode server) -
自动精简订阅者
(Auto-pruning of subscribers) -
基于文本协议
(Text-based protocol) -
多服务质量保证
(Multiple qualities of service – QoS) -
发布订阅
(Publish Subscribe)
4、NATS Streaming介绍
-
增强消息协议
(Enhanced message protocol) -
消息/事件持久化
(Message/event persistence) -
至少一次数据传输
(At-least-once-delivery) -
Publisher限速(
Publisher rate limiting) -
Subscriber速率匹配
(Rate matching/limiting per subscriber) -
按主题重发消息
(Historical message replay by subject) -
持续订阅
(Durable subscriptions)
5、NATS与NATS Streaming
-
弄清楚NATS与NATS Streaming各自的职责,区别和他们之间的交互至关重要
;简单来说,NATS实现了基本的发布/订阅模型,NATS Streaming提供的则是更高级的特性,包括ACK,持久化等; -
理解NATS和NATS Streaming的区别最重要的是,NATS Streaming并不是在NATS上功能的增强,它与NATS之间仍然通过Client进行交互,他们的部署是独立的,NATS Streaming以类似于sidecar的形式服务于NATS
5.1、NATS重点关注
详细介绍参考:
https://www.nats.io/documentation/server/gnatsd-intro/
认证授权 :
- NATS提供基于Token和用户名/密码的两种客户端认证方式;
- 提供基本的针对主题订阅和发布的权限管理;
高可用集群
:NATS部署高可用集群非常的简单,只需要在各个实例的配置文件中添加如下配置即可;其中集群可单独设置认证方式;
cluster {
host: '0.0.0.0'
port: 7248
routes = [
nats-route://192.168.59.103:7244
nats-route://192.168.59.103:7246
]
}
自动断开不健康的客户端连接
:
NATS Server和Client之间会维持PING-PONG检查,发现已断开或不健康的连接会主动断开;
这是一种保证Server长时间高效运行的策略;
相对简单的监控界面
通过以下启动参数可以提供一个简单的web监控界面,但是功能很简陋,需要进一步改善;为了弥补不足,提供nats-top工具查看更详尽的服务器信息;
-m your_port
单个推送消息大小限制
NATS单个消息的大小限制为1M,基本上是可以满足一般的数据传输的;
5.2、NATS Streaming
5.2.1、介绍
参考地址:
https://www.nats.io/documentation/streaming/nats-streaming-intro/
了解NATS Streaming主要关注它为NATS Server提供新特性;主要关注的有以下几点:
1).At-least-once-delivery & Durable subscriptions
至少一次投递和持久化,对于在分布式场景下保证数据的一致性非常有用;
2).Historical message replay by subject & 全局客户端ID唯一
可以选择任意历史节点开始订阅恢复订阅
3).多样化持久化支持
默认将消息保存在内存中,同时支持file,mysql两种持久化支持;
5.2.2、场景分析
场景一 高效传输(不保证一致性)
其实在我们使用NATS的初期就是使用的这种模式,主要用于在各个模块信息同步(比如,个人信息的同步),在时效性上和一致性上要求不高;这种场景只需要创建NATS Cluster即可;
场景二 保证最终一致性
一致性的保证主要是通过NATS Streaming提供的特性来完成,在微服务架构中,跨服务的调用链经常存在,如何保证在下游服务不可用或失败的情况下业务数据的一致性要求,NATS Streaming 提供的ACK机制和至少一次传递的特性就非常重要;甚至是要避免在NATS集群宕机恢复过程中可能的数据不一致情况的发生;举例的话,典型的场景包括支付和关键业务状态的更新;
5.2.3、实践方案介绍
场景一
在这种场景下,NATS的角色更多是高效传输层(transport),完成数据的异步传输;因此,只需要部署NATS集群即可,并不需要Streaming提供的高级特性;套用以下模板,创建多节点的NATS集群即可;
集群部署demo(以一个节点配置为例)
# Client port
port: 4222
# HTTP monitoring port
monitor_port: 4223
# 用户
authorization {
users = [
{user: <<用户名1>>,password: <<密码1>>}
]
timeout: 1
}
# This is for clustering multiple servers together.
cluster {
# 集群接口
port: 4224
# 集群链接认证
authorization {
user: <<用户名2>>
password: <<密码2>>
timeout: 0.75
}
# 集群信息
routes = [
nats-route://<<用户名2>>:<<密码2>>@nats-1:4224
nats-route://<<用户名2>>:<<密码2>>@nats-2:4224
]
}
场景二
由于场景二需要Streaming相关特性支持,所以,需要部署Streaming集群;同时,根据NATS与NATS Streaming 之间独特的工作方式,我们完全可以在场景一中部署的NATS集群的基础上进行NATS Streaming 的部署;也就是说,NATS Streaming集群仍然连接此NATS集群;
集群部署demo(以一个节点配置为例)
# NATS Streaming specific configuration
streaming {
id: stan-cluster
store: file
dir: store
nats_server_url: "<<NATS集群地址>>"
# 只需要指定集群名和节点名,实现自定发现
cluster {
node_id: "stan-1"
peers: ["stan-2", "stan-3"]
}
}
Streaming的节点数建议为奇数,Streaming Server通过Raft算法选出leader节点;
总结:NATS使用过程中最显著的感受是轻量,高效以及部署方便(详尽的配置介绍);同时由于它较好的分布式特性,在使用过程中从未出现意外宕机或者数据异常丢失的情况;
参考资料: