API网关Kong学习笔记(十六): Kong转发请求的工作过程

Tags: kong 

目录

说明

刚刚(2018-11-20 17:11:36)才发现kong的网页上有一篇文档非常详细的介绍了kong转发请求的过程:Kong: Proxy Reference

相关笔记

2019-05-06 16:28:56:kong 1.1.x有了一个重大变换,实现了db-less模式,可以不使用数据库了,见笔记二十六:查看全部笔记如果是刚开始学习kong,直接从1.x开始,0.x已经不再维护,0.15是0.x的最后一个版本。

前19篇笔记是刚开始接触kong时记录的,使用的版本是0.14.1,当时对kong一知半解,笔记比较杂乱。第二十篇开始是再次折腾时的笔记,使用的版本是1.0.3,笔记相对条理一些。

从0.x到1.x需要关注的变化有:

  1. 插件全部使用pdk
  2. 0.x中不鼓励使用的特性都被移除了;
  3. 全部使用kong.db,以前独立的dao彻底清除,代码简洁清晰了。

需要考虑的一些问题

怎样设置会话粘连?

可以通过哈希设置,比如说按照consumer、ip、header、cookie中的一个进行hash,使得有相同的特征的请求被同一个后端服务处理。

upstream中设置。

从 Route 到 Service

Route是kong的代理规则,定义了哪些请求代理给哪些service,以请求的方法、host、路径等作为转发依据,见Route的配置

Route与Service是多对一的关系,多个Route可以对应一个Service,每个Route中定义一种类型的Path。

Route中host匹配的是请求中的host,可以使用通配符*,但只能使用一个,可以是前匹配或者后匹配:

{
    "hosts": ["*.example.com", "service.com"]
}

Route将请求代理给Service时,默认将请求头中的host修改为Route中配置的host,如果不希望这样,可以设置preserve_host,使用原始请求头中的host。

Route的path可以是正则表达式,正则表达式的优先级低于非正则表达式描述的path。如果同一个url能匹配多个path,非正则表达式描述的path选用最长匹配,并且优先级高于正则表达式,正则表达式描述的path需要明确设置优先级regex_priority,按照设置的优先级选择。

正则语法为PCRE,并且使用正则表达式描述的path支持捕获,捕获的数据位于ngx.ctx.route_matches中,可以在代码中获取:

--/version/(?<version>\d+)/users/(?<user>\S+)
--/version/1/users/john
local route_matches = ngx.ctx.route_matches

-- route_matches.uri_captures is:
-- { "1", "john", version = "1", user = "john" }

从Route将请求转发给Service时,默认使用原始的path,不做更改,如果设置了strip_path,会将path修改,去掉匹配的部分。

Route中的匹配条件有hostpathmethod三个,条件越多的Route的优先级越高。可以创建一个优先级最低的Route作为最后的“兜底”Route:

{
    "paths": ["/"],
    "service": {
        "id": "..."
    }
}

从 Service 到 Upstream

每个Service对应一个upstream,service中配置了对应的upstream的host、port、path等,也就是upstream的地址,以及相关的访问参数,见Service的定义

Service中的Host可以不是Upstream的名字,可以是一个外部的域名,这样请求直接被转发给外部。

Upstream就是隐藏在kong后面的服务,它的name就是Service中的host,upstream中配置的是负载均衡算法,以及健康检查等,这些配置针对的是upstream关联的Target

代理请求的时候有一些参数设置,例如下面的默认超时时间:

upstream_connect_timeout    默认60000毫秒
upstream_send_timeout       默认60000毫秒
upstream_read_timeout       默认60000毫秒

这些参数都是在Service中配置的,除了超时时间,还有重试次数等。

将请求转发给Upstream的时候使用HTTP/1.1,并且会请求头中设置下面的字段:

Host: <your_upstream_host>
Connection: keep-alive
X-Forwarded-For: <address>
X-Forwarded-Proto: <protocol>
X-Forwarded-Host: <host>
X-Forwarded-Port: <port>

如果是websocket请求,kong会设置下面的请求头,升级为websocket连接:

Connection: Upgrade
Upgrade: websocket

将Upstream的响应返回的时候,会在响应头中设置字段:

Via: kong/x.x.x
X-Kong-Proxy-Latency: <latency>
X-Kong-Upstream-Latency: <latency>

从 Upstream 到 Target

对请求进行代理的时候,主要有两项处理,一是进行负载均衡,二是调用插件进行处理。

一个Upstream可以包含多个Target,负载均衡的过程,就是为当前的请求选择一个Target的过程。

Target是IP或者host加端口,是提供服务的最小单位,每个target可以设置不同的权重:

{
    "target": "1.2.3.4:80",
    "weight": 15,
    "upstream_id": "ee3310c1-6789-40ac-9386-f79c0cb58432"
}

第一种负载均衡方式是通过DNS进行负载均衡,这是Service中直接配置的是外部服务的域名或者IP,而不是Upstream的name的时候,可以采用的方法。

这种方式其实是把负载均衡放在kong外部做的,kong只需要把请求转发给对应域名,具体的负载均衡方法在DNS中设置,涉及不到Upstream和Target,kong的文档中把这也算作一种kong的负载均衡方法。

第二种方式是Ring-balancer,这种方式是kong管理的,kong相当于一个服务注册中心,负责动态增删后端服务(也就是Target),以及平衡负载,这种方式通过upstreamtarget设置。

Upstream是对多个target封装,多个target封装成一个虚拟的host,这个虚拟的host就是upstream的name,被用在Service的host中。

