图片

NATS社区版

NATS 是一个开源、轻量级、高性能的分布式消息中间件。NATS是为简单、安全、万物互联而生,用于替代或者增强传统的消息系统。特别适用于微服务、边缘计算、移动、物联网等场景。NATS 最新引入的JetStream流式技术,实现了真正的多租户、横向可扩展并支持多个部署模型。官网: https://nats.io/
计算巢社区服务
计算巢社区服务

      NATS社区版服务实例部署文档

      概述

      NATS是一个开源、轻量级、高性能的分布式消息中间件。

      随着NATS2.0的出现,NATS生态得到了极大的发展,NATS 2.0提供了分布式安全、去中心化管理、多租户、更大的网络、全球可扩展以及安全的数据共享。但NATS流在适应NATS 2.0方面存在很多限制,而且流系统还没有发展到能够应对下一代物联网和边缘计算的挑战。

      NATS 2.0的下一代NATS流系统被称为NATS JetStream,具有分布式安全、多租户和水平扩展能力。

      计算巢上提供了NATS社区版服务,您无需自行配置云主机,即可在计算巢上快速部署NATS服务、实现运维监控,从而方便地基于NATS搭建您自己云原生、分布式、微服务架构的业务应用。

      本文向您介绍如何开通计算巢上的NATS社区版服务,以及部署流程和使用说明。

      计费说明

      NATS社区版在计算巢上的费用主要涉及:

      • 所选vCPU与内存规格
      • 磁盘容量
      • 公网带宽(如果开启公网服务)

      计费方式包括:

      • 按量付费(小时)
      • 包年包月

      预估费用在创建实例时可实时看到。

      部署架构

      NATS社区版有单机部署和集群部署两种架构。

      集群版目前可以支持选择3-11奇数个节点部署。

      所需权限

      NATS服务需要对ECS、VPC等资源进行访问和创建操作,若您使用RAM用户创建服务实例,需要在创建服务实例前,对使用的RAM用户的账号添加相应资源的权限。 添加RAM权限的详细操作,请参见为RAM用户授权。所需权限如下表所示。

      权限策略名称 备注
      AliyunECSFullAccess 管理云服务器服务(ECS)的权限
      AliyunVPCFullAccess 管理专有网络(VPC)的权限
      AliyunROSFullAccess 管理资源编排服务(ROS)的权限
      AliyunComputeNestUserFullAccess 管理计算巢服务(ComputeNest)的用户侧权限
      AliyunCloudMonitorFullAccess 管理云监控(CloudMonitor)的权限

      部署流程

      本文档演示部署集群版的流程。

      参数说明

      您在创建服务实例的过程中,需要配置服务实例信息。下文介绍ZooKeeper社区版服务实例输入参数的详细信息。

      参数组 参数项 示例 说明
      选择模板 模板选择 集群版 模板架构类型
      服务实例名称 test 实例的名称
      地域 华东1(杭州) 选中服务实例的地域,建议就近选中,以获取更好的网络延时。
      可用区配置 部署区域 可用区I 地域下的不同可用区域
      付费类型配置 付费类型 按量付费 或 包年包月
      选择已有基础资源配置 VPC ID vpc-xxx 选择专有网络的ID。
      选择已有基础资源配置 交换机ID vsw-xxx 选择交换机ID。若找不到交换机, 可尝试切换地域和可用区
      ECS实例配置 实例类型 ecs.g7.large 实例规格,可以根据实际需求选择
      ECS实例配置 系统盘空间 40 系统盘空间,可以根据实际需求选择
      ECS实例配置 数据盘空间 40 数据盘空间,可以根据实际需求选择
      ECS实例配置 实例密码 ** 设置实例密码。长度8~30个字符,必须包含三项(大写字母、小写字母、数字、()`~!@#$%^&*-+={}[]:;'<>,.?/ 中的特殊符号)
      ECS实例配置 开启公网IP true 是否开启公网IP
      NATS配置 集群节点数 3 集群版节点数
      NATS配置 admin密码 * 默认admin用户的密码22-30字符

      部署步骤

      单击部署链接, 进入服务实例部署界面,根据界面提示,可以选择默认的部署模板,快速部署,也可以使用自定义模板,对一些参数进行个性化配置。

      详细的部署页面如下:

      create-instance-first-page.png

      便捷的方式是选择默认的套餐,然后只需要选择可用区、选择VPC信息、配置实例密码、NATS密码点击即可进行集群创建。

      img.png

      等待大约1分钟,状态变为「已部署」时,集群即完成创建。 img_1.png 此时点击服务实例名称连接,进入连接页面:

      img_2.png

      可以看到公网和私网访问页面。

      下面演示通过公网地址操作NATS.

      集群配置探查

      nats 配置文件

      [root@iZbp139ju1kmizva7adgdbZ ~]# cat /etc/nats/nats.conf 
      server_name=iZbp139ju1kmizva7adgdbZ-172-16-0-155
      listen: 0.0.0.0:4222
      http: 8222
      accounts {
        $SYS {
          users = [
            { user: "admin",
              pass: "$2a$11$GUizXsS82Y.dll.uZXDic.qMDePF2IT6d3t5iWIs.rQ3lY1p6mDKC"
            }
          ]
        }
      }
      
      jetstream {
         store_dir=/data/nats-storage
      }
      
      cluster {
        name: C1
        listen: 0.0.0.0:4248
        routes = [
      
            nats-route://172.16.0.155:4248
            nats-route://172.16.0.157:4248
            nats-route://172.16.0.156:4248
        ]
      }
      
      

      从配置可以看到默认启用了JetStream特性,持久化目录存储在数据盘/data下

      [root@iZbp19f7ptaaw66l28h5bnZ ~]# df -h
      Filesystem      Size  Used Avail Use% Mounted on
      devtmpfs        3.8G     0  3.8G   0% /dev
      tmpfs           3.8G     0  3.8G   0% /dev/shm
      tmpfs           3.8G  512K  3.8G   1% /run
      tmpfs           3.8G     0  3.8G   0% /sys/fs/cgroup
      /dev/vda1        40G  2.5G   35G   7% /
      /dev/vdb1        40G   49M   38G   1% /data
      tmpfs           768M     0  768M   0% /run/user/0
      [root@iZbp19f7ptaaw66l28h5bnZ ~]# tree /data/nats-storage/
      /data/nats-storage/
      └── jetstream
          ├── $G
          │   └── streams
          │       └── my_stream
          │           ├── meta.inf
          │           ├── meta.sum
          │           ├── msgs
          │           │   ├── 1.blk
          │           │   ├── 1.fss
          │           │   └── 1.idx
          │           └── obs
          │               ├── foo_comsumer
          │               │   ├── meta.inf
          │               │   ├── meta.sum
          │               │   └── o.dat
          │               ├── foo_consumer
          │               │   ├── meta.inf
          │               │   ├── meta.sum
          │               │   └── o.dat
          │               └── foo_consumer2
          │                   ├── meta.inf
          │                   ├── meta.sum
          │                   └── o.dat
      

      nats 使用systemd启动配置如下:

      
      $ cat /etc/systemd/system/natsd.service 
      [Unit]
      Description=natsd.service
      
      [Service]
      Type=simple
      ExecStart=/usr/bin/nats-server --config /etc/nats/nats.conf
      Restart=always
      RestartSec=10
      
      [Install]
      WantedBy=multi-user.target
      

      NATS 集群实践

      创建context

      $ nats context save computenest-nats --server nats://47.98.102.138:4222,nats://47.98.102.138:4222,nats://47.98.102.138:4222 --description 'ComputeNest NATS Cluster' --select
      NATS Configuration Context "computenest-nats"
      
      Description: ComputeNest NATS Cluster
      Server URLs: nats://47.98.102.138:4222,nats://47.98.102.138:4222,nats://47.98.102.138:4222
      Path: /root/.config/nats/context/computenest-nats.json
      Connection: OK
      
      $ nats context ls
      ╭──────────────────────────────────────────────╮
      │                Known Contexts                │
      ├───────────────────┬──────────────────────────┤
      │ Name              │ Description              │
      ├───────────────────┼──────────────────────────┤
      │ computenest-nats* │ ComputeNest NATS Cluster │
      │ local             │ Local Host               │
      ╰───────────────────┴──────────────────────────╯
      

      接下来所有的步骤都默认会使用上面配置的计算巢 NATS 集群.

      创建流

      $ nats stream add my_stream
      ? Subjects foo
      ? Storage file
      ? Replication 3
      ? Retention Policy Limits
      ? Discard Policy Old
      ? Stream Messages Limit -1
      ? Per Subject Messages Limit -1
      ? Total Stream Size -1
      ? Message TTL -1
      ? Max Message Size -1
      ? Duplicate tracking time window 2m0s
      ? Allow message Roll-ups No
      ? Allow message deletion Yes
      ? Allow purging subjects or the entire stream Yes
      
      Stream my_stream was created
      
      Information for Stream my_stream created 2023-04-09 08:28:33
      
                   Subjects: foo
                   Replicas: 3
                    Storage: File
      
      Options:
      
                  Retention: Limits
           Acknowledgements: true
             Discard Policy: Old
           Duplicate Window: 2m0s
          Allows Msg Delete: true
               Allows Purge: true
             Allows Rollups: false
      
      Limits:
      
           Maximum Messages: unlimited
        Maximum Per Subject: unlimited
              Maximum Bytes: unlimited
                Maximum Age: unlimited
       Maximum Message Size: unlimited
          Maximum Consumers: unlimited
      
      
      Cluster Information:
      
                       Name: C1
                     Leader: iZbp139ju1kmizva7adgdcZ-172-16-0-157
                    Replica: iZbp139ju1kmizva7adgdbZ-172-16-0-155, current, seen 0.00s ago
                    Replica: iZbp139ju1kmizva7adgddZ-172-16-0-156, current, seen 0.00s ago
      
      State:
      
                   Messages: 0
                      Bytes: 0 B
                   FirstSeq: 0
                    LastSeq: 0
           Active Consumers: 0
      
      

      注意事项:

      • Replication 配置为3,指明创建的流具备三个副本的高可用版本,NATS 会基于RAFT协议进行数据备份实现高可用

      发布消息

      本部分使用nats pub命令进行发布消息

      $ nats pub foo --count=1000 --sleep 1s "publication #{{Count}} @ {{TimeStamp}}"
       27 / 1000 [====>--------------------------------------------] 26 
      
      

      创建消费者

      要消费消息,首先要创建消费者:

      $ nats consumer add
      ? Consumer name foo_consumer
      ? Delivery target (empty for Pull Consumers) 
      ? Start policy (all, new, last, subject, 1h, msg sequence) all
      ? Acknowledgement policy explicit
      ? Replay policy instant
      ? Filter Stream by subject (blank for all) 
      ? Maximum Allowed Deliveries -1
      ? Maximum Acknowledgements Pending 0
      ? Deliver headers only without bodies No
      ? Add a Retry Backoff Policy No
      ? Select a Stream my_stream
      Information for Consumer my_stream > foo_consumer created 2023-04-09T08:31:23+08:00
      
      Configuration:
      
              Durable Name: foo_consumer
                 Pull Mode: true
            Deliver Policy: All
                Ack Policy: Explicit
                  Ack Wait: 30s
             Replay Policy: Instant
           Max Ack Pending: 1,000
         Max Waiting Pulls: 512
      
      Cluster Information:
      
                      Name: C1
                    Leader: iZbp139ju1kmizva7adgddZ-172-16-0-156
                   Replica: iZbp139ju1kmizva7adgdbZ-172-16-0-155, current, not seen
                   Replica: iZbp139ju1kmizva7adgdcZ-172-16-0-157, current, seen 0.00s ago
      
      State:
      
         Last Delivered Message: Consumer sequence: 0 Stream sequence: 0
           Acknowledgment floor: Consumer sequence: 0 Stream sequence: 0
               Outstanding Acks: 0 out of maximum 1,000
           Redelivered Messages: 0
           Unprocessed Messages: 45
                  Waiting Pulls: 0 of maximum 512
      
      
      

      消费消息

      创建完消费者后就可以进行消费数据:

      $ nats consumer next my_stream foo_consumer --count 1000
      [09:05:18] subj: foo / tries: 1 / cons seq: 1 / str seq: 1 / pending: 27
      
      publication #1 @ 2023-04-06T15:17:18+08:00
      
      Acknowledged message
      
      [09:05:18] subj: foo / tries: 1 / cons seq: 2 / str seq: 2 / pending: 26
      
      publication #2 @ 2023-04-06T15:17:19+08:00
      
      Acknowledged message
      
      [09:05:18] subj: foo / tries: 1 / cons seq: 3 / str seq: 3 / pending: 25
      ...
      

      多实例消费

      多实例消费演示多个实例同时消费一个topic时,NATS 会进行一定的负载均衡保证每个启动的实例均分生产的消息,这在实际业务中可以做负载均衡,消费者水平扩展。

      消费实例1:

      $ nats consumer next my_stream foo_consumer --count 1000
      ...
      [08:33:45] subj: foo / tries: 1 / cons seq: 186 / str seq: 186 / pending: 0
      
      publication #186 @ 2023-04-09T08:33:45+08:00
      
      Acknowledged message
      
      [08:33:47] subj: foo / tries: 1 / cons seq: 188 / str seq: 188 / pending: 0
      
      publication #188 @ 2023-04-09T08:33:47+08:00
      
      Acknowledged message
      
      [08:33:49] subj: foo / tries: 1 / cons seq: 190 / str seq: 190 / pending: 0
      
      publication #190 @ 2023-04-09T08:33:49+08:00
      
      Acknowledged message
      
      [08:33:51] subj: foo / tries: 1 / cons seq: 192 / str seq: 192 / pending: 0
      
      publication #192 @ 2023-04-09T08:33:51+08:00
      
      Acknowledged message
      ...
      

      消费实例2:

      $ nats consumer next my_stream foo_consumer --count 1000
      [08:33:46] subj: foo / tries: 1 / cons seq: 187 / str seq: 187 / pending: 0
      
      publication #187 @ 2023-04-09T08:33:46+08:00
      
      Acknowledged message
      
      [08:33:48] subj: foo / tries: 1 / cons seq: 189 / str seq: 189 / pending: 0
      
      publication #189 @ 2023-04-09T08:33:48+08:00
      
      Acknowledged message
      
      [08:33:50] subj: foo / tries: 1 / cons seq: 191 / str seq: 191 / pending: 0
      
      publication #191 @ 2023-04-09T08:33:50+08:00
      
      Acknowledged message
      
      [08:33:52] subj: foo / tries: 1 / cons seq: 193 / str seq: 193 / pending: 0
      
      publication #193 @ 2023-04-09T08:33:52+08:00
      
      Acknowledged message
      
      

      查看流状态

      $ nats stream info my_stream
      nats stream info my_stream
      Information for Stream my_stream created 2023-04-09 08:28:33
      
                   Subjects: foo
                   Replicas: 3
                    Storage: File
      
      Options:
      
                  Retention: Limits
           Acknowledgements: true
             Discard Policy: Old
           Duplicate Window: 2m0s
          Allows Msg Delete: true
               Allows Purge: true
             Allows Rollups: false
      
      Limits:
      
           Maximum Messages: unlimited
        Maximum Per Subject: unlimited
              Maximum Bytes: unlimited
                Maximum Age: unlimited
       Maximum Message Size: unlimited
          Maximum Consumers: unlimited
      
      
      Cluster Information:
      
                       Name: C1
                     Leader: iZbp139ju1kmizva7adgdcZ-172-16-0-157
                    Replica: iZbp139ju1kmizva7adgdbZ-172-16-0-155, current, seen 0.85s ago
                    Replica: iZbp139ju1kmizva7adgddZ-172-16-0-156, current, seen 0.85s ago
      
      State:
      
                   Messages: 350
                      Bytes: 26 KiB
                   FirstSeq: 1 @ 2023-04-09T00:30:38 UTC
                    LastSeq: 350 @ 2023-04-09T00:36:30 UTC
           Active Consumers: 1
         Number of Subjects: 1
      
      

      说明:

      • 可以看到流的副本数为3
      • 集群信息部分可以看到node2-c1 这个节点是Leader,node1、node3是Follower

      下一步将node2节点宕机观看流的情况。

      高可用验证

      通过查看流的状态发现创建的流的leader节点是"iZbp139ju1kmizva7adgdcZ-172-16-0-157", 现在将此节点关机: image.png 之后再查看流的状态

      $ nats stream info my_stream
      Information for Stream my_stream created 2023-04-09 08:28:33
      
                   Subjects: foo
                   Replicas: 3
                    Storage: File
      
      Options:
      
                  Retention: Limits
           Acknowledgements: true
             Discard Policy: Old
           Duplicate Window: 2m0s
          Allows Msg Delete: true
               Allows Purge: true
             Allows Rollups: false
      
      Limits:
      
           Maximum Messages: unlimited
        Maximum Per Subject: unlimited
              Maximum Bytes: unlimited
                Maximum Age: unlimited
       Maximum Message Size: unlimited
          Maximum Consumers: unlimited
      
      
      Cluster Information:
      
                       Name: C1
                     Leader: iZbp139ju1kmizva7adgddZ-172-16-0-156
                    Replica: iZbp139ju1kmizva7adgdbZ-172-16-0-155, current, seen 0.38s ago
                    Replica: iZbp139ju1kmizva7adgdcZ-172-16-0-157, outdated, OFFLINE, seen 20.64s ago, 548 operations behind
      
      State:
      
                   Messages: 545
                      Bytes: 41 KiB
                   FirstSeq: 1 @ 2023-04-09T00:30:38 UTC
                    LastSeq: 545 @ 2023-04-09T00:39:46 UTC
           Active Consumers: 1
         Number of Subjects: 1
      
      

      可以看到集群状态部分 156号节点变成新的Leader,157状态为OFFLINE。

      此时创建新的消费者重新消费数据:

      nats consumer add
      ? Consumer name foo_consumer2
      ? Delivery target (empty for Pull Consumers) 
      ? Start policy (all, new, last, subject, 1h, msg sequence) all
      ? Acknowledgement policy explicit
      ? Replay policy instant
      ? Filter Stream by subject (blank for all) 
      ? Maximum Allowed Deliveries -1
      ? Maximum Acknowledgements Pending 0
      ? Deliver headers only without bodies No
      ? Add a Retry Backoff Policy No
      ? Select a Stream my_stream
      
      Information for Consumer my_stream > foo_consumer2 created 2023-04-09T08:42:07+08:00
      
      Configuration:
      
              Durable Name: foo_consumer2
                 Pull Mode: true
            Deliver Policy: All
                Ack Policy: Explicit
                  Ack Wait: 30s
             Replay Policy: Instant
           Max Ack Pending: 1,000
         Max Waiting Pulls: 512
      
      Cluster Information:
      
                      Name: C1
                    Leader: iZbp139ju1kmizva7adgdbZ-172-16-0-155
                   Replica: iZbp139ju1kmizva7adgdcZ-172-16-0-157, outdated, not seen
                   Replica: iZbp139ju1kmizva7adgddZ-172-16-0-156, current, seen 0.00s ago
      
      State:
      
         Last Delivered Message: Consumer sequence: 0 Stream sequence: 0
           Acknowledgment floor: Consumer sequence: 0 Stream sequence: 0
               Outstanding Acks: 0 out of maximum 1,000
           Redelivered Messages: 0
           Unprocessed Messages: 685
                  Waiting Pulls: 0 of maximum 512
      
      $ nats consumer next my_stream foo_consumer2 --count 3
      [08:42:27] subj: foo / tries: 1 / cons seq: 1 / str seq: 1 / pending: 703
      
      publication #1 @ 2023-04-09T08:30:38+08:00
      
      Acknowledged message
      
      [08:42:27] subj: foo / tries: 1 / cons seq: 2 / str seq: 2 / pending: 702
      
      publication #2 @ 2023-04-09T08:30:39+08:00
      
      Acknowledged message
      
      [08:42:27] subj: foo / tries: 1 / cons seq: 3 / str seq: 3 / pending: 701
      
      publication #3 @ 2023-04-09T08:30:40+08:00
      
      Acknowledged message
      

      此时故障节点恢复之后:重新查看流的状态:

      $  nats stream info my_stream
      Information for Stream my_stream created 2023-04-09 08:28:33
      
                   Subjects: foo
                   Replicas: 3
                    Storage: File
      
      Options:
      
                  Retention: Limits
           Acknowledgements: true
             Discard Policy: Old
           Duplicate Window: 2m0s
          Allows Msg Delete: true
               Allows Purge: true
             Allows Rollups: false
      
      Limits:
      
           Maximum Messages: unlimited
        Maximum Per Subject: unlimited
              Maximum Bytes: unlimited
                Maximum Age: unlimited
       Maximum Message Size: unlimited
          Maximum Consumers: unlimited
      
      
      Cluster Information:
      
                       Name: C1
                     Leader: iZbp139ju1kmizva7adgddZ-172-16-0-156
                    Replica: iZbp139ju1kmizva7adgdbZ-172-16-0-155, current, seen 0.22s ago
                    Replica: iZbp139ju1kmizva7adgdcZ-172-16-0-157, current, seen 0.22s ago
      
      State:
      
                   Messages: 780
                      Bytes: 58 KiB
                   FirstSeq: 1 @ 2023-04-09T00:30:38 UTC
                    LastSeq: 780 @ 2023-04-09T00:43:43 UTC
           Active Consumers: 2
         Number of Subjects: 1
      
      

      可以看到流的集群信息三个节点全部变为可用状态,刚异常的node2节点恢复了,加入之前两个健康节点的集群后自动变成了follower。

      下一步

      NATS 目前逐步演变为一个生态,可以实践、演示的功能还非常多,包括单不限于以下方面:

      • 安全认证:支持Token、user/pass、TLS、NKEY、JWT等安全配置
      • 连接协议:除了基于默认的nats 连接协议外,还支持WebSocket、MQTT连接,并且可以通过Kafka Bridge JMS 将其他消息系统的流量转到NATS
      • JetStream 更多的功能:JetStream 是NATS最新一代的高可用流式系统,支持非常多的高级特性:
      • 流重放策略
      • 流式存储
      • 保留策略
      • 消息配额
      • 持久化
      • 流Mirror
      • 双端流控
      • Exactly-Once语义支持
      • 多租户管理:基于nsc工具进行多租户账号配置管理
      • 边缘场景:为了支持边缘计算、IOT场景,NATS支持在边缘部署本地的NATS集群,跟中心集群交互。使得边缘设备可以通过连接边缘本地集群快速进行业务数据的生产,不会强依赖跟远端中心集群的网络稳定性,边缘场景参考

      参考文档

      [1]: nats cluster creation: https://docs.nats.io/running-a-nats-service/nats_docker#creating-a-nats-cluster

      [2]: jetString cluster: https://docs.nats.io/running-a-nats-service/configuration/clustering/jetstream_clustering

      [3]: js walkthrough: https://docs.nats.io/nats-concepts/jetstream/js_walkthrough

      [4]: 基于NATS JetStream构建分布式事件流系统

      © 2009-2022 Aliyun.com 版权所有