Kong(V1.0.2)loadbalancing

介紹

Kong爲多個後端服務提供了多種負載平衡請求的方法:一種簡單的基於DNS-based的方法,以及一種更動態的環形負載均衡器ring-balancer,它還容許在不須要DNS服務器的狀況下使用service registry。ios

DNS-based loadbalance

當使用基於DNS-based的負載均衡時,後端服務的註冊是在Kong以外完成的,Kong只從DNS服務器接收更新。算法

若是主機名解析爲多個IP地址,則使用包含主機名(而不是IP地址)的主機定義的每一個服務將自動使用基於DNS-based的負載平衡,前提是主機名不解析爲upstream 名稱或DNS主機文件中的名稱。後端

DNS記錄ttl設置(生存時間)決定刷新的頻率。當ttl爲0時,每一個請求每次都將使用本身的DNS查詢來解析。很明顯,這將帶來性能損失,可是更新/更改的延遲很是低。api

A記錄

一條記錄包含一個或多個IP地址。所以,當hostname 解析爲a記錄時,每一個後端服務必須有本身的IP地址。緩存

由於沒有權重信息,因此在負載均衡器中全部條目的權重都是相等的,均衡器將執行直接的循環。bash

SRV記錄

SRV記錄包含其全部IP地址的權重和端口信息。後端服務能夠經過IP地址和端口號的惟一組合來標識。所以,一個IP地址能夠在不一樣的端口上承載相同服務的多個實例。服務器

由於權重信息是可用的,因此每一個條目將在負載均衡器中得到本身的權重,並執行加權循環。cookie

相似地,來自DNS服務器的端口信息將覆蓋任何給定的端口信息。若是一個服務具備host=myhost.com和port=123的屬性,而且myhost.com解析爲一個SRV記錄127.0.0.1:456,那麼請求將被代理到http://127.0.0.1:456/somepath,由於端口123將被456覆蓋。負載均衡

 

DNS優先級

DNS解析器將開始解析如下記錄類型,順序以下:dom

  1. 前面解析的最後一個成功類型
  2. SRV記錄
  3. 一個記錄
  4. CNAME記錄

此順序可經過dns_order configuration property進行配置。

DNS警告

  • 每當刷新DNS記錄時,都會生成一個列表來正確處理權重。儘可能保持權重做爲彼此保持算法性能的倍數,例如,兩個權重17和31將轉化爲527的entries ,而權重16和32(或最小等價1和2)會致使結構僅僅3entries ,尤爲是在一個很是小的(甚至0)ttl值。
  • 某些命名服務器不返回全部entries (因爲UDP包的大小),在這種狀況下(例如,Consul 返回最多3entries ),給定的Kong節點將只使用由nameserver提供的少數上游服務實例。在此場景中,上游實例池的加載可能不一致,由於因爲nameserver提供的信息有限,Kong節點實際上並不知道某些實例。爲了減小這種狀況,可使用不一樣的名稱服務器,使用IP地址而不是名稱,或者確保使用足夠的Kong節點來仍然使用全部上游服務。
  • 當nameserver返回3個名稱錯誤時,這是對Kong的有效響應。若是這是意外的,首先驗證查詢的名稱是否正確,而後檢查nameserver配置。
  • 從DNS記錄(A記錄或SRV)中初始選擇IP地址不是隨機的。所以,當使用ttl爲0的記錄時,nameserver將隨機化記錄entries。

Ring-balancer

當使用環形負載均衡器時,後端服務的添加和刪除將由Kong處理,不須要DNS更新。Kong將擔任服務註冊。節點能夠經過單個HTTP請求添加/刪除,並當即啓動/中止接收流量。

經過upstream 和target entities配置環形負載均衡器。

target:帶有後端服務所在端口號的IP地址或主機名,例如。「192.168.100.12:80」。每一個目標得到一個額外的權重,以指示它得到的相對負載。IP地址能夠是IPv4和IPv6格式。

upstream:能夠在Route hiost字段中使用的「虛擬主機名」,例如,upstream名爲weather.v2的上游服務將從得到全部帶參數host=weather.v2.service的請求。

upstream

每一個上游都有本身的環形負載均衡器。每一個upstream能夠有許多target entries,代理到「虛擬主機名」的請求將在目標上進行負載平衡。一個環形負載均衡器有預先定義的槽數,而且根據目標權重,槽被分配給upstream的目標。

