NATS

未匹配的标注
本文档最新版为 3.x,旧版本可能放弃维护,推荐阅读最新版!

NATS

这篇文档着眼于 nats, 将 nats 消息系统集成到 micro 工具包中. 它讨论包括围绕服务发现, 微服务的同步和异步通信.

什么是 NATS?

NATS 是一个开源的原生云消息系统或更简单的消息总线. NATS 由 Apcera 的创始人 Derek Collison 创建. 它起源于 VMWare, 并开始成为一个基于 ruby 的系统. 用 Go 重写了已有很长时间, 并且正在稳步获得那些寻求高度可扩展性和高性能消息传递系统的人的采用.

如果您想了解有关 NATS 的更多信息, 可参阅 nats.io 或加入 社区.

为什么选择 NATS?

为什么不选择 NATS? 过去曾与许多消息总线合作过, 很快就清楚 NATS 是不一样的烟火. 多年来, 消息传递被誉为企业的救星, 导致系统试图成为所有人的一切. 这导致了很多虚假的承诺, 显著的性能膨胀和高技术成本, 产生了比解决问题更多的问题.

相比之下, NATS 采取非常专注的方式, 解决性能和可用性问题, 同时保持令人难以置信的精简. 它提到 “永远在线并且可用”, 并且使用 “自动修剪和伸缩” 消息模式. 它的简单性, 重点和轻量级特性使其成为微服务生态系统的主要候选者. 我们相信它很快将成为服务间消息传递的主要候选人.

NATS 提供了什么:

  • 高性能和可扩展性

  • 高可用性

  • 极其轻巧

  • 最多一次交付

    NATS 不提供什么:

  • 坚持

  • 合约

  • 增强交付模式

  • 企业级排队

这简要介绍了选择 NATS 的原因. 那么它如何适应 Micro? 来! 我们讨论一下.

Micro 的 NATS

Micro 是一个微服务工具包, 采用可插拔的体系结构, 允许将底层的依赖关系以最小的更改进行替换. Go-Micro 框架的每个接口都为微服务提供了构建块; 用于服务发现的 注册表, 用于同步通信的 传输, 用于异步通信的 消息总线 的代理等等.

为每个组件创建插件并实现接口一样简单. 我们将花更多时间详细说明, 如何在未来的博客文章中撰写插件. 如果您想查看 NATS 或任何其他系统的插件, 例如 etcd discovery, kafka broker, rabbitmq transport, 您可以在这里找到它们 github.com/micro/go-plugins.

基于 NATS 的 Micro 本质上是一组 go-micro 插件, 可用于与 NATS 消息总线系统集成. 通过为 go-micro 的各种接口提供插件, 我们创建了许多可以选择的架构模式集成.

根据我们的经验, 一种实现不适合所有情况, 而 Micro NATS 的灵活性允许您定义适合您和您的团队模型.

下面我们将讨论传输, 代理和注册中心的 NATS 插件的实现.

传输

传输是同步通信的 Micro 接口. 它使用常见的 Socket 语义, 与 Listen, DialAccept 类似. 这些概念和模式对于使用 tcp, http 等的同步通信很好理解, 但适应消息总线可能有些困难. 与消息总线建立连接, 而不是与服务本身建立连接. 为了解决这个问题, 我们使用与 topics 和 channels 的伪连接的概念.

这是其工作原理.

服务使用 transport.Listen 来侦听消息. 这将创建一个到 NATS 的连接. 当 transport.Accept 被调用时, 一个独特的 topic 会被创建和订阅. 这个独特的 topic 将被用作 go-micro 注册表中的服务地址. 接收到的每条消息将被用作伪套接字/连接的基础. 如果现有连接具有相同的回复地址, 我们只需将该消息放入该连接的缓存中.

想要与此服务通信的客户端将使用 transport.Dial 创建与服务的连接. 这将连接到 NATS, 创建它自己独特的 topic 并订阅它. 该 topic 用于服务的响应. 每当客户端向服务发送消息时, 它都会将回复地址设置为该 topic.

当任何一方想要关闭连接时, 他们只需调用 transport.Close 即可终止与 NATS 的连接.

使用传输插件

导入传输插件

import _ "github.com/micro/go-plugins/transport/nats"

从传输标志开始

go run main.go --transport=nats --transport_address=127.0.0.1:4222

或者直接使用传输工具

transport := nats.NewTransport()

go-micro 传输接口定义

type Transport interface {
    Dial(addr string, opts ...DialOption) (Client, error)
    Listen(addr string, opts ...ListenOption) (Listener, error)
    String() string
}

Transport

Broker

代理是异步消息的转发 micro 接口. 它提供了适用于大多数邮件代理的高级通用实现. 就其本质而言, NATS 是一个异步消息传输系统, 它被用作消息代理. 有一点需要注意 NATS 不持久化消息. 虽然这对一些人来说可能并不理想, 但我们仍然认为 NATS 可以也应该作为一个代理来使用 go-micro. 在不需要持久性的情况下, 它允许高度可扩展的 pub/sub 子体系结构.

NATS 提供了一个非常直接的发布和订阅机制, 包括 topic, channel 等概念. 在这里没有真正的技巧使它工作. 消息可以以异步触发和遗忘的方式发布. 使用相同 channel 名称的订阅者在 NATS 中形成一个队列组, 然后它将允许消息自动均匀分布在订阅者中.