每个upstream中有一个预先设置好的slot数量,upstream中的多个target按照各自的权重分到slot中的一块,slot需要是预计的target数量的100倍。

Target可以通过admin api进行增加、删除,变更target的开销很小,upstream变更的开销比较大,因为涉及到slot的重新分配。

Target的权重设置为0,target将不被选用。

Upstream的api

Target的api

负载均衡算法默认是带有权重的轮询(weighted-round-robin ),除此之外还可使用hash的方式,hash的输入可以是:none(不使用hash的方式), consumer, ip, header, cookie。

使用hash方式的时候,要注意,第一,target地址要使用IP,不能是域名,域名解析会带来开销,而且有些域名服务器不会返回所有可用IP,第二,选择的hash输入要是足够变化多端的,使hash的输出要足够分散。

负载均衡的细节参考Loadbalancing reference

蓝绿部署

蓝绿的切换只需要修改service关联的upstream即可,一个“蓝色”的upstream,一个“绿色”的upstream,蓝绿切换的时候,两个upstream使用不同的名字和不同的target。

蓝绿切换的时候直接修改service中的host即可。

金丝雀部署

金丝雀部署通过修改target的权重即可实现,target的权重设置为零,则不被使用,权重越高分担的流量越高。

Target的健康检查

Target的健康检查是一个有坑的地方,Health Checks and Circuit Breakers中有具体描述。

健康检查在Upstream中配置,有主动(active)和被动(passive)两种方式。

主动方式是按照配置的,定时访问Target,判断Target是否存货。Paasive的方式被动响应结果,如果发现失败的响应,则将对应的Target标记为失败。

第一个坑是,健康检查需要配置,如果不配置,默认就没有健康检查。

第二个坑是,如果只使用被动的方式,当一个Target被认为失败后,就会一直被认为失败,修复以后,必须手动发起一次访问,才能将其重新加载负载均衡列表中:

$ curl -i -X POST http://localhost:8001/upstreams/my_upstream/targets/10.1.2.3:1234/healthy
HTTP/1.1 204 No Content

一定要配置健康检查,并且最好使用主动的方式。

SSL配置

首先要创建certificates对象,certificate包含证书和私钥,以及snis,snis指定了证书绑定的host。

$ curl -i -X POST http://localhost:8001/certificates \
    -F "cert=@/path/to/cert.pem" \
    -F "key=@/path/to/cert.key" \
    -F "snis=ssl-example.com,other-ssl-example.com"
HTTP/1.1 201 Created
...

使用了snis中的host的route,可以通过https协议访问。

可以在route中配置接受的协议类型,如果只配置了http,那么http和https协议都接受,如果只配置了https,只接受https协议:

{
    "hosts": ["..."],
    "paths": ["..."],
    "methods": ["..."],
    "protocols": ["http", "https"],
    "service": {
        "id": "..."
    }
}

参考

  1. Kong: Proxy Reference
  2. Health Checks and Circuit Breakers

kong

  1. API网关Kong学习笔记(二十六): Kong 1.1引入db-less模式,无数据库部署
  2. API网关Kong学习笔记(二十五): 重温 kong ingress controller
  3. API网关Kong学习笔记(二十四): 在kubernetes中启用kong的插件
  4. API网关Kong学习笔记(二十三): Kong 1.0.3的plugin/插件机制的实现
  5. API网关Kong学习笔记(二十二): Kong 1.0.3源代码快速走读
  6. API网关Kong学习笔记(二十一): Kong的开发环境设置(IntelliJ Idea)
  7. API网关Kong学习笔记(二十): Kong 1.0.3的安装部署和与Kubernetes的对接
  8. API网关Kong学习笔记(十九): Kong的性能测试(与Nginx对比)
  9. API网关Kong学习笔记(十八): Kong Ingress Controller的CRD详细说明
  10. API网关Kong学习笔记(十七): Kong Ingress Controller的使用
  11. API网关Kong学习笔记(十六): Kong转发请求的工作过程
  12. API网关Kong学习笔记(十五): KongIngress的定义细节
  13. API网关Kong学习笔记(十四): Kong的Admin API概览和使用
  14. API网关Kong学习笔记(十三): 向数据库中插入记录的过程分析
  15. API网关Kong学习笔记(十二): 插件的目录中schema分析
  16. API网关Kong学习笔记(十一): 自己动手写一个插件
  17. API网关Kong学习笔记(十): Kong在生产环境中的部署与性能测试方法
  18. API网关Kong学习笔记(九): Kong对WebSocket的支持
  19. API网关Kong学习笔记(八): Kong Ingress Controller的实现
  20. API网关Kong学习笔记(七): Kong数据平面Plugin的调用与实现
  21. API网关Kong学习笔记(六): Kong数据平面的事件、初始化与插件加载
  22. API网关Kong学习笔记(五): 功能梳理和插件使用-安全插件使用
  23. API网关Kong学习笔记(四): 功能梳理和插件使用-认证插件使用
  24. API网关Kong学习笔记(三): 功能梳理和插件使用-基本使用过程
  25. API网关Kong学习笔记(二): Kong与Kubernetes集成的方法
  26. API网关Kong学习笔记(一): Nginx、OpenResty和Kong入门,基础概念和安装部署
  27. API网关Kong学习笔记(零): 使用过程中遇到的问题以及解决方法

推荐阅读

Copyright @2011-2019 All rights reserved. 转载请添加原文连接,合作请加微信lijiaocn或者发送邮件: [email protected],备注网站合作

友情链接:  系统软件  程序语言  运营经验  水库文集  网络课程  微信网文  发现知识星球