当前位置:首页 > > 架构师社区
[导读]Kong是一个云原生,高效,可扩展的分布式 API 网关。

Kong(https://github.com/Kong/kong)是一个云原生,高效,可扩展的分布式 API 网关。自 2015 年在 github 开源后,广泛受到关注,目前已收获 1.68w+ 的 star,其核心价值在于高性能和可扩展性。

为什么需要 API 网关

选择Kong作为你的API网关

在微服务架构之下,服务被拆的非常零散,降低了耦合度的同时也给服务的统一管理增加了难度。如上图左所示,在旧的服务治理体系之下,鉴权,限流,日志,监控等通用功能需要在每个服务中单独实现,这使得系统维护者没有一个全局的视图来统一管理这些功能。API 网关致力于解决的问题便是为微服务纳管这些通用的功能,在此基础上提高系统的可扩展性。如右图所示,微服务搭配上 API 网关,可以使得服务本身更专注于自己的领域,很好地对服务调用者和服务提供者做了隔离。

为什么是 Kong

SpringCloud 玩家肯定都听说过 Zuul 这个路由组件,包括 Zuul2 和 Springcloud Gateway 等框架,在国内的知名度都不低。没错,我称呼这些为组件 Or 框架,而 Kong 则更衬的上产品这个词。在此我们可以简单对比下 Zuul 和 Kong。

举例而言,如果选择使用 Zuul,当需要为应用添加限流功能,由于 Zuul 只提供了基本的路由功能,开发者需要自己研发 Zuul Filter,可能你觉得一个功能还并不麻烦,但如果在此基础上对 Zuul 提出更多的要求,很遗憾,Zuul 使用者需要自行承担这些复杂性。而对于 Kong 来说,限流功能就是一个插件,只需要简单的配置,即可开箱即用。

Kong 的插件机制是其高可扩展性的根源,Kong 可以很方便地为路由和服务提供各种插件,网关所需要的基本特性,Kong 都如数支持:

  • 云原生: 与平台无关,Kong可以从裸机运行到Kubernetes

  • 动态路由:Kong 的背后是 OpenResty+Lua,所以从 OpenResty 继承了动态路由的特性

  • 熔断

  • 健康检查

  • 日志: 可以记录通过 Kong 的 HTTP,TCP,UDP 请求和响应。

  • 鉴权: 权限控制,IP 黑白名单,同样是 OpenResty 的特性

  • SSL: Setup a Specific SSL Certificate for an underlying service or API.

  • 监控: Kong 提供了实时监控插件

  • 认证: 如数支持 HMAC, JWT, Basic, OAuth2.0 等常用协议

  • 限流

  • REST API: 通过 Rest API 进行配置管理,从繁琐的配置文件中解放

  • 可用性: 天然支持分布式

  • 高性能: 背靠非阻塞通信的 nginx,性能自不用说

  • 插件机制: 提供众多开箱即用的插件,且有易于扩展的自定义插件接口,用户可以使用 Lua 自行开发插件

上面这些特性中,反复提及了 Kong 背后的 OpenResty,实际上,使用 Kong 之后,Nginx 可以完全摒弃,Kong 的功能是 Nginx 的父集。

而 Zuul 除了基础的路由特性以及其本身和 SpringCloud 结合较为紧密之外,并无任何优势。

Kong 的架构

选择Kong作为你的API网关 image-20180712184740981

从技术的角度讲,Kong 可以认为是一个 OpenResty 应用程序。OpenResty 运行在 Nginx 之上,使用 Lua 扩展了 Nginx。Lua 是一种非常容易使用的脚本语言,可以让你在 Nginx 中编写一些逻辑操作。之前我们提到过一个概念 Kong = OpenResty + Nginx + Lua,但想要从全局视角了解 Kong 的工作原理,还是直接看源码比较直接。我们定位到本地的 Kong 文件夹,按照上图中的目录层级来识识 Kong 的庐山真面目。

  1. Kong 文件下包含了全部源码和必要组件,分析他们,我们便得到了 Kong 的架构。0.13.x 是目前 Kong 的最新版本。

  2. 从 2 号块中可以看到 nginx.conf ,这其实便是一个标准的 Nginx 目录结构,这也揭示了 Kong 其实就是运行在 Nginx 的基础之上,而进行的二次封装。由 share 文件夹向下展开下一次分析。

  3. share 文件夹中包含了 OpenResty 的相关内容,其实背后就是一堆 Lua 脚本,例如 lapis 包含了数据库操作,Nginx 生命周期,缓存控制等必要的 Lua 脚本,logging 包含了日志相关的 Lua 脚本,resty 包含了 dns,健康检查等相关功能的 Lua 脚本…而其中的 kong 目录值得我们重点分析,他包含了 Kong 的核心对象。

  4. api 和 core 文件夹,封装了 Kong 对 service,route,upstream,target 等核心对象的操作代码(这四个核心对象将会在下面的小节重点介绍),而 plugins 文件夹则是 Kong 高可扩展性的根源,存放了 kong 的诸多扩展功能。

  5. plugins 文件夹包含了上一节提到的 Kong 的诸多插件功能,如权限控制插件,跨域插件,jwt 插件,oauth2 插件…如果需要自定义插件,则需要将代码置于此处。

从上述文件夹浏览下来,大概可以看到它和 Nginx 的相似之处,并在此基础之上借助于 Lua 对自身的功能进行了拓展,除了 nginx.conf 中的配置,和相对固定的文件层级,Kong 还需要连接一个数据库来管理路由配置,服务配置,upstream 配置等信息,是的,由于 Kong 支持动态路由的特性,所以几乎所有动态的配置都不是配置在文件中,而是借助于 Postgres 或者 Cassandra 进行管理。

选择Kong作为你的API网关 postgres

Kong 对外暴露了 Restful API,最终的配置便是落地在了数据库之中。

Kong 的管理方式

通过文件夹结构的分析,以及数据库中的表结构,我们已经对 Kong 的整体架构有了一个基本的认识,但肯定还存在一个疑问:我会配置 Nginx 来控制路由,但这个 Kong 应当怎么配置才能达到相同的目的呢?莫急,下面来看看 Kong 如何管理配置。

Kong 简单易用的背后,便是因为其所有的操作都是基于 HTTP Restful API 来进行的。

选择Kong作为你的API网关 kong端点

其中 8000/8443 分别是 Http 和 Https 的转发端口,等价于 Nginx 默认的 80 端口,而 8001 端口便是默认的管理端口,我们可以通过 HTTP Restful API 来动态管理 Kong 的配置。

一个典型的 Nginx 配置

upstream helloUpstream { server localhost:3000 weight=100;
} server { listen 80; location /hello { proxy_pass http://helloUpstream;
    }
}

如上这个简单的 Nginx 配置,便可以转换为如下的 Http 请求。

对应的 Kong 配置

# 配置 upstream curl -X POST http://localhost:8001/upstreams --data "name=helloUpstream" # 配置 target curl -X POST http://localhost:8001/upstreams/hello/targets --data "target=localhost:3000" --data "weight=100" # 配置 service curl -X POST http://localhost:8001/services --data "name=hello" --data "host=helloUpstream" # 配置 route curl -X POST http://localhost:8001/routes --data "paths[]=/hello" --data "service.id=8695cc65-16c1-43b1-95a1-5d30d0a50409"

这一切都是动态的,无需手动 reload nginx.conf。

我们为 Kong 新增路由信息时涉及到了 upstream,target,service,route 等概念,他们便是 Kong 最最核心的四个对象。(你可能在其他 Kong 的文章中见到了 api 这个对象,在最新版本 0.13 中已经被弃用,api 已经由 service 和 route 替代)

从上面的配置以及他们的字面含义大概能够推测出他们的职责,upstream 是对上游服务器的抽象;target 代表了一个物理服务,是 ip + port 的抽象;service 是抽象层面的服务,他可以直接映射到一个物理服务(host 指向 ip + port),也可以指向一个 upstream 来做到负载均衡;route 是路由的抽象,他负责将实际的 request 映射到 service

他们的关系如下

upstream 和 target :1 对 n

service 和 upstream :1 对 1 或 1 对 0 (service 也可以直接指向具体的 target,相当于不做负载均衡)

service 和 route:1 对 n

高可扩展性的背后—插件机制

Kong 的另一大特色便是其插件机制,这也是我认为的 Kong 最优雅的一个设计。

文章开始时我们便提到一点,微服务架构中,网关应当承担所有服务共同需要的那部分功能,这一节我们便来介绍下,Kong 如何添加 jwt 插件,限流插件。

插件(Plugins)装在哪儿?对于部分插件,可能是全局的,影响范围是整个 Kong 服务;大多数插件都是装在 service 或者 route 之上。这使得插件的影响范围非常灵活,我们可能只需要对核心接口进行限流控制,只需要对部分接口进行权限控制,这时候,对特定的 service 和 route 进行定向的配置即可。

为 hello 服务添加50次/秒的限流

curl -X POST http://localhost:8001/services/hello/plugins \
--data "name=rate-limiting" \
--data "config.second=50"

为 hello 服务添加 jwt 插件

curl -X POST http://localhost:8001/services/login/plugins \
--data "name=jwt"

同理,插件也可以安装在 route 之上

curl -X POST http://localhost:8001/routes/{routeId}/plugins \
--data "name=rate-limiting" \
--data "config.second=50"

curl -X POST http://localhost:8001/routes/{routeId}/plugins \
--data "name=jwt"

在官方文档中,我们可以获取全部的插件 https://konghq.com/plugins/,部分插件需要收费的企业版才可使用。

选择Kong作为你的API网关 kong插件

总结

Kong 是目前市场上相对较为成熟的开源 API 网关产品,无论是性能,扩展性,还是功能特性,都决定了它是一款优秀的产品,对 OpenResty 和 Lua 感兴趣的同学,Kong 也是一个优秀的学习参考对象。基于 OpenResty,可以在现有 Kong 的基础上进行一些扩展,从而实现更复杂的特性,比如我司内部的 ABTest 插件和定制化的认证插件,开发成本都相对较低。Kong 系列的文章将会在以后持续连载。

Kirito 有话说:感谢阅读,为了博主更好地创作,提供更多的原创文章,请大家务必!务必!务必!帮我点击阅读一下明天即将发出来的公众号文章!!!感谢老铁~


阅读扩展

初识 Kong 之负载均衡 https://www.cnkirito.moe/kong-loadbalance/

Kong 集成 Jwt 插件 https://www.cnkirito.moe/kong-jwt/


免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