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.

相关文章
相关标签/搜索