Kong侦听四个端口的请求,默认情况是:

  8000:此端口是Kong用来监听来自客户端的HTTP请求的,并将此请求转发到您的上游服务。这也是本教程中最主要用到的端口。

  8443:此端口是Kong监听HTTP的请求的端口。该端口具有与8000端口类似的行为,但是它只监听HTTPS的请求,并不会产生转发行为。可以通过配置文件来禁用此端口。

  8001:用于管理员对KONG进行配置的端口。

  8444:用于管理员监听HTTPS请求的端口。

  在本文中,我们将介绍Kong的路由功能,并详细说明8000端口上的客户端请求如何根据请求头、URI或HTTP被代理到配置中的上游服务。

基础术语

  API:指Kong的API实例。您可以通过管理员身份配置您的API。

  Plugin:他指的是Kong的“插件”,它们是在代理生命周期中运行的业务逻辑。可以通过管理员身份进行全局配置,也可针对每个API进行分别配置。

  Client:指向Kong的代理端口发出请求的下游客户,即第三方客户端。

  Upstream service:指的是位于Kong后面的您自己的API服务,客户端请求被转发的最终目的地。nginx中的上游服务器。

概述

  从整体上来看,Kong侦听其配置的代理端口上的HTTP请求(默认为8000),并识别正在请求的是哪个上游服务,然后运行在该API上的配置插件(如果没有则不执行),并将上游的HTTP请求转发到您自己的API服务。

  当客户端向代理端口发出请求时,Kong将根据API在KONG里的配置情况,来决定将请求传入到哪个上游服务中。 您可以在KONG里对每个API添加许多属性,但是有三个是必须要配置的,他们是hosts、uris和methods。如果KONG无法确定API请求的上游服务地址,则会返回一下内容:

HTTP/1.1  Not Found
Content-Type: application/json
Server: kong/<x.x.x> {
"message": "no API found with those values"
}

回忆下:如何向KONG添加一个API

    在之前的添加一个API的指南中,有学习过如何使用8001端口,在KONG服务中添加一个API的操作:

$ curl -i -X POST http://localhost:8001/apis/ \
-d 'name=my-api' \
-d 'upstream_url=http://my-api.com' \
-d 'hosts=example.com' \
-d 'uris=/my-api' \
-d 'methods=GET,HEAD'
HTTP/1.1 Created
...

    该代码表示用户成功在Kong里注册一个名为“my-api”的API,可通过访问“http://example.com”发送请求。它还指定了一些HTTP请求的属性,但请注意,这里有且只有一个HOST,URIS和METHODS属性。当完成此配置后,以后所有的符合此host、uris和methods的请求,都将由KONG来代理过滤转发。Kong是一个透明的代理,它会将请求转发给您的上游服务,除了添加诸如Connection之类的各种标题。

转发功能

    现在我们来讨论一下,一个HTTP请求是如何与API配置属性(如host、uris、methods)相匹配的。需要注意的是,这三个字段(h、u、m)都是可选的,但至少要有一个被指定。对于客户端请求与API的匹配:

    · 请求必须包含所有已配置的字段

    · 请求中的字段值必须与至少一个已配置的值相匹配(尽管字段配置接受一个或多个值,请求只需要考虑匹配其中之一)

    让我们来看几个例子。请看如下一个API配置:

{
"name": "my-api",
"upstream_url": "http://my-api.com",
"hosts": ["example.com", "service.com"],
"uris": ["/foo", "/bar"],
"methods": ["GET"]
}

    与该API相匹配的一些请求可能是:

GET /foo HTTP/1.1
Host: example.com GET /bar HTTP/1.1
Host: service.com GET /foo/hello/world HTTP/1.1
Host: example.com

    以上的三个请求都满足API定义中设置的条件。但是,以下的几个请求则与配置的条件不匹配:

