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.

posted on 2019-02-14 14:12  duanxz  阅读(935)  评论(0编辑  收藏  举报