Consul是一個免費的開源工具, 它提供服務發現、健康檢查、負載均衡和全域性分佈的鍵值儲存。此外, 它還提供了一組用於構建業務流程工作流和工具的基礎元素。在微服務體系結構中, 應用程式通常跨越多個IP地址執行, 並繫結到各種埠。服務發現有助於查詢這些不同的服務, 而不管它們位於何處。
由於同一個服務的多個例項通常同時執行在微服務體系結構中, 因此在例項健康變化時,例項數量變化時,以及叢集狀態變化時,我們需要一種策略去平等地均衡所有到健康例項的流量。這就是負載均衡層的工作。本文討論了在微服務體系結構中與Consul進行負載均衡的幾種常用策略。
直接使用Consul
對Consul進行負載均衡的一種方法是使用Consul的內建負載均衡功能。Consul將健康檢查與服務發現結合在一起。這意味著不健康的主機永遠不會通過查詢返回到服務發現層。在這種模式下, 每次應用程式和服務希望在資料中心查詢其他服務時,他們直接與Consul進行對話。
請考慮以下配置檔案, 其中包括某個後端服務的IP地址:
services:
backend: 10.2.5.391
複製程式碼
通常情況下,對於IP地址進行硬編碼(尤其是在微服務體系結構中),被認為是一種不好的做法。隨著應用程式在整個系統中執行, 將此配置檔案保持為最新, 尤其是在計算機叢集上,變得非常困難。相反, 更好的方法是利用Consul的DNS發現層。
services:
backend: backend.service.consul
複製程式碼
就像"www.hashicorp.com"是一個web地址, "backend.service.consul"也是。這裡,TLD 或域字尾(domain suffix)是可配置的, 但預設值為.Consul。任何以該TLD結尾的請求都將被解析到Consul。這裡.service名稱空間告訴Consul查詢服務 (而不是機器的節點),. backend是要查詢的服務的名稱。對 "backend.service.consul"的請求被解析到一組IP地址, 就像"www.hashicorp.com"被解析為一組IP地址一樣。然而, 對於Consul, 該解析發生在服務發現層,並整合了健康檢查機制。
每次應用程式或核心解析該DNS條目時, 它都會收到一個與叢集中的健康服務對應的 IP 地址列表的隨機迴圈(round-robin)響應。DNS介面基本上提供了零配置(zero-touch)服務發現,並能整合到任何應用程式中。
優點:
- 不依賴外部工具或流程
- 沒有其他服務用於監視或維護
- 預設情況下高度可用
- 儘可能接近實時
- DNS易於使用, 工作量極小
- 健康檢查是分散式的, 叢集負載極小
缺點:
- 單點故障-即使Consul在預設情況下是高度可用的, 但如果Consul不可用或無法訪問, 此模式不提供故障轉移
- 要求在應用程式中直接使用HTTP API, 或進行 DNS 查詢, 假定埠或進行兩個 DNS 查詢以查詢地址和埠
- 應用與Consul強耦合
Fabio
Fabio是一個開源工具, 它為Consul管理的服務提供快速、現代、零配置的負載均衡HTTP(s)和TCP路由器。使用者在Consul註冊服務,並提供健康檢查,Fabio將自動把流量路由到他們。不需要額外配置。
使用者註冊一項服務, 採用以urlprefix-開頭的tag, 如:
urlprefix-/my-service
複製程式碼
在本示例中, 當在/my-service上,對Fabio發出請求時, Fabio將自動將流量路由到叢集中的健康服務上。Fabio還支援更高階的路由配置。
優點:
- 與Consul豐富整合
- 比DNS方法更多控制負載均衡
- 強大的社群支援和超過4000的GitHub star
- 支援TCP代理
- 訪問日誌記錄和一系列其他令人稱讚的功能
- 整合HashiCorp Vault
- 用於路由視覺化的可選Web UI
- 非常詳細的開源文件
缺點:
- 需要額外的服務才能執行和監視
- 與Consul和Consul tag緊密耦合
Nginx/HAProxy with Consul Template
對Consul進行負載均衡的另一種方法是使用第三方工具 (如Nginx 或 HAProxy) 來平衡流量,並使用開源工具 (如Consul Template) 來管理配置。在這種模式下, Consul Template動態管理 nginx.conf 或 haproxy.conf配置檔案, 它定義負載均衡器和服務列表。此列表是模板化的, Consul Template作為服務執行以保持模板為最新。 Consul Template與Consul群集有持續的連線, 當服務池發生更改時, Consul Template會寫入一個新的配置檔案, 併發出訊號讓Nginx或HAProxy程式重新載入其配置。這裡是一個示例的Nginx的Consul Template模板:
upstream myapp {
{{ range service "myapp" }}
server {{ .Address }}:{{ .Port }}
{{ end }}
}
複製程式碼
在此示例中, Consul Template將監視所有名為 "myapp" 的服務。如果它們的任何狀態發生更改, Consul Template將產生一個新的配置檔案, 並指示 Nginx 程式重新載入。上面的模板在nginx.conf中呈現為這樣:
upstream myapp {
server 10.2.5.60:13845
server 10.6.96.234:45033
server 10.10.20.123:18677
}
複製程式碼
必須指出, 在這種模式下, Nginx 和 HAProxy 都不知道Consul的存在;它們只是讀取它們的配置, 就好像這些值是由操作員或配置管理工具硬編碼的一樣。
優點:
- 處理在非預設埠上執行的應用程式, 而無需額外的API 請求
- Nginx 和 HAProxy 都是經過線上考驗的工具
- 團隊可能已經擁有這些工具的專業知識或現有的基礎設施
- 如果Consul離線, 仍然有最後已知良好的服務狀態的一個記錄
- Consul template也可與Vault整合, 如果配置檔案具有像TLS 私鑰或共享密碼等機密資料時,這使得它一個理想的解決方案,。
缺點:
- 需要兩個額外的服務來管理和監視-Nginx/HAProxy 和Consul Template
- 由於阻塞查詢, 低效模板可能給Consul群集造成巨大壓力
- 對實踐 "一個容器一個服務" 正規化的挑戰
- 一個 "飛行豬" 群集 (服務在健康和不健康之間翻轉的群集或具有大量連續快速流失的群集) 可能導致 Nginx/HAproxy 配置不穩定
Nginx with Custom Module
最近, 我開始嘗試移除Consul Template, 但保持經過時間考驗的靈活性和熟悉度的Nginx。社會上有一些非常有趣和創新的做法, 即:
- Dynamic Nginx Upstreams for Consul via lua-nginx-module by Zachary Schneider
- Nginx upsync module
- Nginx Pro DNS resolution
- ngx_http_set_backend which inspired binding Nginx modules in C to Consul in Golang
最終, 這些方法要麼涉及太多的移動部件, 要麼包括Consul的基本服務發現之外的擴充套件功能。因此, 我寫的 ngx_http_consul_backend_module, 對於每個導向nginx的請求,動態選擇upstream。
它看起來這樣:
http {
server {
listen 80;
server_name example.com;
location /my-service {
consul $backend service-name;
proxy_pass http://$backend;
}
}
}
複製程式碼
對於每個請求, consul關鍵字告訴 Nginx 委託給自定義模組並選擇一個隨機的健康後端服務, 然後將請求代理到該後端服務。肯定有改進的地方, 但是這個概念驗證表明, 沒有中介工具,也 可能直接連線 Nginx 和Consul。
優點:
- 處理非預設埠上執行的應用程式, 而無需額外的 API 請求
- 沒有外部工具-只是執行 Nginx 並直接指向Consul
- 使用正式Consul SDK客戶端庫提供的HTTP/2、stale queries等等
缺點:
- 需要從原始碼編譯 Nginx 以安裝自定義模組
- 每個到後端的請求,呼叫Consul(每個請求需要消耗請求的RTT和Consul解析的RTT)
- 需要 Nginx 定製模組的知識來完成任務
- 對於TLS私鑰或共享密碼,不能與Vault整合
- 模組經過線上嚴苛測試 (尚未)
HAProxy 1.8
HAProxy 1.8 (當前在撰寫本篇文章時釋出的候選版本) 在不使用第三方工具或模組的情況下, 通過 DNS 新增了服務發現的內建功能。HAProxy 已經內建 DNS 解決方案有一段時間了, 但 HAProxy 1.8 通過 SRV 記錄和支援 EDNS 為埠帶來了解決方案, 使其與Consul完美配對。
優點:
- 沒有外部工具-只是執行HAProxy,並直接指向Consul
- 優雅的處理重新載入, TTLs 等。
- 也支援 Kubernetes 和Docker Swarm服務發現
缺點:
- 需要 HAProxy
- 相較於Consul Template,對於失敗場景,更少的靈活性
結論
對於採用Consul的應用,有許多負載均衡的策略和技術。這篇文章詳細介紹了一些最常見的技術, 並希望激發靈感, 以新的,振奮人心的方式整合行業標準的負載均衡工具和Consul。無論您是直接使用Consul, 彌合與Consul模板的差距, 編譯自己的Nginx定製版本, 或嘗試HAProxy 1.8候選釋出版本, 我們期待聽到您如何負載均衡您的微服務應用。
原文連結:www.hashicorp.com/blog/load-b…