GET / HTTP/1.1
Host: example.com POST /foo HTTP/1.1
Host: example.com GET /foo HTTP/1.1
Host: foo.com

    以上的三个请求只满足两个配置条件。第一个请求的URI不匹配,第二个请求的HTTP方法不匹配,第三个请求的Host头不匹配。

    现在我们了解了hosts、uris、methods是如何一起工作的。下面我们来逐个了解他们是如何单独工作的。

    1. 请求的HOST头:

      基于HOST头发送请求,是通过KONG发送请求的最直接的一种方式,这也是HOST头的基本用法之一。KONG使通过HOST访问API实体的流程更加简便快捷。HOSTS 接受多种参数,当使用管理员API进行请求时,需要将每个参数间用逗号分隔开来配置:

$ curl -i -X POST http://localhost:8001/apis/ \
-d 'name=my-api' \
-d 'upstream_url=http://test-api.com' \
-d 'hosts=test-api.com,demo.com,service.com'
HTTP/1.1 Created
...

此时,客户端可使用 hosts=test-api.com, demo.com, service.com 中的任意一个HOST头对 my-api 进行访问,但不能缺省HOST的值。

    1.1 使用通配符查找主机名

  为了使代理更灵活,KONG允许使用通配符来配置HOSTS。通配符允许任何满足条件的HOST头对API实体进行访问。在配置通配符时,只允许在HOST的最左或最右配置一个星号(*),例如:

*.example.com :允许类似于 a.example.com 或 a.b.example.com 等形式的HOST头访问。
example.*   :允许类似于 example.a 或 example.b.cn 等形式的HOST头访问。

  一个完整的例子:

{
"name": "test-api",
"upstream_url": "http://test-api.com",
"hosts": ["*.example.com", "service.com"]
}

  匹配的HOST头请求类似于一下几种,但不限于一下的例子中的形式:

GET / HTTP/1.1
Host: an.example.com GET / HTTP/1.1
Host: service.com

    1.2. preserve_host属性

      当启用代理时,KONG默认将API的 upstream_url 的值配置为上游服务主机的 host 。preserve_host提供一个boolean值,对KONG的这个行为进行限制。例如,当使用preserve_host的默认值进行配置时,API的配置信息大致为:

{
"name": "my-api",
"upstream_url": "http://my-api.com",
"hosts": ["service.com"],
}

此时,客户端发送的请求信息格式大致为:

GET / HTTP/1.1
Host: service.com

KONG会从API的upstream_url中提取HOST值,在做代理时,会向上游服务发送类似的请求:

GET / HTTP/1.1
Host: my-api.com

然而,当管理员在配置API时,明确指定了preserver_host=true时:

{
"name": "my-api",
"upstream_url": "http://my-api.com",
"hosts": ["service.com"],
"preserve_host": true
}

并假设客户端发送了相同的请求:

GET / HTTP/1.1
Host: service.com

KONG将会保留客户端发送来的HOST值,在做代理时,会向上游服务发送以下的请求:

GET / HTTP/1.1
Host: service.com

    2 请求URI

      KONG将请求转发给上游服务的另一种方式,是通过配置uris属性来指定请求的URI值。uris可以配置多个值,此时客户端在进行请求时,必须选择uris中的一个值作为请求的前缀。

  例如,如果API的配置为:

{
"name": "my-api",
"upstream_url": "http://my-api.com",
"uris": ["/service", "/hello/world"]
}

  以下的几种请求方式都可以对此API进行访问:

GET /service HTTP/1.1
Host: my-api.com GET /service/resource?param=value HTTP/1.1
Host: my-api.com GET /hello/world/resource HTTP/1.1
Host: anything.com

  以上几种方式在进行请求时,KONG侦测到他们的前缀与API的uris属性值是匹配的,所以这些请求是可用的。

  当uris属性配置好后,在进行请求时,KONG首先会取最长的uris值对URI进行匹配筛选,如果未匹配,然后才会取次长度的uris值进行匹配,依次类推,直到匹配成功为止或拒绝访问。譬如上面的例子里,在发送请求时,KONG首先会取 `/hello/world` 与请求uri进行匹配,如果未成功,才会继续取 `/service` 继续匹配工作。

    2.1 strip_uri属性

      在配置API的uris时,如果你希望隐藏上游服务的真实uri,并以另外的一种URI提供给客户端时,通过简单的配置API的strip_uri属性就可以实现。例如:

{
"name": "my-api",
"upstream_url": "http://my-api.com",
"uris": ["/service"],
"strip_uri": true
}

  启用strip_uri属性来指示Kong在代理此API时,在上游请求的URI中不应包含匹配的URI前缀。针对上面的API配置,当客户端发送请求时

GET /service/path/to/resource HTTP/1.1
Host:

  KONG代理到上游服务的真实uri为(此时的uri不包含uris中配置的内容)

GET /path/to/resource HTTP/1.1
Host: my-api.com

    3. HTTP请求方法

      从KONG 0.10版本开始,可以通过配置API的methods属性来指定客户端的请求。默认情况下,无论HTTP请求方式如何,Kong都会将请求将其代理到API的。但是,当配置methods属性后,只有HTTP请求方式匹配时才会被KONG代理。methods属性可以配置多个值:

{
"name": "api-1",
"upstream_url": "http://my-api.com",
"methods": ["GET", "HEAD"]
}

  以下的两种HTTP请求方式都可以被代理

GET / HTTP/1.1
Host: HEAD /resource HTTP/1.1
Host:

  但是不会匹配POST或DELETE等其他的请求方式。配置此属性,可以更细粒度的管理你的API。

代理的优先级

      一个API可以通过配置hosts、uris和methods属性定义匹配规则。对于Kong来说,只有当所有的字段都匹配时,才会进行转发。然而,KONG允许两个或更多的API拥有相同的配置。此时,就涉及到请求的优先级问题了。

    匹配优先级原则是:在评估请求时,Kong会首先与匹配规则最多的API进行匹配(when evaluating a request, Kong will first try to match the APIs with the most rules.)。例如有两个API的配置如下

{
"name": "api-1",
"upstream_url": "http://my-api.com",
"hosts": ["example.com"]
}, {
"name": "api-2",
"upstream_url": "http://my-api-2.com",
"hosts": ["example.com"],
"methods": ["POST"]
}

  api-2比api-1多了一个methods配置,所以KONG会最先将请求与api-2进行匹配。通过此配置,我们就能避免在请求api-2时,错误的转发到api-1。

此时,这个请求会被转发到api-1:

GET / HTTP/1.1
Host: example.com

而这个请求,会被转发到api-2:

POST / HTTP/1.1
Host: example.com

  以此类推,如果一个api同时配置了hosts、methods、uris,则这个API会最先与请求进行匹配,他的优先级会是三个中最高的。

