基於Docker + Consul + Nginx + Consul-template的服務負載均衡實現

前言

上一篇文章使用 ConsulRegistratordocker 的容器環境中搭建了服務註冊和發現集羣。在服務發現和註冊的基礎上,本文將引入 Nginx反向代理服務器和 Consul-template 組件,實現動態的服務負載均衡html


正文

1. 工具介紹

1.1. Nginx

一個高性能的 HTTP反向代理服務器,用於前端訪問流量到後臺應用服務器負載均衡請求轉發前端

1.2. Consul-template

Consul-templateHashiCorp 基於 Consul 所提供的可擴展的工具,經過監聽 Consul 中的數據變化,動態地修改一些配置文件中地模板。經常使用於在 NginxHAProxy 上動態配置健康狀態下的客戶端反向代理信息。node

2. 實現原理

  • 經過 Nginx 自身實現負載均衡請求轉發
  • 經過 Consul-templateconfig 功能實時監控 Consul 集羣節點的服務數據的變化;
  • 實時的用 Consul 節點的信息替換 Nginx 配置文件的模板,並從新加載配置文件;

Consul-templatenginx 必須安裝在同一臺機器上,由於 Consul-template 須要動態修改 nginx 的配置文件 nginx.conf,而後執行 nginx -s reload 命令進行路由更新,達到動態負載均衡的目的。nginx

2.1. 傳統負載均衡

傳統的負載均衡,就是 Client 支姐訪問 Nginx,而後被轉發到後端某一臺 Web Server。若是後端有添加/刪除 Web Server,運維須要手動改下 nginx.conf ,而後從新載入配置,就能夠動態的調整負載均衡。git

2.2. 自動負載均衡

再看看基於服務自動發現和註冊的負載均衡,負載均衡的方式沒有變,只是多了一些外圍組件,固然這些組件對 Client 是不可見的,client 依然只能看到 Nginx 入口,訪問方式也沒變化。github

Nginx 的動態負載均衡實現流程以下:web

  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.183192.168.1.185,每臺主機部署兩個 Client WebApp 容器和一個 Client Server 容器,用於模擬服務層的負載均衡。redis

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

