前言
上一篇文章使用 Consul
和 Registrator
在 docker
的容器环境中搭建了服务注册和发现集群。在服务发现和注册的基础上,本文将引入 Nginx
反向代理服务器和 Consul-template
组件,实现动态的服务负载均衡。
正文
1. 工具介绍
1.1. Nginx
一个高性能的 HTTP
和反向代理服务器,用于前端访问流量到后台应用服务器负载均衡和请求转发。
1.2. Consul-template
Consul-template
是 HashiCorp
基于 Consul
所提供的可扩展的工具,通过监听 Consul
中的数据变化,动态地修改一些配置文件中地模板。常用于在 Nginx
、HAProxy
上动态配置健康状态下的客户端反向代理信息。
2. 实现原理
- 通过
Nginx
自身实现负载均衡和请求转发; - 通过
Consul-template
的config
功能实时监控Consul
集群节点的服务和数据的变化; - 实时的用
Consul
节点的信息替换Nginx
配置文件的模板,并重新加载配置文件;
Consul-template
和nginx
必须安装在同一台机器上,因为Consul-template
需要动态修改nginx
的配置文件nginx.conf
,然后执行nginx -s reload
命令进行路由更新,达到动态负载均衡的目的。
2.1. 传统负载均衡
传统的负载均衡,就是 Client
支姐访问 Nginx
,然后被转发到后端某一台 Web Server
。如果后端有添加/删除 Web Server
,运维需要手动改下 nginx.conf
,然后重新载入配置,就可以动态的调整负载均衡。
2.2. 自动负载均衡
再看看基于服务自动发现和注册的负载均衡,负载均衡的方式没有变,只是多了一些外围组件,当然这些组件对 Client
是不可见的,client
依然只能看到 Nginx
入口,访问方式也没变化。
Nginx
的动态负载均衡实现流程如下:
- 以相同的
Consul
标签对Web Server
进行服务标记和分类,新增或者删除Web Server
服务器节点; -
Registrator
监控到Web Server
的状态更新,自动在Consul
服务注册中心将它注册或者注销; -
Consul-template
订阅了Consul
服务注册中心的服务消息,接收到Consul
的消息推送,即Web Server
服务节点状态发生改变。 -
Consul-template
自动去修改和替换Nginx
服务器下的nginx
配置文件中的模板,并重新加载服务达到自动负载均衡的目的。
3. 环境准备
3.1. 系统环境
软件 | 版本 |
---|---|
操作系统 | Ubuntu:16.04 x86_64,内核:4.8.0-58-generic |
docker | Docker version 1.12.6, build 78d1802 |
docker-compose | docker-compose version 1.8.0 |
3.2. 节点规划
主机IP | 组件 |
---|---|
192.168.1.181 | Consul Server, Registrator, Nginx, Consul-template |
192.168.1.186 | Consul Server, Registrator, Nginx, Consul-template |
192.168.1.182 | Consul Client, Registrator, Client WebApp1, Server WebApp1, Server WebApp2 |
192.168.1.183 | Consul Client, Registrator, Client WebApp2, Server WebApp3, Server WebApp4 |
192.168.1.185 | Consul Client, Registrator, Client WebApp3, Server WebApp5, Server WebApp6 |
- Client WebApp:提供基于
Thrift
的RPC
客户端和基于Http
协议的RESTful
客户端,用于访问Server
程序。 - Server WebApp:提供基于
Thrift
的RPC
服务端和基于Http
协议的RESTful
服务端,供Client
程序调用。
这里的3台主机 - 192.168.1.182
、192.168.1.183
和 192.168.1.185
,每台主机部署两个 Client WebApp
容器和一个 Client Server
容器,用于模拟服务层的负载均衡。
3.3. 镜像构建
- Consul:consul:latest
- Registrator:gliderlabs/registrator:latest
- Nginx和Consul-template:liberalman/nginx-consul-template:latest
- Client WebApp:test-client:latest
- Server WebApp:test-server:latest
这里先说说 test-client
和 test-server
的镜像构建:
- 克隆项目到本地项目环境: https://github.com/ostenant/spring-cloud-starter-thrift
- 切换到子模块
spring-cloud-starter-thrift-examples
下的test
目录,执行命令mvn clean package
进行程序打包。 - 分别将
test-client
和test-server
项目根目录下的Dockerfile
文件和target
目录下的target/*.jar
程序拷贝到192.168.1.182
、192.168.1.183
和192.168.1.185
目录下。 - 进入客户端
Dockerfile
所在目录,对客户端程序test-client
进行镜像构建,命令如下:docker build . -t test-client:latest
- 进入服务端
Dockerfile
所在目录,对服务端程序test-server
进行镜像构建,命令如下:docker build . -t test-server:latest
构建完成后查看本地镜像库:
3.4. 部署模型
五台主机,其中 192.168.1.181
和 192.168.1.186
两台主机的主要作用如下:
- 作为负载均衡转发器 (这里只是演示,可以通过
KeepAlived
实现Nginx
的HA
),将前端访问流量经过负载算法一次转发到后台Client WebApp
。 - 以
Server
模式启动Consul
节点,其中一台作为整个服务发现与注册集群的leader
, 用于同步和持久化其余三台Client
模式的Consul
节点的数据和状态信息。
其余三台主机 - 192.168.1.182
、192.168.1.183
和 192.168.1.185
,充当的角色如下:
- 每台分别以
Client
模式部署Consul
节点,用于注册和发现本机docker
容器暴露的服务,同时和Consul Server
的leader
节点进行服务状态同步。 - 分别启动一个
Client WebApp
容器实例和两个Server WebApp
容器实例,将Client WebApp
的请求根据服务层的负载算法二次转发到Server WebApp
中的任意一台上完成具体的业务处