能夠經過管理API上的簡單HTTP請求來添加和刪除目標。這個操做相對簡單。更改upstream自己的開銷更大,例如,當槽數發生變化時須要從新構建負載均衡器。

只有在清理目標歷史記錄時,纔會自動從新構建均衡器;除此以外,它只會在更改的基礎上從新構建。

在負載均衡器中有位置(從1到slots),它們隨機分佈在環上,爲了在運行時廉價地調用環形負載均衡器,須要隨機性。一個簡單的輪詢(位置)就能夠在目標上提供一個分佈良好的加權輪詢,同時在插入/刪除目標時具備廉價的操做。

每一個目標使用的插槽的數量應該(至少)在100左右,以確保插槽是正確分佈的。如。對於最大指望的8個目標,上游應該定義至少插槽=800,即便初始設置只有2個目標。

這裏的權衡是插槽的數量越多,隨機分佈越好,可是更改(添加/刪除目標)的成本就越高

關於添加和操做上行流的詳細信息能夠在Admin API reference的上游部分中得到。

Target

由於upstream 維護更改的歷史記錄,因此只能添加、不能修改或刪除目標。要更改目標,只需爲目標添加一個新條目,並更改權重值。最後一個條目將被使用。所以,設置weight=0將禁用目標,從而有效地將其從均衡器中刪除。關於添加和操做目標的詳細信息能夠在Admin API reference的目標部分中找到。

當非活動條目比活動條目多10倍時,將自動清除目標。清理將涉及到從新構建均衡器,所以比僅僅添加目標條目更昂貴。

目標也能夠有主機名而不是IP地址。在這種狀況下,名稱將被解析,找到的全部條目將單獨添加到環均衡器中,例如,添加api.host.com:123和weight=100。名稱「api.host.com」解析爲包含兩個IP地址的A記錄。而後將兩個ip地址都添加爲目標,每一個ip地址的權值爲100,端口爲123。注意:權重用於單個條目,而不是整個條目!

若是它解析爲SRV記錄,那麼DNS記錄中的端口和權值字段也將被提取,並將否決給定的端口123和權值=100。

均衡器將尊重DNS記錄的ttl設置和請求,並在其到期時更新均衡器。

例外:當DNS記錄ttl=0時,主機名將做爲單個目標添加,並具備指定的權重。每當代理請求這個目標時,它將再次查詢名稱服務器。

Balancing算法

默認狀況下,環型均衡器將使用加權循環方案。另外一種選擇是使用基於哈希的算法。哈希的輸入能夠是none、consumer、ip、header或cookie。當設置爲none時,將使用加權循環方案,並禁用哈希。

有兩個選項,主服務器失敗時的主服務器和回退服務器(例如,若是主服務器被設置爲使用者,可是沒有通過身份驗證的使用者)

不一樣的哈希選項:

  • none:不要使用散列,而是使用加權循環(默認)。
  • consumer:使用consumer id做爲散列輸入。若是沒有可用的consumer id(對於ldap之類的外部身份驗證),則此選項將回退到憑據id上。
  • ip:將使用遠程(原始)ip地址做爲輸入。在使用此選項時,請檢查肯定實際IPdetermining the real IP的配置設置。
  • header:使用指定的header(在hash_on_header或hash_fallback_header字段中)做爲散列的輸入。
  • cookie:使用指定的cookie名稱(在hash_on_cookie字段中)和指定的路徑(在hash_on_cookie_path字段中,默認爲「/」)做爲哈希的輸入。若是cookie不在請求中,它將由響應設置。所以,若是cookie是主要的散列機制,則hash_fallback設置無效。

哈希算法基於「一致性哈希」(或「ketama原則」),它確保當均衡器經過更改目標(添加、刪除、失敗或更改權重)進行修改時,只會發生最小數目的哈希損失。這將最大化上游緩存命中。

有關確切設置的更多信息,請參見Admin API reference的上游部分

Balancing caveats