這裏先說說 test-clienttest-server 的鏡像構建:算法

  1. 克隆項目到本地項目環境: github.com/ostenant/sp…
  2. 切換到子模塊 spring-cloud-starter-thrift-examples 下的 test 目錄,執行命令 mvn clean package 進行程序打包。
  3. 分別將 test-clienttest-server 項目根目錄下的 Dockerfile 文件和target目錄下的 target/*.jar程序拷貝到 192.168.1.182192.168.1.183192.168.1.185 目錄下。
  4. 進入客戶端 Dockerfile 所在目錄,對客戶端程序 test-client 進行鏡像構建,命令以下:docker build . -t test-client:latest
  5. 進入服務端 Dockerfile 所在目錄,對服務端程序 test-server 進行鏡像構建,命令以下:docker build . -t test-server:latest

構建完成後查看本地鏡像庫:spring

3.4. 部署模型

五臺主機,其中 192.168.1.181192.168.1.186 兩臺主機的主要做用以下:

  1. 做爲負載均衡轉發器 (這裏只是演示,能夠經過 KeepAlived 實現 NginxHA),將前端訪問流量通過負載算法一次轉發到後臺 Client WebApp
  2. Server模式啓動 Consul節點,其中一臺做爲整個服務發現與註冊集羣leader, 用於同步持久化其他三臺 Client 模式的 Consul 節點的數據狀態信息

其他三臺主機 - 192.168.1.182192.168.1.183192.168.1.185,充當的角色以下:

  1. 每臺分別以 Client 模式部署 Consul 節點,用於註冊發現本機 docker 容器暴露的服務,同時和 Consul Serverleader 節點進行服務狀態同步
  2. 分別啓動一個 Client WebApp 容器實例和兩個 Server WebApp 容器實例,將 Client WebApp 的請求根據服務層的負載算法二次轉發Server WebApp 中的任意一臺上完成具體的業務處理。

這裏有兩次服務轉發操做:

  • 接入層的轉發:兩臺 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

version: '2'
services:
 load_balancer:
 image: liberalman/nginx-consul-template:latest
 hostname: lb
 links:
 - consul_server_master:consul
 ports:
 - "80:80"

 consul_server_master:
 image: consul:latest
 hostname: consul_server_master
 ports:
 - "8300:8300"
 - "8301:8301"
 - "8302:8302"
 - "8400:8400"
 - "8500:8500"
 - "8600:8600"
 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

 registrator:
 image: gliderlabs/registrator:latest
 hostname: registrator
 links:
 - consul_server_master:consul
 volumes:
 - "/var/run/docker.sock:/tmp/docker.sock"
 command:  -ip 192.168.1.181 consul://192.168.1.181:8500
複製代碼
  • 主機:192.168.1.186

docker-compose.yml

version: '2'
services:
 load_balancer:
 image: liberalman/nginx-consul-template:latest
 hostname: lb
 links:
 - consul_server_slave:consul
 ports:
 - "80:80"

 consul_server_slave:
 image: consul:latest
 hostname: consul_server_slave
 ports:
 - "8300:8300"
 - "8301:8301"
 - "8302:8302"
 - "8400:8400"
 - "8500:8500"
 - "8600:8600"
 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

 registrator:
 image: gliderlabs/registrator:latest
 hostname: registrator
 links:
 - consul_server_slave:consul
 volumes:
 - "/var/run/docker.sock:/tmp/docker.sock"
 command:  -ip 192.168.1.186 consul://192.168.1.186:8500
複製代碼

(b). 在兩臺主機上分別經過 docker-compose 啓動多容器應用,命令以下:

docker-compose up -d
複製代碼

這是在主機 192.168.1.181 上運行啓動命令時的輸出,能夠看到 docker-compose 啓動時會先去檢查目標鏡像文件是否拉取到本地,而後依次建立啓動 docker-compose.yml 文件配置的容器實例

(c). 查看正常啓動的容器進程,觀察ConsulRegistratorNginx/Consul-template的容器都正常啓動。

(d). 利用 docker-compose,以相同的方式在主機 192.168.1.186 上啓動所配置的容器服務實例,查看啓動狀態以下:

(e). 訪問 http://IP:8500 查看 Consul Server節點信息服務註冊列表

  • 節點信息:

  • 服務狀態列表:

兩臺 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-servertest-client服務實例在配置時須要指定相關的環境變量

  • 主機:192.168.1.182

docker-compose.yml

version: '2'
services:
 consul_client_01:
 image: consul:latest
 ports:
 - "8300:8300"
 - "8301:8301"
 - "8301:8301/udp"
 - "8302:8302"
 - "8302:8302/udp"
 - "8400:8400"
 - "8500:8500"
 - "8600:8600"
 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

 registrator:
 image: gliderlabs/registrator:latest
 volumes:
 - "/var/run/docker.sock:/tmp/docker.sock"
 command:  -ip 192.168.1.182 consul://192.168.1.182:8500

 test_server_1:
 image: test-server:latest
 environment:
 - SERVICE_8080_NAME=test-server-http-service
 - SERVICE_8080_TAGS=test-server-http-service-01
 - SERVICE_8080_CHECK_INTERVAL=10s
 - SERVICE_8080_CHECK_TIMEOUT=2s
 - SERVICE_8080_CHECK_HTTP=/health
 - SERVICE_25000_NAME=test-server-thrift-service
 - SERVICE_25000_TAGS=test-server-thrift-service-01
 - SERVICE_25000_CHECK_INTERVAL=10s
 - SERVICE_25000_CHECK_TIMEOUT=2s
 - SERVICE_25000_CHECK_TCP=/
 ports:
 - "16000:8080"
 - "30000:25000"

 test_server_2:
 image: test-server:latest
 environment:
 - SERVICE_8080_NAME=test-server-http-service
 - SERVICE_8080_TAGS=test-server-http-service-02
 - SERVICE_8080_CHECK_INTERVAL=10s
 - SERVICE_8080_CHECK_TIMEOUT=2s
 - SERVICE_8080_CHECK_HTTP=/health
 - SERVICE_25000_NAME=test-server-thrift-service
 - SERVICE_25000_TAGS=test-server-thrift-service-02
 - SERVICE_25000_CHECK_INTERVAL=10s
 - SERVICE_25000_CHECK_TIMEOUT=2s
 - SERVICE_25000_CHECK_TCP=/
 ports:
 - "18000:8080"
 - "32000:25000"

 test_client_1:
 image: test-client:latest
 environment:
 - SERVICE_8080_NAME=my-web-server
 - SERVICE_8080_TAGS=test-client-http-service-01
 - SERVICE_8080_CHECK_INTERVAL=10s
 - SERVICE_8080_CHECK_TIMEOUT=2s
 - SERVICE_8080_CHECK_HTTP=/features
 ports:
 - "80:8080"
複製代碼
  • 主機:192.168.1.183

docker-compose.yml

version: '2'
services:
 consul_client_02:
 image: consul:latest
 ports:
 - "8300:8300"
 - "8301:8301"
 - "8301:8301/udp"
 - "8302:8302"
 - "8302:8302/udp"
 - "8400:8400"
 - "8500:8500"
 - "8600:8600"
 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

 registrator:
 image: gliderlabs/registrator:latest
 volumes:
 - "/var/run/docker.sock:/tmp/docker.sock"
 command:  -ip 192.168.1.183 consul://192.168.1.183:8500

 test_server_1:
 image: test-server:latest
 environment:
 - SERVICE_8080_NAME=test-server-http-service
 - SERVICE_8080_TAGS=test-server-http-service-03
 - SERVICE_8080_CHECK_INTERVAL=10s
 - SERVICE_8080_CHECK_TIMEOUT=2s
 - SERVICE_8080_CHECK_HTTP=/health
 - SERVICE_25000_NAME=test-server-thrift-service
 - SERVICE_25000_TAGS=test-server-thrift-service-03
 - SERVICE_25000_CHECK_INTERVAL=10s
 - SERVICE_25000_CHECK_TIMEOUT=2s
 - SERVICE_25000_CHECK_TCP=/
 ports:
 - "16000:8080"
 - "30000:25000"

 test_server_2:
 image: test-server:latest
 environment:
 - SERVICE_8080_NAME=test-server-http-service
 - SERVICE_8080_TAGS=test-server-http-service-04
 - SERVICE_8080_CHECK_INTERVAL=10s
 - SERVICE_8080_CHECK_TIMEOUT=2s
 - SERVICE_8080_CHECK_HTTP=/health
 - SERVICE_25000_NAME=test-server-thrift-service
 - SERVICE_25000_TAGS=test-server-thrift-service-04
 - SERVICE_25000_CHECK_INTERVAL=10s
 - SERVICE_25000_CHECK_TIMEOUT=2s
 - SERVICE_25000_CHECK_TCP=/
 ports:
 - "18000:8080"
 - "32000:25000"

 test_client_1:
 image: test-client:latest
 environment:
 - SERVICE_8080_NAME=my-web-server
 - SERVICE_8080_TAGS=test-client-http-service-02
 - SERVICE_8080_CHECK_INTERVAL=10s
 - SERVICE_8080_CHECK_TIMEOUT=2s
 - SERVICE_8080_CHECK_HTTP=/features
 ports:
 - "80:8080"
複製代碼
  • 主機:192.168.1.185

docker-compose.yml

version: '2'
services:
 consul_client_03:
 image: consul:latest
 ports:
 - "8300:8300"
 - "8301:8301"
 - "8301:8301/udp"
 - "8302:8302"
 - "8302:8302/udp"
 - "8400:8400"
 - "8500:8500"
 - "8600:8600"
 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

 registrator:
 image: gliderlabs/registrator:latest
 volumes:
 - "/var/run/docker.sock:/tmp/docker.sock"
 command:  -ip 192.168.1.185 consul://192.168.1.185:8500

 test_server_1:
 image: test-server:latest
 environment:
 - SERVICE_8080_NAME=test-server-http-service
 - SERVICE_8080_TAGS=test-server-http-service-05
 - SERVICE_8080_CHECK_INTERVAL=10s
 - SERVICE_8080_CHECK_TIMEOUT=2s
 - SERVICE_8080_CHECK_HTTP=/health
 - SERVICE_25000_NAME=test-server-thrift-service
 - SERVICE_25000_TAGS=test-server-thrift-service-05
 - SERVICE_25000_CHECK_INTERVAL=10s
 - SERVICE_25000_CHECK_TIMEOUT=2s
 - SERVICE_25000_CHECK_TCP=/
 ports:
 - "16000:8080"
 - "30000:25000"

 test_server_2:
 image: test-server:latest
 environment:
 - SERVICE_8080_NAME=test-server-http-service
 - SERVICE_8080_TAGS=test-server-http-service-06
 - SERVICE_8080_CHECK_INTERVAL=10s
 - SERVICE_8080_CHECK_TIMEOUT=2s
 - SERVICE_8080_CHECK_HTTP=/health
 - SERVICE_25000_NAME=test-server-thrift-service
 - SERVICE_25000_TAGS=test-server-thrift-service-06
 - SERVICE_25000_CHECK_INTERVAL=10s
 - SERVICE_25000_CHECK_TIMEOUT=2s
 - SERVICE_25000_CHECK_TCP=/
 ports:
 - "18000:8080"
 - "32000:25000"

 test_client_1:
 image: test-client:latest
 environment:
 - SERVICE_8080_NAME=my-web-server
 - SERVICE_8080_TAGS=test-client-http-service-03
 - SERVICE_8080_CHECK_INTERVAL=10s
 - SERVICE_8080_CHECK_TIMEOUT=2s
 - SERVICE_8080_CHECK_HTTP=/features
 ports:
 - "80:8080"
複製代碼

注意:咱們使用的第三方鏡像 liberalman/nginx-consul-templateNginx 會把名稱爲 my-web-server服務容器做爲後臺轉發的目標服務器,所以,在 test-client 的配置項中,須要指定 SERVICE_XXX_NAMEmy-web-server。固然你也能夠本身製做鏡像指定模板

(b). 在三臺主機上使用 docker-compose 啓動多容器應用:

docker-compose up -d
複製代碼

以主機 192.168.1.182 爲例 (其他兩臺相似),控制檯日誌顯示,建立並啓動 docker-compose.yml 文件配置的5個容器實例

(c). 查看正常啓動的容器進程,觀察到 Consul、一臺test-client 和 兩臺test-server的容器都正常啓動。

(d). 在 b 操做中的控制檯輸出能夠看到:docker-compose 並不是按照 docker-compose.yml 文件中服務配置的前後順序啓動。 registrator 容器的啓動依賴於 consul 容器,而此時 consul 還並未啓動,就出現了 registrator 優先啓動而異常退出的現象。解決方法是再運行一次 docker-compose up -d 命令。

(e). 再次查看容器進程,此時 Registrator 容器就已經正常啓動了。

(f). 以相同的方式在其他兩臺主機上重複以上操做,再次訪問 http://IP:8500 查看 Consul Server節點信息服務註冊列表

  • Consul 集羣節點信息,包括兩臺 Consul Server 節點和一臺 Consul Client 節點,節點右側能夠看到全部的服務註冊列表和相關的健康檢查結果

  • nginx 服務狀態列表,服務名稱 nginx-consul-template,提供 http 服務,共有2個服務實例:

  • test-client 服務狀態列表,服務名稱爲 my-web-server,提供 http 服務,共有3個服務實例:

  • test-server 服務狀態列表,服務名稱爲 test-server-http-servicetest-server-thrift-service,分別對應6個 http 服務實例和 6個 thrift 服務實例:

三臺 Consul Client 主機上的容器服務實例均正常啓動,服務註冊和發現運行正常!

4. 結果驗證

4.1. Nginx負載均衡

4.1.1. 訪問Nginx

Nginx 默認訪問端口號爲80,任選一臺 Nginx 訪問,好比: http://192.168.1.181/swagger-ui.html

請求轉發至 Test ClientSwagger頁面,代表 nginx配置文件 nginx.confConsul-template 成功修改。

4.1.2. 進入Nginx容器

運行 docker ps 查看 nginx-consul-template 的容器 ID,好比這裏是:4f2731a7e0cb。進入 nginx-consul-template 容器。

docker-enter 4f2731a7e0cb
複製代碼

查看容器內部的進程列表:

特別留意如下一行進程命令,這裏完成了三步重要的操做:

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 都加入了路由轉發列表中。

退出並關閉主機 192.168.1.182 上的 test-client 容器。

再次查看 app.conf,能夠發現路由節點 192.168.1.182:80 已經從 Nginx路由轉發列表剔除掉了。

一樣的,從新啓動 test-client 恢復容器,又能夠發現 Nginx路由轉發列表 再次自動將其添加!

4.2. 服務負載均衡

4.2.1. 接口測試

test-client 經過 http 通訊方式請求任意一臺 test-server,返回響應結果 (請求處理時間 ms )。

test-client 經過 thrift 通訊方式請求任意一臺 test-server,返回響應結果 (請求處理時間 ms )。

4.2.3. 日誌分析

服務的負載均衡並非很好觀察,這裏直接截取了一段 test-client服務緩存列表動態定時刷新時打印的日誌:

2018-02-09 13:15:55.157  INFO 1 --- [erListUpdater-1] t.c.l.ThriftConsulServerListLoadBalancer : Refreshed thrift serverList: [
test-server-thrift-service: [
	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},
	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},
	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},
	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},
	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},
	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}
],
test-server-http-service: [
	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},
	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},
	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},
	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},
	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},
	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}
],
my-web-server: [
	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},
	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},
	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}
]]
複製代碼

服務實例

  • 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) 解決方案,引入了接入層服務層自動負載均衡的實現,詳細給出了實踐方案技術手段


歡迎關注技術公衆號: 零壹技術棧

零壹技術棧

本賬號將持續分享後端技術乾貨,包括虛擬機基礎,多線程編程,高性能框架,異步、緩存和消息中間件,分佈式和微服務,架構學習和進階等學習資料和文章。

相關文章
相關標籤/搜索