转:https://www.jianshu.com/p/fa41434d444a

前言

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


正文

1. 工具介绍

1.1. Nginx

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

1.2. Consul-template

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

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 ,然后重新载入配置,就可以动态的调整负载均衡。

 
image

2.2. 自动负载均衡

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

 
image

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

  1. 以相同的 Consul 标签对 Web Server 进行服务标记和分类,新增或者删除 Web Server 服务器节点;
  2. Registrator 监控到 Web Server 的状态更新,自动在 Consul服务注册中心将它注册或者注销;
  3. Consul-template 订阅了 Consul 服务注册中心的服务消息,接收到 Consul 的消息推送,即 Web Server 服务节点状态发生改变。
  4. 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:提供基于ThriftRPC客户端和基于Http协议的RESTful客户端,用于访问 Server 程序。
  • Server WebApp:提供基于ThriftRPC服务端和基于Http协议的RESTful服务端,供 Client 程序调用。

这里的3台主机 - 192.168.1.182192.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 的镜像构建:

  1. 克隆项目到本地项目环境: https://github.com/ostenant/spring-cloud-starter-thrift
  2. 切换到子模块 spring-cloud-starter-thrift-examples 下的 test 目录,执行命令 mvn clean package 进行程序打包。
  3. 分别将 test-client 和 test-server 项目根目录下的 Dockerfile 文件和target目录下的 target/*.jar程序拷贝到 192.168.1.182 、192.168.1.183 和 192.168.1.185 目录下。
  4. 进入客户端 Dockerfile 所在目录,对客户端程序 test-client 进行镜像构建,命令如下:docker build . -t test-client:latest
  5. 进入服务端 Dockerfile 所在目录,对服务端程序 test-server 进行镜像构建,命令如下:docker build . -t test-server:latest

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

 
image

3.4. 部署模型

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

  1. 作为负载均衡转发器 (这里只是演示,可以通过 KeepAlived 实现 Nginx 的HA),将前端访问流量经过负载算法一次转发到后台 Client WebApp 。
  2. 以 Server模式启动 Consul节点,其中一台作为整个服务发现与注册集群的 leader, 用于同步和持久化其余三台 Client 模式的 Consul 节点的数据和状态信息。

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

  1. 每台分别以 Client 模式部署 Consul 节点,用于注册和发现本机 docker 容器暴露的服务,同时和 Consul Server 的  leader 节点进行服务状态同步。
  2. 分别启动一个 Client WebApp 容器实例和两个 Server WebApp 容器实例,将 Client WebApp 的请求根据服务层的负载算法二次转发到 Server WebApp 中的任意一台上完成具体的业务处理。
 
image

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

  • 接入层的转发:两台 Nginx 服务器将客户流量,经由一次转发至三个 Client WebApp服务实例中任意一个做处理。
  • 服务层的转发:三个 Client WebApp服务实例其中之一,根据从服务注册中心拉取的健康的服务缓存列表,将请求二次转发至六个 Server WebApp服务实例其中之一做处理。

3.5. 开始搭建

3.5.1. Consul Server主机

(a). 分别编写 docker-compose.yml,注意 Registrator 需要配置各自的 IP地址。

  • 主机:192.168.1.181

docker-compose.yml

  1. version: '2'
  2. services:
  3. load_balancer:
  4. image: liberalman/nginx-consul-template:latest
  5. hostname: lb
  6. links:
  7. - consul_server_master:consul
  8. ports:
  9. - "80:80"
  10.  
  11. consul_server_master:
  12. image: consul:latest
  13. hostname: consul_server_master
  14. ports:
  15. - "8300:8300"
  16. - "8301:8301"
  17. - "8302:8302"
  18. - "8400:8400"
  19. - "8500:8500"
  20. - "8600:8600"
  21. command: consul agent -server -bootstrap-expect 1 -advertise 192.168.1.181 -node consul_server_master -data-dir /tmp/data-dir -client 0.0.0.0 -ui
  22.  
  23. registrator:
  24. image: gliderlabs/registrator:latest
  25. hostname: registrator
  26. links:
  27. - consul_server_master:consul
  28. volumes:
  29. - "/var/run/docker.sock:/tmp/docker.sock"
  30. command: -ip 192.168.1.181 consul://192.168.1.181:8500
  • 主机:192.168.1.186

docker-compose.yml

  1. version: '2'
  2. services:
  3. load_balancer:
  4. image: liberalman/nginx-consul-template:latest
  5. hostname: lb
  6. links:
  7. - consul_server_slave:consul
  8. ports:
  9. - "80:80"
  10.  
  11. consul_server_slave:
  12. image: consul:latest
  13. hostname: consul_server_slave
  14. ports:
  15. - "8300:8300"
  16. - "8301:8301"
  17. - "8302:8302"
  18. - "8400:8400"
  19. - "8500:8500"
  20. - "8600:8600"
  21. command: consul agent -server -join=192.168.1.181 -advertise 192.168.1.186 -node consul_server_slave -data-dir /tmp/data-dir -client 0.0.0.0 -ui
  22.  
  23. registrator:
  24. image: gliderlabs/registrator:latest
  25. hostname: registrator
  26. links:
  27. - consul_server_slave:consul
  28. volumes:
  29. - "/var/run/docker.sock:/tmp/docker.sock"
  30. command: -ip 192.168.1.186 consul://192.168.1.186:8500

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

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

 
image

(c). 查看正常启动的容器进程,观察ConsulRegistrator 和 Nginx/Consul-template的容器都正常启动。

 
image

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

 
image

(e). 访问 http://IP:8500 查看 Consul Server 的节点信息和服务注册列表。

  • 节点信息:
 
image
  • 服务状态列表:
 
image

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

3.5.2. Consul Client主机

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

服务定义

环境变量Key 环境变量Value 说明
SERVICE_ID web-001 可以为GUID或者可读性更强变量,保证不重复
SERVICE_NAME web 如果ID没有设置,Consul会将name作为id,则有可能注册失败
SERVICE_TAGS nodejs,web 服务的标签,用逗号分隔,开发者可以根据标签来查询一些信息
SERVICE_IP 内网IP 要使用Consul,可访问的IP
SERVICE_PORT 50001 应用的IP, 如果应用监听了多个端口,理应被视为多个应用
SERVICE_IGNORE Boolean 是否忽略本Container,可以为一些不需要注册的Container添加此属性

服健康检查定义

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

环境变量Key 环境变量Value 说明
--- 以下为HTTP模式 --- ---
SERVICE_80_CHECK_HTTP /path_to_health_check 你的健康状态检查的路径如 /status
SERVICE_80_CHECK_INTERVAL 15s 15秒检查一次
SERVICE_80_CHECK_TIMEOUT 2s 状态检查超时时间
--- 以下为HTTPS模式 --- ---
SERVICE_443_CHECK_HTTPS /path_to_health_check 你的健康状态检查的路径如 /status
SERVICE_443_CHECK_INTERVAL 15s 15秒检查一次
SERVICE_443_CHECK_TIMEOUT 2s 状态检查超时时间
--- 以下为TCP模式 --- ---
SERVICE_443_CHECK_TCP /path_to_health_check 你的健康状态检查的路径如 /status
SERVICE_443_CHECK_INTERVAL 15s 15秒检查一次
SERVICE_443_CHECK_TIMEOUT 2s 状态检查超时时间
--- 使用脚本检查 --- ---
SERVICE_CHECK_SCRIPT curl --silent --fail example.com 如官方例子中的check_redis.py
--- 其他 --- ---
SERVICE_CHECK_INITIAL_STATUS passing Consul默认注册后的服务为failed

配置说明

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

  • 主机:192.168.1.182

docker-compose.yml

  1. version: '2'
  2. services:
  3. consul_client_01:
  4. image: consul:latest
  5. ports:
  6. - "8300:8300"
  7. - "8301:8301"
  8. - "8301:8301/udp"
  9. - "8302:8302"
  10. - "8302:8302/udp"
  11. - "8400:8400"
  12. - "8500:8500"
  13. - "8600:8600"
  14. command: consul agent -retry-join 192.168.1.181 -advertise 192.168.1.182 -node consul_client_01 -data-dir /tmp/data-dir -client 0.0.0.0 -ui
  15.  
  16. registrator:
  17. image: gliderlabs/registrator:latest
  18. volumes:
  19. - "/var/run/docker.sock:/tmp/docker.sock"
  20. command: -ip 192.168.1.182 consul://192.168.1.182:8500
  21.  
  22. test_server_1:
  23. image: test-server:latest
  24. environment:
  25. - SERVICE_8080_NAME=test-server-http-service
  26. - SERVICE_8080_TAGS=test-server-http-service-01
  27. - SERVICE_8080_CHECK_INTERVAL=10s
  28. - SERVICE_8080_CHECK_TIMEOUT=2s
  29. - SERVICE_8080_CHECK_HTTP=/health
  30. - SERVICE_25000_NAME=test-server-thrift-service
  31. - SERVICE_25000_TAGS=test-server-thrift-service-01
  32. - SERVICE_25000_CHECK_INTERVAL=10s
  33. - SERVICE_25000_CHECK_TIMEOUT=2s
  34. - SERVICE_25000_CHECK_TCP=/
  35. ports:
  36. - "16000:8080"
  37. - "30000:25000"
  38.  
  39. test_server_2:
  40. image: test-server:latest
  41. environment:
  42. - SERVICE_8080_NAME=test-server-http-service
  43. - SERVICE_8080_TAGS=test-server-http-service-02
  44. - SERVICE_8080_CHECK_INTERVAL=10s
  45. - SERVICE_8080_CHECK_TIMEOUT=2s
  46. - SERVICE_8080_CHECK_HTTP=/health
  47. - SERVICE_25000_NAME=test-server-thrift-service
  48. - SERVICE_25000_TAGS=test-server-thrift-service-02
  49. - SERVICE_25000_CHECK_INTERVAL=10s
  50. - SERVICE_25000_CHECK_TIMEOUT=2s
  51. - SERVICE_25000_CHECK_TCP=/
  52. ports:
  53. - "18000:8080"
  54. - "32000:25000"
  55.  
  56. test_client_1:
  57. image: test-client:latest
  58. environment:
  59. - SERVICE_8080_NAME=my-web-server
  60. - SERVICE_8080_TAGS=test-client-http-service-01
  61. - SERVICE_8080_CHECK_INTERVAL=10s
  62. - SERVICE_8080_CHECK_TIMEOUT=2s
  63. - SERVICE_8080_CHECK_HTTP=/features
  64. ports:
  65. - "80:8080"
  • 主机:192.168.1.183

docker-compose.yml

  1. version: '2'
  2. services:
  3. consul_client_02:
  4. image: consul:latest
  5. ports:
  6. - "8300:8300"
  7. - "8301:8301"
  8. - "8301:8301/udp"
  9. - "8302:8302"
  10. - "8302:8302/udp"
  11. - "8400:8400"
  12. - "8500:8500"
  13. - "8600:8600"
  14. command: consul agent -retry-join 192.168.1.181 -advertise 192.168.1.183 -node consul_client_02 -data-dir /tmp/data-dir -client 0.0.0.0 -ui
  15.  
  16. registrator:
  17. image: gliderlabs/registrator:latest
  18. volumes:
  19. - "/var/run/docker.sock:/tmp/docker.sock"
  20. command: -ip 192.168.1.183 consul://192.168.1.183:8500
  21.  
  22. test_server_1:
  23. image: test-server:latest
  24. environment:
  25. - SERVICE_8080_NAME=test-server-http-service
  26. - SERVICE_8080_TAGS=test-server-http-service-03
  27. - SERVICE_8080_CHECK_INTERVAL=10s
  28. - SERVICE_8080_CHECK_TIMEOUT=2s
  29. - SERVICE_8080_CHECK_HTTP=/health
  30. - SERVICE_25000_NAME=test-server-thrift-service
  31. - SERVICE_25000_TAGS=test-server-thrift-service-03
  32. - SERVICE_25000_CHECK_INTERVAL=10s
  33. - SERVICE_25000_CHECK_TIMEOUT=2s
  34. - SERVICE_25000_CHECK_TCP=/
  35. ports:
  36. - "16000:8080"
  37. - "30000:25000"
  38.  
  39. test_server_2:
  40. image: test-server:latest
  41. environment:
  42. - SERVICE_8080_NAME=test-server-http-service
  43. - SERVICE_8080_TAGS=test-server-http-service-04
  44. - SERVICE_8080_CHECK_INTERVAL=10s
  45. - SERVICE_8080_CHECK_TIMEOUT=2s
  46. - SERVICE_8080_CHECK_HTTP=/health
  47. - SERVICE_25000_NAME=test-server-thrift-service
  48. - SERVICE_25000_TAGS=test-server-thrift-service-04
  49. - SERVICE_25000_CHECK_INTERVAL=10s
  50. - SERVICE_25000_CHECK_TIMEOUT=2s
  51. - SERVICE_25000_CHECK_TCP=/
  52. ports:
  53. - "18000:8080"
  54. - "32000:25000"
  55.  
  56. test_client_1:
  57. image: test-client:latest
  58. environment:
  59. - SERVICE_8080_NAME=my-web-server
  60. - SERVICE_8080_TAGS=test-client-http-service-02
  61. - SERVICE_8080_CHECK_INTERVAL=10s
  62. - SERVICE_8080_CHECK_TIMEOUT=2s
  63. - SERVICE_8080_CHECK_HTTP=/features
  64. ports:
  65. - "80:8080"
  • 主机:192.168.1.185

docker-compose.yml

  1. version: '2'
  2. services:
  3. consul_client_03:
  4. image: consul:latest
  5. ports:
  6. - "8300:8300"
  7. - "8301:8301"
  8. - "8301:8301/udp"
  9. - "8302:8302"
  10. - "8302:8302/udp"
  11. - "8400:8400"
  12. - "8500:8500"
  13. - "8600:8600"
  14. command: consul agent -retry-join 192.168.1.181 -advertise 192.168.1.185 -node consul_client_03 -data-dir /tmp/data-dir -client 0.0.0.0 -ui
  15.  
  16. registrator:
  17. image: gliderlabs/registrator:latest
  18. volumes:
  19. - "/var/run/docker.sock:/tmp/docker.sock"
  20. command: -ip 192.168.1.185 consul://192.168.1.185:8500
  21.  
  22. test_server_1:
  23. image: test-server:latest
  24. environment:
  25. - SERVICE_8080_NAME=test-server-http-service
  26. - SERVICE_8080_TAGS=test-server-http-service-05
  27. - SERVICE_8080_CHECK_INTERVAL=10s
  28. - SERVICE_8080_CHECK_TIMEOUT=2s
  29. - SERVICE_8080_CHECK_HTTP=/health
  30. - SERVICE_25000_NAME=test-server-thrift-service
  31. - SERVICE_25000_TAGS=test-server-thrift-service-05
  32. - SERVICE_25000_CHECK_INTERVAL=10s
  33. - SERVICE_25000_CHECK_TIMEOUT=2s
  34. - SERVICE_25000_CHECK_TCP=/
  35. ports:
  36. - "16000:8080"
  37. - "30000:25000"
  38.  
  39. test_server_2:
  40. image: test-server:latest
  41. environment:
  42. - SERVICE_8080_NAME=test-server-http-service
  43. - SERVICE_8080_TAGS=test-server-http-service-06
  44. - SERVICE_8080_CHECK_INTERVAL=10s
  45. - SERVICE_8080_CHECK_TIMEOUT=2s
  46. - SERVICE_8080_CHECK_HTTP=/health
  47. - SERVICE_25000_NAME=test-server-thrift-service
  48. - SERVICE_25000_TAGS=test-server-thrift-service-06
  49. - SERVICE_25000_CHECK_INTERVAL=10s
  50. - SERVICE_25000_CHECK_TIMEOUT=2s
  51. - SERVICE_25000_CHECK_TCP=/
  52. ports:
  53. - "18000:8080"
  54. - "32000:25000"
  55.  
  56. test_client_1:
  57. image: test-client:latest
  58. environment:
  59. - SERVICE_8080_NAME=my-web-server
  60. - SERVICE_8080_TAGS=test-client-http-service-03
  61. - SERVICE_8080_CHECK_INTERVAL=10s
  62. - SERVICE_8080_CHECK_TIMEOUT=2s
  63. - SERVICE_8080_CHECK_HTTP=/features
  64. ports:
  65. - "80:8080"

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

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

  1. docker-compose up -d

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

 
image

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

 
image

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

 
image

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

 
image

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

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

[图片上传失败...(image-af895-1536936846870)]

  • nginx 服务状态列表,服务名称 nginx-consul-template,提供 http 服务,共有2个服务实例:
 
image
  • test-client 服务状态列表,服务名称为 my-web-server,提供 http 服务,共有3个服务实例:
 
image
  • test-server 服务状态列表,服务名称为 test-server-http-service 和 test-server-thrift-service,分别对应6个 http 服务实例和 6个 thrift 服务实例:
 
image
 
image

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

4. 结果验证

4.1. Nginx负载均衡

4.1.1. 访问Nginx

Nginx 默认访问端口号为80,任选一台 Nginx 访问,比如: http://192.168.1.181/swagger-ui.html

 
image

请求转发至 Test Client 的 Swagger页面,表明 nginx配置文件 nginx.conf 被 Consul-template 成功修改。

4.1.2. 进入Nginx容器

运行 docker ps 查看 nginx-consul-template 的容器 ID,比如这里是:4f2731a7e0cb。进入 nginx-consul-template 容器。

  1. docker-enter 4f2731a7e0cb

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

 
image

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

  1. consul-template -consul-addr=consul:8500 -template /etc/consul-templates/nginx.conf.ctmpl:/etc/nginx/conf.d/app.conf:nginx -s reload
  1. Consul-template 利用 Consul 上的服务信息对 Nginx 的配置文件模板 /etc/consul-templates/nginx.conf.ctmpl 进行重新解析和渲染。
  2. 渲染生成的 nginx 配置文件为 /etc/nginx/conf.d/app.conf
  3. 进一步运行 nginx -s reload 重新加载 app.conf,更新路由转发列表。

查看 app.conf 的配置项,发现三个 test-client 节点的 IP:port 都加入了路由转发列表中。

 
image

退出并关闭主机 192.168.1.182 上的 test-client 容器。

 
image

再次查看 app.conf,可以发现路由节点 192.168.1.182:80 已经从 Nginx 的路由转发列表上剔除掉了。

 
image

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

4.2. 服务负载均衡

4.2.1. 接口测试

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

 
image

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

 
image

4.2.3. 日志分析

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

  1. 2018-02-09 13:15:55.157 INFO 1 --- [erListUpdater-1] t.c.l.ThriftConsulServerListLoadBalancer : Refreshed thrift serverList: [
  2. test-server-thrift-service: [
  3. ThriftServerNode{node='consul_client_01', serviceId='test-server-thrift-service', tags=[test-server-thrift-service-01], host='192.168.1.182', port=30000, address='192.168.1.182', isHealth=true},
  4. ThriftServerNode{node='consul_client_01', serviceId='test-server-thrift-service', tags=[test-server-thrift-service-02], host='192.168.1.182', port=32000, address='192.168.1.182', isHealth=true},
  5. ThriftServerNode{node='consul_client_02', serviceId='test-server-thrift-service', tags=[test-server-thrift-service-03], host='192.168.1.183', port=30000, address='192.168.1.183', isHealth=true},
  6. ThriftServerNode{node='consul_client_02', serviceId='test-server-thrift-service', tags=[test-server-thrift-service-04], host='192.168.1.183', port=32000, address='192.168.1.183', isHealth=true},
  7. ThriftServerNode{node='consul_client_03', serviceId='test-server-thrift-service', tags=[test-server-thrift-service-05], host='192.168.1.185', port=30000, address='192.168.1.185', isHealth=true},
  8. ThriftServerNode{node='consul_client_03', serviceId='test-server-thrift-service', tags=[test-server-thrift-service-06], host='192.168.1.185', port=32000, address='192.168.1.185', isHealth=true}
  9. ],
  10. test-server-http-service: [
  11. ThriftServerNode{node='consul_client_01', serviceId='test-server-http-service', tags=[test-server-http-service-01], host='192.168.1.182', port=16000, address='192.168.1.182', isHealth=true},
  12. ThriftServerNode{node='consul_client_01', serviceId='test-server-http-service', tags=[test-server-http-service-02], host='192.168.1.182', port=18000, address='192.168.1.182', isHealth=true},
  13. ThriftServerNode{node='consul_client_02', serviceId='test-server-http-service', tags=[test-server-http-service-03], host='192.168.1.183', port=16000, address='192.168.1.183', isHealth=true},
  14. ThriftServerNode{node='consul_client_02', serviceId='test-server-http-service', tags=[test-server-http-service-04], host='192.168.1.183', port=18000, address='192.168.1.183', isHealth=true},
  15. ThriftServerNode{node='consul_client_03', serviceId='test-server-http-service', tags=[test-server-http-service-05], host='192.168.1.185', port=16000, address='192.168.1.185', isHealth=true},
  16. ThriftServerNode{node='consul_client_03', serviceId='test-server-http-service', tags=[test-server-http-service-06], host='192.168.1.185', port=18000, address='192.168.1.185', isHealth=true}
  17. ],
  18. my-web-server: [
  19. ThriftServerNode{node='consul_client_01', serviceId='my-web-server', tags=[test-client-http-service-01], host='192.168.1.182', port=80, address='192.168.1.182', isHealth=true},
  20. ThriftServerNode{node='consul_client_02', serviceId='my-web-server', tags=[test-client-http-service-02], host='192.168.1.183', port=80, address='192.168.1.183', isHealth=true},
  21. ThriftServerNode{node='consul_client_03', serviceId='my-web-server', tags=[test-client-http-service-03], host='192.168.1.185', port=80, address='192.168.1.185', isHealth=true}
  22. ]]

服务实例

  • test-server-http-service 所有健康的服务实例:
服务IP地址 服务端口 服务标签
192.168.1.182 16000 test-server-http-service-01
192.168.1.182 18000 test-server-http-service-02
192.168.1.183 16000 test-server-http-service-03
192.168.1.183 18000 test-server-http-service-04
192.168.1.185 16000 test-server-http-service-05
192.168.1.185 18000 test-server-http-service-06
  • test-server-thrift-service 所有健康的服务实例:
服务IP地址 服务端口 服务标签
192.168.1.182 30000 test-server-thrift-service-01
192.168.1.182 32000 test-server-thrift-service-02
192.168.1.183 30000 test-server-thrift-service-03
192.168.1.183 32000 test-server-thrift-service-04
192.168.1.185 30000 test-server-thrift-service-05
192.168.1.185 32000 test-server-thrift-service-06
  • my-web-server 所有健康的服务实例:
服务IP地址 服务端口 服务标签
192.168.1.182 80 test-client-http-service-01
192.168.1.183 80 test-client-http-service-02
192.168.1.185 80 test-client-http-service-03

spring-cloud-starter-thrift 采用的轮询的转发策略,也就是说 my-web-server 会按次序循环往来地将 http 或者 rpc 请求分发到各自的 6 个服务实例完成处理。


总结

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

基于Docker + Consul + Nginx + Consul-Template的服务负载均衡实现(转)的更多相关文章

  1. nginx配置分发Tomcat服务,负载均衡

    文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1.背景 项目中瓦片资源越来越多,如果提高瓦片的访问效率是一个需要解决的 ...

  2. Nginx使用反向代理实现负载均衡

    Nginx使用反向代理实现负载均衡 yls 2019-9-20 简介 基于docker容器以及docker-compose,所以需要自学docker在linux环境的基本使用 使用两个tomcat作为 ...

  3. 图文解说:Nginx+tomcat配置集群负载均衡

    图文解说:Nginx+tomcat配置集群负载均衡 博客分类: appserver nginxTomcatUbuntuLinux网络应用  作者:niumd Blog:http://ari.iteye ...

  4. Nginx的反相代理, 负载均衡

    转自 http://freeloda.blog.51cto.com/2033581/1288553 大纲 一.前言 二.环境准备 三.安装与配置Nginx 四.Nginx之反向代理 五.Nginx之负 ...

  5. 搭建 Keepalived + Nginx + Tomcat 的高可用负载均衡架构

    1 概述 初期的互联网企业由于业务量较小,所以一般单机部署,实现单点访问即可满足业务的需求,这也是最简单的部署方式,但是随着业务的不断扩大,系统的访问量逐渐的上升,单机部署的模式已无法承载现有的业务量 ...

  6. 基于Spring cloud Ribbon和Eureka实现客户端负载均衡

    前言 本案例将基于Spring cloud Ribbon和Eureka实现客户端负载均衡,其中Ribbon用于实现客户端负载均衡,Eureka主要是用于服务注册及发现: 传统的服务端负载均衡 常见的服 ...

  7. Keepalived + Nginx + Tomcat 的高可用负载均衡架构搭建

    Keepalived + Nginx + Tomcat 的高可用负载均衡架构搭建 Nginx 是一个高性能的 HTTP反向代理服务器 Keepalived 是一个基于VRRP协议来实现的LVS服务高可 ...

  8. 搭建Keepalived + Nginx + Tomcat的高可用负载均衡架构

    1 概述 初期的互联网企业由于业务量较小,所以一般单机部署,实现单点访问即可满足业务的需求,这也是最简单的部署方式,但是随着业务的不断扩大,系统的访问量逐渐的上升,单机部署的模式已无法承载现有的业务量 ...

  9. octavia的实现与分析(一)·openstack负载均衡的现状与发展以及lvs,Nginx,Haproxy三种负载均衡机制的基本架构和对比

    [负载均衡] 大量用户发起请求的情况下,服务器负载过高,导致部分请求无法被响应或者及时响应. 负载均衡根据一定的算法将请求分发到不同的后端,保证所有的请求都可以被正常的下发并返回. [主流实现-LVS ...

随机推荐

  1. props、state、forms

    {}用来内嵌任何JS表达式JSX属性JS核心分为三大块:Es6.DOM.WindowBABEL编译器:可以在线编译html语法生成对应的react语法 **自定义组件第一个字母大写:用于区别普通的对象 ...

  2. http://www.easytest.xyz/login_action/

    http://www.easytest.xyz/login_action/一个挺牛逼的系统,有空学习下 https://www.cnblogs.com/1fengchen1/archive/2019/ ...

  3. 使用CIFAR-10样本数据集测试卷积神经网络(ConvolutionalNeuralNetwork,CNN)

    第一次将例程跑起来了,有些兴趣. 参考的是如下URL: http://www.yidianzixun.com/article/0KNz7OX1 本来是比较Keras和Tensorflow的,我现在的水 ...

  4. linux系统编程之进程(五)

    今天继续学习系统编程,学习的主题还是进程,今天主要讨论的是守护进程相关的概念,开始进入正题: 什么是守护进程:       守护进程的创建步骤: 在描述它之前,首先得先了解两个概念:进程组.会话期: ...

  5. Ubuntu常见服务启停

    停止rpcbind服务service portmap stop 停止nfs服务service nfs-kernel-server stop 停止Telnet服务/etc/xinetd.d/telnet ...

  6. debug错误总结

    1, 2,就是一个大括号的问题..让你总是得不了满分..明明和别人的代码差不多. 3,就比如P1914,这种藏坑的题,或者说这一类藏坑的题. 坑是什么呢?就是位数不够往后推的时候.. 你不填坑你就得不 ...

  7. python列表命令

    创建普通列表:member;: 创建混合列表:mix: 创建空列表:empty >>> member = ['lala','oo'] >>> member ['la ...

  8. JS各种案例效果

    1.进度条拖拽 <!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...

  9. java.util.Properties 读取配置文件中的参数

    用法 getProperty方法的返回值是String类型. java.util.Properties 读取配置文件中的参数 //读取配置文件 FileInputStream inStream = n ...

  10. mongodb 集群配置文件

    本文档是在mongodb为3.4下编写的,仅作为参考,详细内容请参考:https://docs.mongodb.com/manual/reference/configuration-options/# ...