代理行为

  上述内容详细讲述了KONG将请求代理到上游服务的代理规则。下面我们将详细说明,在KONG将请求转发到上游服务的这段时间内实际发生的一些事。

  1. 负载平衡

    从KONG 1.10 版本开始,Kong继承实现了负载平衡的功能,可以将转发的请求分发到多个上游服务实例。在 Kong 0.10之前,一般情况下,Kong会将代理的请求转发到指定的upstream_url上,如果想实现服务的负载平衡,需要额外的工具来完成。您可以通过查阅负载平衡相关资料,找到更多有关向API添加负载平衡的信息。

  2. 插件扩展

    使用者可以通过plugins来自定义扩展插件,并将插件应用到request/response的生命周期中。插件可以在您的生产环境中对代理行为进行多种操作。通过对插件进行配置,可以将插件应进行全局应用或针对个别API应用。如果对给定的某个或某些API应用了一个插件或多个插件,则在代理请求到上游服务前,会首先执行API的匹配,匹配成功后再执行定义的插件,当插件执行完后,如果满足天剑,才会将请求最终代理到上游服务中去。这里包含了插件的访问时段的概念,具体参考插件开发配置相关资料。

  3. 代理或请求超时

    当KONG将所有的代理逻辑,包括API验证和插件等,都处理完后,才会将请求代理到上游服务。这些是通过Nginx的代理模块来实现的。从KONG 0.10开始,可以通过配置以下三个API属性来定义连接超时时间:

  upstream_connect_timeout: 定义同上游服务建立连接的超时时间,单位是毫秒,默认值为60000.

  upstream_send_timeout: 定义两个连续向上游服务发送的写入操作的超时时间,单位是毫秒,默认值为60000.

  upstream_read_timeout: 定义两个连续向上游服务发送读取操作的超时时间,单位是毫秒,默认值为60000.

    在使用HTTP/1.1时,KONG会默认添加以下请求头信息:

  HOST:<上游服务的host>

  Connection:keep-alive : 允许重复使用上游连接

  X-REAL-IP:<$proxy_add_x_forwarded_for>: 参见 nginx_http_proxy_module.

  X-Forwarded-Proto:<protocol>: protocol是客户端使用的协议名

    其他的请求头都按默认配置添加。

    当使用WebSocket时,会有例外发生。如果发生,KONG允许通过以下请求头对协议进行升级:

  Connection:Upgrade

  Upgrade:WebSocket

  4. Response

    Kong接收上游服务的响应,并以流式方式将其发回下游客户端。此时,Kong将执行添加到该特定API的后续插件,并且这些插件继承了header_filter子句。当所有继承了header_filter的插件执行完后,以下的几种头信息将返回给客户端:

  Via:kong/x.x.x KONG的版本信息,x.x.x是他的版本号。

  Kong-Proxy-Latency:<latency>,其中 latency 表示Kong接收来自客户端的请求并将请求发送到上游服务所消耗的时间值(毫秒)。

  Kong-Upstream-Latency:<latency>,其中 latency 表示Kong等待上游服务响应的第一个字节所消耗的时间数(毫秒)。

    当headers发送到客户端后,Kong将执行此API上已注册的、继承了body_filter的插件。body_filter将上游返回的数据成功处理后,然后再发送给客户端。

配置一个fallback API

  默认情况下,当向KONG发送请求时,如果请求失败,KONG会返回 HTTP 404,“API not found” 等信息。为了避免这种情况的发生,我们可以通过配置 fallback API 实现自定义 “异常\错误” 信息。

  下面是一个例子:

{
"name": "root-fallback",
"upstream_url": "http://www.error.page",
"uris": ["/"]
}

  观察此配置中的“uris”,会发现,此处配置“/”可以适配所有的请求,根据uris的匹配规则,每个请求都会首先匹配最长的uri,依次递减。所以当所有的uri都不匹配时,请求会自动转发到这里配置的上有服务中去,因此而实现了自定义 “异常\错误” 信息。

配置API的SSL

  Kong提供了一种在每个连接的基础上动态提供SSL证书的方法。从0.10版本开始,SSL插件已被删除,SSL证书由内核直接处理,并可通过Admin API进行配置。你的客户端HTTP库必须支持SNI(Server Name Indication)扩展以确保SSL可用。

  SSL证书由Kong Admin API的两个资源处理:

    · /certificates  存储您的密钥和证书。

    · /snis  将注册的证书与服务器名称指示相关联。

  以下是为给定的API配置SSL证书的方法:

    首先,通过Admin API上传SSL证书和密钥:

$ 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 Created
...

  snis是加密参数,直接插入SNI并将上传的证书与之相关联。

  您现在必须在Kong内注册以下API。为方便起见,我们将使用Host头将请求转发到此API:

$ curl -i -X POST http://localhost:8001/apis \
-d "name=ssl-api" \
-d "upstream_url=http://my-api.com" \
-d "hosts=ssl-example.com,other-ssl-example.com"
HTTP/1.1 Created
...

  好了,现在你可以向KONG发送HTTPs请求了:

$ curl -i https://localhost:8443/ \
-H "Host: ssl-example.com"
HTTP/1.1 OK
...

  1. https_only参数:

    如果你希望仅通过HTTPS提供API,可以通过启用其https_only属性来实现:

$ curl -i -X POST http://localhost:8001/apis \
-d "name=ssl-only-api" \
-d "upstream_url=http://example.com" \
-d "hosts=my-api.com" \
-d "https_only=true"
HTTP/1.1 Created
...

    这样配置后,KONG将拒绝代理非HTTPS的请求。如果此时使用HTTP请求来访问这个API,KONG会提示用户需要将客户端升级到HTTPS:

$ curl -i http://localhost:8000 \
-H "Host: my-api.com"
HTTP/1.1
Content-Type: application/json; charset=utf-
Transfer-Encoding: chunked
Connection: Upgrade
Upgrade: TLS/1.2, HTTP/1.1
Server: kong/x.x.x {"message":"Please use HTTPS protocol"}

  2. http_if_terminated参数:

    当API被锁定在HTTPS请求时,如果你想在请求头信息中添加X-Forwarded-Proto,只要为API配置http_if_terminated属性即可:

$ curl -i -X PATCH http://localhost:8001/apis/ssl-only-api \
-d "http_if_terminated=true"
HTTP/1.1 OK
...

    并且我们使用X-Forwarded-Proto(假设它来自可信任的客户端)发出请求:

$ curl -i http://localhost:8000 \
-H "Host: my-api.com" \
-H "X-Forwarded-Proto: https"
HTTP/1.1 OK
...

    Kong现在代理了这个请求,因为它假定你的体系结构的先前组件已经实现了SSL。

代理WebSocket

  由于KONG的底层实现了Nginx,所以他也支持WebSocket。如果你希望在客户端和KONG之间建议一个WebSocket连接,那么你必须首先建立一个WebSocket握手。这个通过HTTP Upgrade机制完成。这个可以通过客户端对KONG进行操作,例如:

GET / HTTP/1.1
Connection: Upgrade
Host: my-websocket-api.com
Upgrade: WebSocket

  此时,KONG会将Connection和Upgrade两个请求头转发到上游服务中去。

小结

  通过本指南,希望你了解了Kong的底层代理相关的知识,从API的uris匹配,到如何使用WebSocket协议、为API配置SSL。如果想了解更多的相关知识,请参考Nginx的负载平衡相关内容。

微服务Kong(八)——代理参考的更多相关文章

  1. 微服务Kong(九)——认证参考

    客户端访问上游API服务,通常由Kong的认证插件及其配置参数来控制. 通用认证 一般情况下,上游API服务都需要客户端有身份认证,且不允许错误的认证或无认证的请求通过.认证插件可以实现这一需求.这些 ...

  2. 微服务Kong(六)——配置参考

    1. 配置加载 如果您通过其中一个官方软件包安装了Kong,Kong会附带默认配置文件,该文件可以在/etc/kong/kong.conf.default中找到.要开始配置Kong,您可以复制此文件: ...

  3. 微服务Kong(十)——负载均衡参考

    KONG为请求多个后端服务提供了多种负载均衡方案:一种是简单的基于DNS,另一种是更加动态的环形均衡器,他在不需要DNS服务器的情况下也允许服务注册. 一.基于DNS的负载均衡 当使用基于DNS的负载 ...

  4. 微服务Kong(七)——CLI参考

    KONG提供了一套CLI(命令行界面)命令,您可以通过它来启动.停止和管理您的Kong实例.CLI管理您的本地节点(如在当前机器上). 全局配置 所有命令都采用一组指定的可选标志作为参数: --hel ...

  5. 微服务Kong(一)——简介

    重要提示: 本教程是根据 KONG 0.10.x 版本进行编写的. 一.什么是KONG Kong是一个可扩展的开源API层(也称为API网关或API中间件).它运行在任何RESTful API之前,并 ...

  6. 微服务Kong(四)——添加插件

    在本节中,您将学习到,如何配置使用KONG的插件来管理您的API.KONG的核心原则之一就是通过插件来实现API的扩展.插件可以使您更为简单的扩展和管理您的API. 在以下的步骤中,您将通过配置key ...

  7. 微服务Kong(三)——添加一个API

    在开始前,请确保您已经安装了KONG服务,并且已经启动了KONG服务. 在本节中,您可以学习到:如何在KONG层添加一个API.这是您使用KONG来管理您的API的第一步.对于此篇教程,我们将使用 h ...

  8. 微服务Kong(五)——添加一个用户(Consumer)

    在本节中,我们将学习如何添加一个用户(consumer)到KONG实例中.用户是与使用您的API的个人相关联,可用于跟踪,访问管理等. NOTE:本节假设您已经正确启用了密钥验证插件.如果没有,请参考 ...

  9. 微服务Kong(二)——快速入门

    在本节中,您将学习如何管理您的KONG实例.首先,我们将指导您如何启动Kong,以便您能访问KONG的RESTful形式的管理界面,您可以通过它来管理您的API,consumers等.通过管理型API ...