使用代理插件

导入代理插件

import _ "github.com/micro/go-plugins/broker/nats"

从代理标志开始

go run main.go --broker=nats --broker_address=127.0.0.1:4222

或者直接使用代理

broker := nats.NewBroker()

go-micro 代理接口:

type Broker interface {
    Options() Options
    Address() string
    Connect() error
    Disconnect() error
    Init(...Option) error
    Publish(string, *Message, ...PublishOption) error
    Subscribe(string, Handler, ...SubscribeOption) (Subscriber, error)
    String() string
}

Broker

注册表

注册表是服务发现的 Go-Micro 接口. 你可能会想使用消息总线进行服务发现? 这能工作吗? 事实上它确实可以并且相当不错. 许多使用消息总线进行传输的人, 会避免使用任何单独的发现机制. 这是因为消息总线本身可以处理通过 topic 和 channel 的路由. 定义为服务名称的 topic 可以用作路由 key, 在订阅该 topic 的服务的实例之间自动进行负载平衡.

Go-micro 将服务发现和传输机制视为两个不同的问题. 无论何时, 客户端向另一个服务器发出请求时, 它会按名称在注册表中查找服务, 选择节点的地址, 然后通过传输器与其进行通信.

通常存储服务发现信息的最常用方式是通过一个分布式的键值存储, 如 zookeeper, etcd 或类似的东西. 正如你可能已经意识到的那样, NATS 不是一个分布式的键值存储, 所以我们要做一些有点不一样的事情…

广播查询!

广播查询与您想象的一样. 服务监听我们认为用于广播查询的特定主题. 任何想要获得服务发现信息的人都会首先创建一个它所订阅的回复主题, 然后用他们的回复地址在广播主题上进行查询.

因为我们实际上并不知道有多少服务实例正在运行, 或者有多少响应将被返回, 所以我们设定了一个我们愿意等待响应的时间的上限. 这是发现分散聚集的简单粗暴方式, 但由于 NAT 的可扩展和高性能特性, 它实际上运行得非常好. 它也间接提供了一个非常简单的过滤服务的方法, 并且响应时间更长. 将来, 我们将着眼于改进底层实现.

总结工作原理:

  1. 创建回复 topic 并订阅
  2. 用广播地址发送广播 topic 的查询
  3. 听取回复并在时间限制后取消订阅
  4. 合并响应和返回结果

使用注册表插件

导入注册表插件

import _ "github.com/micro/go-plugins/registry/nats"

从注册表标志开始

go run main.go --registry=nats --registry_address=127.0.0.1:4222

或者直接使用注册表

registry := nats.NewRegistry()

go-micro 注册表接口定义:

type Registry interface {
    Register(*Service, ...RegisterOption) error
    Deregister(*Service) error
    GetService(string) ([]*Service, error)
    ListServices() ([]*Service, error)
    Watch() (Watcher, error)
    String() string
}

Registry

在 NATS 上伸缩 Micro 服务

在上面的例子中, 我们只在本地主机上指定了一个 NATS 服务器, 但我们推荐的实际使用方法是, 设置一个 NATS 群集以获得高可用性和容错性. 要了解有关 NAT 群集的更多信息, 可参阅 此处 的 NATS 文档.

Micro 接受逗号分隔的地址列表作为上面提到的标志或可选地使用环境变量. 如果您直接使用客户端库, 它还允许一组可变主机作为注册表, 传输和代理的初始化选项.

对于云原生应用的架构世界而言, 我们过去的经验表明, 每个 AZ 或每个地区的群集都是理想的. 大多数云提供商在 AZ 之间具有相对较低 (3-5ms) 的延迟, 这允许区域集群没有问题. 在运行高可用性配置时, 确保您的系统能够容忍 AZ 故障并且在更成熟的配置下, 可以承受整个区域故障很重要. 我们不建议跨地区集群. 理想情况下, 应该使用更高级别的工具来管理多群集和多区域系统.

Micro 是一个令人难以置信的灵活的, 运行时无感知的微服务系统. 它可以在任何地方和配置下运行. 它的世界是由服务注册机制引导. 服务集群可以完全基于您提供访问权限的服务注册中心, AZ 或区域池中进行本地化和命名空间. 结合 NATS 集群, 您可以构建高度可用的体系结构以满足您的需求.

概要

NATS 是一个可扩展的高性能消息中间件系统, 我们认为它非常适合微服务生态系统. 它与 Micro 配合具有非常好竞争力, 我们已经证明它可以用作 注册表, 传输代理 的插件. 我们已经实施了所有三项, 以突出 NATS 的灵活性.

Micro on NATS, 是 Micro 强大的可插拔架构的一个典型例子. 每个 go-micro 软件包都可以通过最小的更改来实现和替换. 将来关于 Micro 的示例, 接下来最有可能是 Kubernetes 上的 Micro.

希望这会激励你尝试使用 NAT 上的 Micro, 甚至为其他系统编写一些插件并回馈给社区.

可以在这里找到 NATS 插件的源码 github.com/micro/go-plugins.

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
taadis
讨论数量: 0
发起讨论 只看当前版本


暂无话题~