Consul是一个免费的开源工具, 它提供服务发现、健康检查、负载均衡和全局分布的键值存储。此外, 它还提供了一组用于构建业务流程工做流和工具的基础元素。在微服务体系结构中, 应用程序一般跨越多个IP地址运行, 并绑定到各类端口。服务发现有助于查找这些不一样的服务, 而无论它们位于何处。nginx
因为同一个服务的多个实例一般同时运行在微服务体系结构中, 所以在实例健康变化时,实例数量变化时,以及集群状态变化时,咱们须要一种策略去平等地均衡全部到健康实例的流量。这就是负载均衡层的工做。本文讨论了在微服务体系结构中与Consul进行负载均衡的几种经常使用策略。git
对Consul进行负载均衡的一种方法是使用Consul的内置负载均衡功能。Consul将健康检查与服务发现结合在一块儿。这意味着不健康的主机永远不会经过查询返回到服务发现层。在这种模式下, 每次应用程序和服务但愿在数据中心查找其余服务时,他们直接与Consul进行对话。github
请考虑如下配置文件, 其中包括某个后端服务的IP地址:web
services:
backend: 10.2.5.391
复制代码
一般状况下,对于IP地址进行硬编码(尤为是在微服务体系结构中),被认为是一种很差的作法。随着应用程序在整个系统中运行, 将此配置文件保持为最新, 尤为是在计算机集群上,变得很是困难。相反, 更好的方法是利用Consul的DNS发现层。后端
services:
backend: backend.service.consul
复制代码
就像"www.hashicorp.com"是一个web地址, "backend.service.consul"也是。这里,TLD 或域后缀(domain suffix)是可配置的, 但默认值为.Consul。任何以该TLD结尾的请求都将被解析到Consul。这里.service命名空间告诉Consul查找服务 (而不是机器的节点),. backend是要查找的服务的名称。对 "backend.service.consul"的请求被解析到一组IP地址, 就像"www.hashicorp.com"被解析为一组IP地址同样。然而, 对于Consul, 该解析发生在服务发现层,并集成了健康检查机制。bash
每次应用程序或内核解析该DNS条目时, 它都会收到一个与集群中的健康服务对应的 IP 地址列表的随机循环(round-robin)响应。DNS接口基本上提供了零配置(zero-touch)服务发现,并能集成到任何应用程序中。并发
优势:app
缺点:负载均衡
Fabio是一个开源工具, 它为Consul管理的服务提供快速、现代、零配置的负载均衡HTTP(s)和TCP路由器。用户在Consul注册服务,并提供健康检查,Fabio将自动把流量路由到他们。不须要额外配置。dom
用户注册一项服务, 采用以urlprefix-开头的tag, 如:
urlprefix-/my-service
复制代码
在本示例中, 当在/my-service上,对Fabio发出请求时, Fabio将自动将流量路由到集群中的健康服务上。Fabio还支持更高级的路由配置。
优势:
缺点:
对Consul进行负载均衡的另外一种方法是使用第三方工具 (如Nginx 或 HAProxy) 来平衡流量,并使用开源工具 (如Consul Template) 来管理配置。在这种模式下, Consul Template动态管理 nginx.conf 或 haproxy.conf配置文件, 它定义负载均衡器和服务列表。此列表是模板化的, Consul Template做为服务运行以保持模板为最新。 Consul Template与Consul群集有持续的链接, 当服务池发生更改时, Consul Template会写入一个新的配置文件, 并发出信号让Nginx或HAProxy进程从新加载其配置。这里是一个示例的Nginx的Consul Template模板:
upstream myapp {
{{ range service "myapp" }}
server {{ .Address }}:{{ .Port }}
{{ end }}
}
复制代码
在此示例中, Consul Template将监视全部名为 "myapp" 的服务。若是它们的任何状态发生更改, Consul Template将产生一个新的配置文件, 并指示 Nginx 进程从新加载。上面的模板在nginx.conf中呈现为这样:
upstream myapp {
server 10.2.5.60:13845
server 10.6.96.234:45033
server 10.10.20.123:18677
}
复制代码
必须指出, 在这种模式下, Nginx 和 HAProxy 都不知道Consul的存在;它们只是读取它们的配置, 就好像这些值是由操做员或配置管理工具硬编码的同样。
优势:
缺点:
最近, 我开始尝试移除Consul Template, 但保持通过时间考验的灵活性和熟悉度的Nginx。社会上有一些很是有趣和创新的作法, 即:
最终, 这些方法要么涉及太多的移动部件, 要么包括Consul的基本服务发现以外的扩展功能。所以, 我写的 ngx_http_consul_backend_module, 对于每一个导向nginx的请求,动态选择upstream。
它看起来这样:
http {
server {
listen 80;
server_name example.com;
location /my-service {
consul $backend service-name;
proxy_pass http://$backend;
}
}
}
复制代码
对于每一个请求, consul关键字告诉 Nginx 委托给自定义模块并选择一个随机的健康后端服务, 而后将请求代理到该后端服务。确定有改进的地方, 可是这个概念验证代表, 没有中介工具,也 可能直接链接 Nginx 和Consul。
优势:
缺点:
HAProxy 1.8 (当前在撰写本篇文章时发布的候选版本) 在不使用第三方工具或模块的状况下, 经过 DNS 添加了服务发现的内置功能。HAProxy 已经内置 DNS 解决方案有一段时间了, 但 HAProxy 1.8 经过 SRV 记录和支持 EDNS 为端口带来了解决方案, 使其与Consul完美配对。
优势:
缺点:
对于采用Consul的应用,有许多负载均衡的策略和技术。这篇文章详细介绍了一些最多见的技术, 并但愿激发灵感, 以新的,振奋人心的方式集成行业标准的负载均衡工具和Consul。不管您是直接使用Consul, 弥合与Consul模板的差距, 编译本身的Nginx定制版本, 或尝试HAProxy 1.8候选发布版本, 咱们期待听到您如何负载均衡您的微服务应用。