Kong(V1.0.2)loadbalancing

介绍

Kong为多个后端服务提供了多种负载平衡请求的方法:一种简单的基于DNS-based的方法,以及一种更动态的环形负载均衡器ring-balancer,它还允许在不需要DNS服务器的情况下使用service registry。

DNS-based loadbalance

当使用基于DNS-based的负载均衡时,后端服务的注册是在Kong之外完成的,Kong只从DNS服务器接收更新。

如果主机名解析为多个IP地址,则使用包含主机名(而不是IP地址)的主机定义的每个服务将自动使用基于DNS-based的负载平衡,前提是主机名不解析为upstream 名称或DNS主机文件中的名称。

DNS记录ttl设置(生存时间)决定刷新的频率。当ttl为0时,每个请求每次都将使用自己的DNS查询来解析。很明显,这将带来性能损失,但是更新/更改的延迟非常低。

A记录

一条记录包含一个或多个IP地址。因此,当hostname 解析为a记录时,每个后端服务必须有自己的IP地址。

因为没有权重信息,所以在负载均衡器中所有条目的权重都是相等的,均衡器将执行直接的循环。

SRV记录

SRV记录包含其所有IP地址的权重和端口信息。后端服务可以通过IP地址和端口号的唯一组合来标识。因此,一个IP地址可以在不同的端口上承载相同服务的多个实例。

因为权重信息是可用的,所以每个条目将在负载均衡器中获得自己的权重,并执行加权循环。

类似地,来自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解析器将开始解析以下记录类型,顺序如下:

  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.

原文地址:https://www.cnblogs.com/duanxz/p/10374305.html