基于Docker+Consul+Nginx+Consul-template的服务负载均衡实现

前言

上一篇文章使用 和 在 的容器环境中搭建了服务注册和发现集群。在服务发现和注册的基础上,本文将引入 反向代理服务器和 组件,实现动态的服务负载均衡

正文

1. 工具介绍

1.1. Nginx

一个高性能的 和反向代理服务器,用于前端访问流量到后台应用服务器负载均衡请求转发

1.2. Consul-template

是 基于 所提供的可扩展的工具,通过监听 中的数据变化,动态地修改一些配置文件中地模板。常用于在 、 上动态配置健康状态下的客户端反向代理信息。

2. 实现原理

通过 自身实现负载均衡请求转发

通过 的 功能实时监控 集群节点的服务数据的变化;

实时的用 节点的信息替换配置文件的模板,并重新加载配置文件;

和 必须安装在同一台机器上,因为 需要动态修改 的配置文件 ,然后执行 命令进行路由更新,达到动态负载均衡的目的。

2.1. 传统负载均衡

传统的负载均衡,就是 支姐访问 ,然后被转发到后端某一台 。如果后端有添加/删除,运维需要手动改下 ,然后重新载入配置,就可以动态的调整负载均衡。

2.2. 自动负载均衡

再看看基于服务自动发现和注册的负载均衡,负载均衡的方式没有变,只是多了一些外围组件,当然这些组件对 是不可见的, 依然只能看到 入口,访问方式也没变化。

的动态负载均衡实现流程如下:

以相同的标签对 进行服务标记分类新增或者删除服务器节点;

监控到 的状态更新,自动在 服务注册中心将它注册或者注销

订阅了 服务注册中心的服务消息,接收到 的消息推送,即 服务节点状态发生改变。

自动去修改和替换服务器下的 配置文件中的模板,并重新加载服务达到自动负载均衡的目的。

3. 环境准备

3.1. 系统环境

3.2. 节点规划

Client WebApp:提供基于 的 客户端和基于 协议的 客户端,用于访问 程序。

Server WebApp:提供基于 的 服务端和基于 协议的 服务端,供 程序调用。

这里的3台主机 - 、 和 ,每台主机部署两个 容器和一个 容器,用于模拟服务层的负载均衡。

3.3. 镜像构建

Consul:consul:latest

Registrator:gliderlabs/registrator:latest

NginxConsul-template:liberalman/nginx-consul-template:latest

Client WebApp:test-client:latest

Server WebApp:test-server:latest

这里先说说 和 的镜像构建:

克隆项目到本地项目环境: https://github.com/ostenant/spring-cloud-starter-thrift

切换到子模块 下的 目录,执行命令 进行程序打包。

分别将 和 项目根目录下的 文件和 目录下的 程序拷贝到 、 和 目录下。

进入客户端所在目录,对客户端程序 进行镜像构建,命令如下:

进入服务端所在目录,对服务端程序 进行镜像构建,命令如下:

构建完成后查看本地镜像库:

3.4. 部署模型

五台主机,其中 和 两台主机的主要作用如下:

作为负载均衡转发器(这里只是演示,可以通过 实现 的 ),将前端访问流量经过负载算法一次转发到后台 。

以 模式启动 节点,其中一台作为整个服务发现与注册集群的 , 用于同步持久化其余三台 模式的 节点的数据状态信息

其余三台主机 - 、 和 ,充当的角色如下:

每台分别以 模式部署 节点,用于注册发现本机 容器暴露的服务,同时和 的 节点进行服务状态同步

分别启动一个 容器实例和两个 容器实例,将 的请求根据服务层的负载算法二次转发到 中的任意一台上完成具体的业务处理。

这里有两次服务转发操作:

接入层的转发:两台 服务器将客户流量,经由一次转发至三个 服务实例中任意一个做处理。

服务层的转发:三个 服务实例其中之一,根据从服务注册中心拉取的健康的服务缓存列表,将请求二次转发至六个 服务实例其中之一做处理。

3.5. 开始搭建

3.5.1. Consul Server主机

(a). 分别编写 ,注意 需要配置各自的 地址。

主机:192.168.1.181

docker-compose.yml

主机:192.168.1.186

docker-compose.yml