随机推荐

  1. Plasma Cash 合约解读

    作者介绍 虫洞社区·签约作者 steven bai Plasma Cash 合约解读 Plasma Cash 合约解读 1. 合约代码 2. 合约文件简单介绍 3. Plasma Cash 的基础数据 ...

  2. Alpha阶段项目展示博客

    烫烫烫烫烫(hotcode5)团队 1. 团队成员的简介和个人博客地址 刘畅 博客园ID:森高Slontia 身份:PM 个人介绍: 弹丸粉 || 小说创作爱好者 || 撸猫狂魔(x || 生命的价值 ...

  3. CocoaPods pod install的时候报错:invalid byte sequence in UTF-8 (ArgumentError)解决办法

    CocoaPods pod install的时候报错:invalid byte sequence in UTF-8 (ArgumentError)解决办法: 基本可以确定是Podfile中的内容编码有 ...

  4. 【探路者】final贡献分配

     [探路者]组成员及各位博客地址. 1蔺依铭:http://www.cnblogs.com/linym762/ 2张恩聚:http://www.cnblogs.com/zej87/ 3米赫:http: ...

  5. SQL语句联表查询

    Natural join:字段名和数据类型相同字段进行等值连接: inner join:与join相同,把符合条件的元组选出来,创建视图时用的即是inner join: left join:左表全选出 ...

  6. ASP.NET中实现封装与策略模式

    首先把运算方法封装起来,这样在网页界面中直接就可以调用了,不过是换张脸而已! using System; using System.Collections.Generic; using System. ...

  7. c++课的圆周面积

    又回顾了一下一两个月没动过的类,似乎又有点手生了,不过还好还可以做. 在栋哥的推荐下下载了一个vs2015,表示从dev的白鼠形式的简单操作缓过来还有些不习惯呢,不过有些功能,例如诊断还是挺好用的 这 ...

  8. Team饭来了团队作业3需求改进与系统设计

    团队名称:饭来了 人员组成: 队长:侯晓东          学号:2016012087 队员:崔啸寒          学号:2016012006 队员:方柱权          学号:201601 ...

  9. 深入理解JAVA I/O系列三:字符流详解

    字符流为何存在 既然字节流提供了能够处理任何类型的输入/输出操作的功能,那为什么还要存在字符流呢?容我慢慢道来,字节流不能直接操作Unicode字符,因为一个字符有两个字节,字节流一次只能操作一个字节 ...

  10. 0506-Scrum 项目 2.0视频

    一.团队项目要求 应用NABCD模型,分析你们初步选定的项目,充分说明你们选题的理由. 录制为演说视频,上传到视频网站,并把链接发到团队博客上. 二.NABCD模型 选题:约拍平台——家教平台 1) ...