1. 程式人生 > >Consul負載均衡策略

Consul負載均衡策略

Consul是一個免費的開源工具,它提供了服務發現、健康檢查、負載均衡和全域性分散式的鍵值儲存。此外,它還提供了一組用於構建編排工作流和工具的原型。在微服務體系架構中,應用程式通常執行在許多IP地址上,並繫結到各種埠。服務發現有助於發現這些不同的服務,而不管它們位於何處。

由於同一服務的多個例項常常在微服務體系架構中同時執行,因此我們需要一種策略,以便在處理健康狀態的更改、例項數量的更改和叢集狀態的更改時,均衡地平衡服務的所有健康例項的流量。這是負載均衡層的工作。本文討論了在微服務體系架構中與Consul負載均衡的一些常見策略。

Consul Directly

與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或域字尾是可配置的,但預設值是.consul。以TLD結尾的任何請求都將被解析到Consul。.service

名稱空間告訴Consul查詢服務(與機器節點相對照)。backend 是要查詢的服務的名稱。請求“backend.service.consul"解析到一組IP地址,就像請求“www.hashicorp.com”解析到一組IP地址一樣。然而,對於Consul,解析發生在服務發現層,並整合到健康檢查機制中。

每當應用程式或核心解析這個DNS條目時,它將收到一組IP地址的隨機round-robin響應,這些地址對應於叢集中的健康服務。DNS介面基本上提供了與任何應用程式的零接觸服務發現整合。

優點

  • 不依賴外部工具或程序
  • 不需要監視或維護其他服務
  • 預設高度可用
  • 儘可能接近實時
  • DNS很容易使用,工作量很小
  • 健康檢查是分散式的,叢集負載最小

缺點

  • 單點故障——即使Consul在預設情況下高度可用,如果Consul不可用或不可訪問,這種模式不會提供故障轉移
  • 要求直接在應用程式中使用HTTP API或進行DNS查詢,並假設埠或進行兩個DNS查詢以查詢地址和埠
  • 應用程式和Consul之間的緊耦合

Fabio

Fabio是一個開源工具,它為Consul管理的服務提供了快速、現代、零配置負載均衡HTTP(S)和TCP路由器。使用者註冊服務和健康檢查到Consul,fabio將自動路由流量到他們,不需要額外的配置。

使用者註冊一個以urlprefix-開頭的標籤的服務,例如:

urlprefix-/my-service

在本例中,當對fabio 發出/my-service請求時,fabio將自動將流量路由到叢集中的健康服務。Fabio還支援更高階的路由配置

優點

  • 與Consul的豐富整合
  • 比DNS方法更能控制負載均衡
  • 在GitHub上超過4000星的支援和採用
  • 支援TCP代理
  • 訪問日誌和許多其他很棒的特性
  • 整合HashiCorp Vault
  • 用於路由視覺化的可選Web UI
  • 非常詳細的開源文件

缺點

  • 需要額外的服務來執行和監視
  • 與Consul和Consul標籤緊耦合

Nginx/HAProxy與Consul模板

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叢集帶來巨大的壓力
  • 實踐“每個容器一個服務”正規化具有挑戰性
  • 一個“flappy”叢集(一個服務在健康和不健康之間切換的叢集,或者一個持續快速變化的叢集)可能會導致Nginx/HAproxy配置的不穩定性

Nginx自定義模組

最近,我制定了一個目標,試圖從等式中刪除 Consul Template,但要保持Nginx經過時間考驗的靈活性和熟悉性。社群內有一些非常有趣和創新的方法,即:

最終,這些方法要麼涉及太多的活動部件,要麼包含超出Consul公司基本服務發現範圍的特性。因此,我編寫了ngx_http_consul_backend_module模組,該模組對每個nginx請求動態地選擇上游。

就像這樣:

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、陳舊的查詢以及更多開箱即用的東西

缺點

  • 需要從原始碼編譯Nginx以安裝自定義模組
  • 每個請求呼叫Consul到後端(每個請求吃掉請求的RTT和Consul解決方案的RTT)
  • 需要了解Nginx定製模組的知識
  • 不與Vault整合TLS私鑰或共享密碼
  • 模組還沒有經過實戰測試

HAProxy 1.8

HAProxy 1.8(目前是本文撰寫時的釋出候選版本)添加了內建功能,無需使用第三方工具或模組,即可通過DNS找到服務。HAProxy已經有內建DNS解析器一段時間了,但是HAProxy 1.8通過SRV記錄和EDNS的支援為埠帶來了解析,使其與Consul完美地匹配。

優點

  • 沒有外部工具-只是執行HAProxy和直接指向Consul
  • 優雅的處理過載,TTLs等
  • 支援Kubernetes和Docker群集服務發現

缺點

  • 需要HAProxy
  • 在失敗場景上的靈活性不如Consul Template

結論

Consul負載均衡的微服務應用有很多策略和技術。這篇文章詳細介紹了一些最常見的技術,並希望能夠激發靈感,找到新的和令人興奮的方法來整合行業標準負載平衡工具和Consul。無論您是直接使用Consul,橋接與Consul Template的差距,編譯自定義的Nginx自己,或嘗試HAProxy 1.8釋出候選,我們期待聽到您如何平衡您的微服務負載。