環型均衡器被設計成既能夠在單個節點上工做,也能夠在集羣中工做。對於加權循環算法來講差異不大,可是在使用基於散列的算法時,重要的是全部節點構建徹底相同的環平衡器,以確保它們的工做方式徹底相同。爲此,必須以肯定的方式構建均衡器。

  • 不要在均衡器中使用主機名,由於均衡器可能/將緩慢地偏離,由於DNS ttl只有第二次精度,而且更新取決於實際請求名稱的時間。最重要的是一些nameserver不返回全部條目的問題,這加重了這個問題。所以,在Kong集羣中使用散列方法時,只根據目標實體的IP地址添加它們,而不按名稱添加。
  • 當選擇哈希輸入時,確保輸入有足夠的方差來獲得一個分佈良好的哈希。散列將使用CRC-32摘要計算。所以,例如,若是您的系統有數千個用戶,但每一個平臺只定義了幾個consumer(例如。3 consumers:Web, iOS和Android)而後選擇consumer哈希輸入是不夠的,使用遠程IP地址經過設置哈希爲IP將提供更多的輸入方差,所以在哈希輸出更好的分佈。然而,若是許多客戶端位於相同的NAT網關以後(例如在呼叫中心),cookie將提供比ip更好的分佈。

Blue-Green Deployments

Using the ring-balancer a blue-green deployment can be easily orchestrated for a Service.切換目標基礎設施只須要對服務發出補丁請求,以更改其主機值。

Set up the 「Blue」 environment, running version 1 of the address service:

# create an upstream 
curl -X POST http://kong:8001/upstreams \ --data "name=address.v1.service" # add two targets to the upstream 
curl -X POST http://kong:8001/upstreams/address.v1.service/targets \ --data "target=192.168.34.15:80" --data "weight=100" 
curl -X POST http://kong:8001/upstreams/address.v1.service/targets \ --data "target=192.168.34.16:80" --data "weight=50" # create a Service targeting the Blue upstream 
curl -X POST http://kong:8001/services/ \ --data "name=address-service" \ --data "host=address.v1.service" \ --data "path=/address" # finally, add a Route as an entry-point into the Service 
curl -X POST http://kong:8001/services/address-service/routes/ \ --data "hosts[]=address.mydomain.com" 

將host header設置爲address.mydomain.com的請求如今將由Kong代理到兩個已定義的目標;2/3的請求將訪問http://192.168.34.15:80/address (weight=100), 1/3的請求將訪問http://192.168.34.16:80/address (weight=50)。

在部署address服務的版本2以前,設置「綠色」環境:

# create a new Green upstream for address service v2 
curl -X POST http://kong:8001/upstreams \ --data "name=address.v2.service" # add targets to the upstream 
curl -X POST http://kong:8001/upstreams/address.v2.service/targets \ --data "target=192.168.34.17:80" --data "weight=100" 
curl -X POST http://kong:8001/upstreams/address.v2.service/targets \ --data "target=192.168.34.18:80" --data "weight=100" 

To activate the Blue/Green switch, we now only need to update the Service:

# Switch the Service from Blue to Green upstream, v1 -> v2 
curl -X PATCH http://kong:8001/services/address-service \ --data "host=address.v2.service" 

將host header信息設置爲address.mydomain.com的傳入請求如今將由Kong代理到新目標;其中1/2的請求將訪問http://192.168.34.17:80/address (weight=100),另外1/2的請求將訪問http://192.168.34.18:80/address (weight=100)。

與往常同樣,經過Kong Admin API進行的更改是動態的,將當即生效。不須要從新加載或從新啓動,也不會刪除正在處理的請求。

Canary Releases 金絲雀的版本

Using the ring-balancer, target weights 能夠顆粒狀調整,容許平穩、可控的金絲雀發佈canary release.

Using a very simple 2 target example:

# first target at 1000 
curl -X POST http://kong:8001/upstreams/address.v2.service/targets \ --data "target=192.168.34.17:80" --data "weight=1000" # second target at 0 
curl -X POST http://kong:8001/upstreams/address.v2.service/targets \ --data "target=192.168.34.18:80" --data "weight=0" 

經過重複請求,但每次更改權重,流量將緩慢地路由到另外一個目標。例如,設置爲10%:

# first target at 900 
curl -X POST http://kong:8001/upstreams/address.v2.service/targets \ --data "target=192.168.34.17:80" --data "weight=900" # second target at 100 
curl -X POST http://kong:8001/upstreams/address.v2.service/targets \ --data "target=192.168.34.18:80" --data "weight=100" 

The changes through the Kong Admin API are dynamic and will take effect immediately. No reload or restart is required, and no in progress requests will be dropped.

相關文章
相關標籤/搜索