(b). 在两台主机上分别通过 启动多容器应用,命令如下:

这是在主机 上运行启动命令时的输出,可以看到 启动时会先去检查目标镜像文件是否拉取到本地,然后依次创建启动文件配置的容器实例

(c). 查看正常启动的容器进程,观察 、 和 / 的容器都正常启动。

(d). 利用 ,以相同的方式在主机 上启动所配置的容器服务实例,查看启动状态如下:

(e). 访问 查看 的节点信息服务注册列表

节点信息:

服务状态列表:

两台 主机上的容器服务实例均正常启动!

3.5.2. Consul Client主机

一般情况下,我们把 作为服务注册与发现中心,会使用它提供的服务定义( ) 和健康检查定义( ) 功能,相关配置说明参考如下:

服务定义服健康检查定义

配置原则为: 。如果你的应用监听的是 端口,则改为 ,其它环境变量配置同理。

配置说明

(a). 分别编写 ,同样注意 需要配置各自的 地址。 和 的服务实例在配置时需要指定相关的环境变量

主机:192.168.1.182

docker-compose.yml

主机:192.168.1.183

docker-compose.yml

主机:192.168.1.185

docker-compose.yml

注意:我们使用的第三方镜像 , 会把名称为 的服务容器作为后台转发的目标服务器,因此,在 的配置项中,需要指定 为 。当然你也可以自己制作镜像指定模板

(b). 在三台主机上使用 启动多容器应用:

以主机 为例 (其余两台类似),控制台日志显示,创建并启动 文件配置的5个容器实例

(c). 查看正常启动的容器进程,观察到 、一台 和 两台 的容器都正常启动。

(d). 在 操作中的控制台输出可以看到: 并非按照 文件中服务配置的先后顺序启动。 容器的启动依赖于 容器,而此时 还并未启动,就出现了 优先启动而异常退出的现象。解决方法是再运行一次 命令。

(e). 再次查看容器进程,此时 容器就已经正常启动了。

(f). 以相同的方式在其余两台主机上重复以上操作,再次访问 查看 的节点信息服务注册列表

集群节点信息,包括两台 节点和一台 节点,节点右侧可以看到所有的服务注册列表和相关的健康检查结果

服务状态列表,服务名称 ,提供 服务,共有2个服务实例:

服务状态列表,服务名称为 ,提供 服务,共有3个服务实例:

服务状态列表,服务名称为 和 ,分别对应6个 服务实例和 6个 服务实例:

三台 主机上的容器服务实例均正常启动,服务注册和发现运行正常!

4. 结果验证

4.1. Nginx负载均衡

4.1.1. 访问Nginx

默认访问端口号为 ,任选一台 访问,比如: 。

请求转发至 的 页面,表明 配置文件 被 成功修改。

4.1.2. 进入Nginx容器

运行 查看 的容器 ,比如这里是: 。进入 容器。

查看容器内部的进程列表:

特别留意以下一行进程命令,这里完成了三步重要的操作:

利用 上的服务信息对 的配置文件模板进行重新解析渲染

渲染生成的 配置文件为 。

进一步运行 重新加载 ,更新路由转发列表

查看 的配置项,发现三个 节点的 都加入了路由转发列表中。

退出并关闭主机 上的 容器。

再次查看 ,可以发现路由节点已经从 的路由转发列表剔除掉了。

同样的,重新启动 恢复容器,又可以发现 的路由转发列表再次自动将其添加!

4.2. 服务负载均衡

4.2.1. 接口测试

通过 通信方式请求任意一台 ,返回响应结果 (请求处理时间 )。

通过 通信方式请求任意一台 ,返回响应结果 (请求处理时间 )。

4.2.3. 日志分析

服务的负载均衡并不是很好观察,这里直接截取了一段 的服务缓存列表动态定时刷新时打印的日志:

服务实例

所有健康的服务实例:

采用的轮询的转发策略,也就是说 会按次序循环往来地将 或者 请求分发到各自的 个服务实例完成处理。

总结

本文提供了一套基于微服务服务注册与发现体系容器高可用( ) 解决方案,引入了接入层服务层自动负载均衡的实现,详细给出了实践方案技术手段

  • 发表于:
  • 原文链接:http://kuaibao.qq.com/s/20180423G0626V00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券