前言
上一篇文章使用 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
的映象構建:
- 克隆專案到本地專案環境: github.com/ostenant/sp…
- 切換到子模組
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
中的任意一臺上完成具體的業務處理。
這裡有兩次服務轉發操作:
- 接入層的轉發:兩臺
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). 檢視正常啟動的容器程式,觀察Consul
、Registrator
和 Nginx
/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-server
和 test-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-template
,Nginx
會把名稱為my-web-server
的服務容器作為後臺轉發的目標伺服器,因此,在test-client
的配置項中,需要指定SERVICE_XXX_NAME
為my-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-service
和test-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 Client
的 Swagger
頁面,表明 nginx
配置檔案 nginx.conf
被 Consul-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
複製程式碼
Consul-template
利用Consul
上的服務資訊對Nginx
的配置檔案模板/etc/consul-templates/nginx.conf.ctmpl
進行重新解析和渲染。- 渲染生成的
nginx
配置檔案為/etc/nginx/conf.d/app.conf
。 - 進一步執行
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
) 解決方案,引入了接入層和服務層的自動負載均衡的實現,詳細給出了實踐方案和技術手段!
歡迎關注技術公眾號: 零壹技術棧
本帳號將持續分享後端技術乾貨,包括虛擬機器基礎,多執行緒程式設計,高效能框架,非同步、快取和訊息中介軟體,分散式和微服務,架構學習和進階等學習資料和文章。