我建议你阅读 Alexander Sigachev 的报告《分布式系统中的服务发现》的文字记录,以 Consul 为例。
创建服务发现的目的是为了让您能够以最低的成本将新应用程序连接到我们现有的环境。 使用服务发现,我们可以最大程度地将 docker 容器或虚拟服务与其运行的环境分离。
我欢迎大家! 我是 Alexander Sigachev,在 Inventos 工作。 今天我给大家介绍一个服务发现这样一个概念。 让我们以 Consul 为例来看看服务发现。
服务发现解决什么问题? 创建服务发现的目的是为了让您能够以最低的成本将新应用程序连接到我们现有的环境。 使用服务发现,我们可以最大程度地将 docker 容器或虚拟服务与其运行的环境分离。
它是什么样子的? 在网络上的一个经典示例中,这是接受用户请求的前端。 然后它将其路由到后端。 在此示例中,该负载均衡器平衡两个后端。
在这里我们看到我们正在启动应用程序的第三个实例。 因此,当应用程序启动时,它会向服务发现注册。 服务发现通知负载均衡器。 负载均衡器自动更改其配置,新的后端投入运行。 通过这种方式,可以添加后端,或者相反,从工作中排除后端。
服务发现还有哪些方便的用途? 服务发现可以存储 nginx 配置、证书和活动后端服务器列表。
服务发现还允许您检测故障并检测故障。 检测故障的可能方案有哪些?
- 我们开发的这个应用程序会自动通知服务发现它仍然有效。
- 服务发现本身会轮询应用程序的可用性。
- 或者,我们使用第三方脚本或应用程序来检查我们的应用程序的可用性,并通知服务发现一切都很好并且可以工作,或者相反,一切都不好并且需要从平衡中排除该应用程序实例。
每个方案的使用取决于我们使用的软件。 例如,我们刚刚开始开发一个新项目,那么当我们的应用程序通知服务发现时,我们可以轻松地提供一个方案。 或者我们可以连接服务发现正在检查。
如果我们继承了应用程序或由其他人开发了应用程序,那么当我们编写处理程序时,第三种选择是合适的,所有这些都会自动进入我们的工作。
这是一个例子。 nginx 形式的负载均衡器被重新启动。 这是 Consul 提供的可选实用程序。 这是领事模板。 我们描述该规则。 我们说我们正在使用模板(Golang Template Engine)。 当事件发生时,当发生更改的通知时,它会重新生成,并将“重新加载”命令发送到服务发现。 最简单的例子是当 nginx 通过事件重新配置并重新启动时。
什么是领事?
-
首先,这是服务发现。
-
它有一个可用性检查机制——健康检查。
-
它还有一个 KV 商店。
-
它基于使用多数据中心的能力。
这一切能用来做什么? 在 KV Store 中我们可以存储示例配置。 健康检查我们可以检查本地服务并通知。 使用多数据中心,可以构建服务地图。 例如,亚马逊拥有多个区域,并以最佳方式路由流量,以便数据中心之间不会产生不必要的请求,这些请求与本地流量分开计费,因此延迟更短。
让我们了解一下 Consul 中使用的术语。
- Consul 是一个用 Go 编写的服务。 Go 程序的优点之一是您只需下载 1 个二进制文件。 从任何地方启动,您没有任何依赖项。
- 然后,使用这些密钥,我们可以在客户端模式或服务器模式下启动该服务。
- 此外,“datacenter”属性允许您设置该服务器属于哪个数据中心的标志。
- 共识——基于raft协议。 如果有人感兴趣,您可以在 Consul 网站上阅读更多相关信息。 这是一个协议,允许您确定领导者并确定哪些资金被认为是有效且可访问的。
- Gossip 是一种支持节点之间交互的协议。 此外,该系统是分散的。 在一个数据中心内,所有节点都与其邻居进行通信。 并且,相应地,有关当前状态的信息被相互传输。 可以说,这是邻居之间的闲话。
- LAN Gossip – 同一数据中心内的邻居之间的本地数据交换。
- WAN Gossip - 当我们需要在两个数据中心之间同步信息时使用。 信息在标记为服务器的节点之间流动。
- RPC – 允许您通过服务器上的客户端执行请求。
RPC 的描述。 假设 Consul 作为客户端在虚拟机或物理服务器上运行。 我们在当地联系他。 然后本地客户端向服务器请求信息并进行同步。 根据设置,信息可以从本地缓存中检索,也可以与领导者、服务器主控同步。
这两种方案各有利弊。 如果我们使用本地缓存,那么速度会很快。 如果我们处理存储在服务器上的数据,则需要更长的时间,但我们会获得更多相关信息。
如果您以图形方式描述这一点,那么这就是该站点的图片。 我们看到有三个master正在运行。 其中一个标有星号作为领导者。 在此示例中,有三个客户端通过 UDP/TCP 在本地相互交换信息。 并且数据中心之间的信息在服务器之间传输。 在这里,客户可以在本地进行交互。
Consul提供什么API? 为了获取信息,Consul 有两种类型的 API。
这是 DNS API。 默认情况下,Consul 在端口 8600 上运行。 我们可以配置请求代理并通过本地 DNS 进行本地解析来提供访问。 我们可以按域名查询并接收响应中的IP地址信息。
HTTP API - 或者我们可以在端口 8500 上本地请求有关特定服务的信息并接收 JSON 响应,服务器有什么 IP、什么主机、注册什么端口。 并且可以通过令牌传输附加信息。
运行 Consul 需要什么?
在第一个选项中,在开发人员模式下,我们指示这是开发人员模式的标志。 代理作为服务器启动。 它在一台机器上独立执行整个功能。 方便、快捷,首次启动几乎无需额外设置。
第二种模式是在生产中启动。 这就是启动变得有点复杂的地方。 如果我们没有任何版本的consul,那么我们必须将第一台机器带入bootstrap,即这台机器,它将承担领导者的职责。 我们提出它,然后我们提出服务器的第二个实例,向它传递我们的主服务器所在位置的信息。 我们提出第三个。 当我们启动三台机器后,我们在第一台机器上从正在运行的引导程序中以正常模式重新启动它。 数据已同步,初始集群已启动。
建议在服务器模式下运行三到七个实例。 这是因为,如果服务器数量增加,那么它们之间同步信息的时间就会增加。 节点数必须为奇数以保证法定人数。
如何提供健康检查? 我们在Consul配置目录下以Json的形式编写验证规则。 第一个选项是本示例中 google.com 域的可用性。 我们说这个检查需要每隔30秒进行一次。 这样我们就可以检查我们的节点是否可以访问外部网络。
第二个选择是检查自己。 我们使用常规的curl以10秒的间隔在指定端口上调用localhost。
这些检查会被汇总并发送给服务发现。 根据可用性,这些节点要么被排除,要么出现在可用且正常工作的计算机的列表中。
Consul还提供了一个UI界面,该界面以单独的标志启动,并且将在机器上可用。 这允许您查看信息,也可以进行一些更改。
在此示例中,“服务”选项卡已打开。 可以看到有XNUMX个服务正在运行,其中之一就是Consul。 执行的检查次数。 这些机器位于三个数据中心。
这是“节点”选项卡的示例。 我们看到它们有涉及数据中心的复合名称。 它还显示哪些服务正在运行,即我们看到没有设置标签。 这些附加标签可以提供一些信息,开发人员可以使用这些信息来指定附加参数。
您还可以向 Consul 传输有关磁盘状态和平均负载的信息。
问题
问题:我们有一个 docker 容器,如何与 Consul 一起使用它?
答:docker容器有多种实现方式。 最常见的一种是使用第三方 docker 容器负责注册。 启动时,会向其传递一个 docker 套接字。 所有容器注册和取消发布事件都记录在 Consul 中。
问题:那么Consul自己启动docker容器?
答:不。 我们正在运行一个 docker 容器。 在配置时,我们指示 - 监听这样那样的套接字。 这与我们使用证书的方式大致相同,即上传有关我们拥有的位置和内容的信息。
问题:事实证明,我们尝试连接到 Service Discovery 的 Docker 容器内部应该有某种可以将数据发送到 Consul 的逻辑?
答:不是真的。 当它启动时,我们通过环境变量传递变量。 比如说服务名称、服务端口。 寄存器监听该信息并将其输入Consul。
问题:我还有一个关于 UI 的问题。 例如,我们将 UI 部署在生产服务器上。 安全性怎么样? 数据存储在哪里? 是否有可能以某种方式积累数据?
答案:在 UI 中,有来自数据库和服务发现的数据。 我们自己在设置中设置密码。
问:这个可以在网上发布吗?
答:默认情况下,Consul 在 localhost 上启动。 要在互联网上发布,您需要安装某种代理。 我们对自己的安全规则负责。
问:它是否提供开箱即用的历史数据? 查看健康检查的统计数据很有趣。 如果服务器经常出现故障,您还可以诊断问题。
答:我不确定那里有支票的详细信息。
问:当前的状态并不像动态那么重要。
答案:用于分析——是的。
问题:Consul docker 最好不要使用服务发现?
答:我不建议使用它。 报告的目的是介绍这样一个概念是怎样存在的。 从历史上看,我认为它已经发展到了第一个版本。 现在有更完整的解决方案,例如 Kubernetes,它在幕后拥有这一切。 作为 Kubernetes 的一部分,服务发现不如 Etcd。 但我对它并不像对Consul那么熟悉。 因此,我决定以Consul为例进行服务发现。
问:带leader服务器的方案会不会降低整个应用程序的启动速度? 如果领事说谎,他如何确定新的领导者呢?
答:他们有一个完整的协议描述。 如果您有兴趣,可以阅读。
问题:Consul 充当我们的成熟服务器,所有请求都通过它进行?
答:它不充当完整的服务器,而是接管特定区域。 它通常以 service.consul 结尾。 然后我们按逻辑继续前进。 我们在生产中不使用域名,而是使用内部基础设施,如果我们使用 DNS,则内部基础设施通常隐藏在服务器缓存后面。
问题:也就是说,如果我们要访问一个数据库,那么无论如何我们都会先拉Consul来找到这个数据库,对吗?
答:是的。 如果我们使用 DNS,那么当我们使用 DNS 名称时,它的工作方式与没有 Consul 时的工作方式相同。 通常,现代应用程序不会在每个请求中提取域名,因为我们安装了 connect,一切正常,并且在不久的将来我们实际上不会使用它。 如果连接中断,那么是的,我们会再次询问我们的基地在哪里并前往那里。
PS关于健康检查。 Consul 与 Kubernetes 一样,使用相同的系统根据代码状态检查服务的生存状态。
200 OK for healthy
503 Service Unavailable for unhealthy
来源:
来源: habr.com