vlambda博客
学习文章列表

又肝了下微服务 API 网关“金刚”,也是蛮香的~

管她前浪,还是后浪?

能浪的浪,才是好浪!

每天 8:55 更新文章,每天掉亿点点头发...

源码精品专栏

 




摘要: 原创出处 http://www.iocoder.cn/Kong/install/ 「芋道源码」欢迎转载,保留摘要,谢谢!

  • 1. 概述
  • 2. 快速安装
  • 3. Kong 控制台
  • 4. 动态负载均衡
  • 5. 限流限速
  • 6. JWT 身份验证
  • 666. 彩蛋

大家好,我是艿艿,一个很肝的小胖子~

前端时间写了篇文章,有灰常多的留言让写写关于 Kong 的内容,于是乎艿艿又莽了这篇文章~良心如我!

1. 概述

如下 Kong 简介的内容,基于 Kong Github、Kong 官方文档、《API 网关之 Kong 简介》梳理~

另外也推荐下 Kong 的“竞品” APISIX,一款国产的微服务 API 网关,目前已经进入 Apache 中孵化。想要学习的胖友,可以点击传送门学习!

Kong 是由 Mashape 公司开源的云原生、高性能、可扩展的微服务 API 网关。它基于 OpenResty 实现,使用 Cassandra 或 PostgreSQL 存储数据。

又肝了下微服务 API 网关“金刚”,也是蛮香的~
Kong Logo
  • OpenResty:通过 Lua 扩展 Nginx 实现的可伸缩的 Web 平台。
  • Cassandra:Key/Value 存储系统。
  • PostgreSQL:数据库服务器。
又肝了下微服务 API 网关“金刚”,也是蛮香的~
Kong 整体
  • Kong 提供了 RESTful Admin API,可用于管理员进行 Kong 的配置。

1.1 特性

Kong 网关具有以下的特性:

  • 可扩展性:通过简单地添加更多的服务器,可以轻松地进行横向扩展,这意味着您的平台可以在一个较低负载的情况下处理任何请求。

  • 模块化::可以通过添加新的插件进行扩展,这些插件可以通过 RESTful Admin API 轻松配置。

  • 在任何基础架构上运行:Kong 网关可以在任何地方都能运行。可以在云或内部网络环境中部署 Kong,包括单个或多个数据中心设置,以及 public,private 或 invite-only APIs。

1.2 架构

Kong 的整体架构如下所示:

又肝了下微服务 API 网关“金刚”,也是蛮香的~
Kong 整体架构

友情提示:自上往下看哈~注意加粗部分的字!

  • Kong RESTful 管理 API,提供了 API、API消费者、插件、upstreams、证书等管理。
  • Kong 插件拦截请求/响应,类似于 Java Servlet 中的过滤器,实现请求/响应的 AOP 处理。
  • Kong 数据存储用于存储 Kong 集群节点信息、API、消费者、插件等信息,目前提供了 Cassandra 和 PostgreSQL 支持。如果需要高可用,建议使用 Cassandra。
  • Kong 集群中的节点通过 gossip 协议自动发现其它节点。当通过一个 Kong 节点的管理 API 进行一些变更时,也会通知其他节点。每个 Kong 节点的配置信息是会 缓存的,例如插件,那么当在某一个 Kong 节点修改了插件配置时,需要通知其他节点配置的变更。
  • Kong 核心基于 OpenResty,使用 Lua 进行请求/响应的处理。

1.3 插件

Kong 内置了丰富的插件,提供了强大的功能以及集成能力,同时我们又可以基于插件机制自行进行拓展。

又肝了下微服务 API 网关“金刚”,也是蛮香的~
插件体系
  • Authentication 身份认证插件:Kong 提供了 Basic Authentication、Key authentication、OAuth2.0 authentication、HMAC authentication、JWT、LDAP authentication 等等实现。
  • Security 安全控制插件:ACL(访问控制)、CORS(跨域资源共享)、动态SSL、IP 限制、爬虫检测等等实现。
  • Traffic Control 流量控制插件:请求限流(基于请求计数限流)、上游响应限流(根据 upstream 响应计数限流)、请求大小限制等等实现。限流支持本地、Redis 和集群三种限流模式。
  • Analytics & Monitoring 分析监控插件:对接 Datadog、Prometheus、Zipkin 等等监控系统的实现。
  • Transformations 协议转换插件:请求转换(在转发到 upstream 之前修改请求)、响应转换(在 upstream 响应返回给客户端之前修改响应)。
  • Logging 日志应用插件:支持 TCP、UDP、HTTP、File、Syslog、StatsD、Loggly 等等方式传输日志。
  • Serverless 插件:提供对 AWS Lambda、Azure Functions、Apache OpenWhisk、Kong 自带 Serverless Functions 等等的  Serverless 解决方案的支持。
  • Deployment 插件

1.4 请求流程

为了更好地使用 Kong 网关,我们需要理解它处理 API 接口的典型请求工作流程:

又肝了下微服务 API 网关“金刚”,也是蛮香的~
请求流程

Kong 是每个 API 请求的入口点(Endpoint):

  • 当 Kong 运行时,每个对 API 的请求将先被 Kong 命中,然后这个请求将会被代理转发到最终的 API 接口。
  • 在请求(Requests)和响应(Responses)之间,Kong 将会执行已经事先安装和配置好的插件,授权 API 访问操作。

2. 快速安装

在《Kong 文档 —— 安装》下,官方提供了多种安装方式,这里我们采用 CentOS 系统。

又肝了下微服务 API 网关“金刚”,也是蛮香的~
Kong 安装方式

友情提示:如果胖友会使用 Docker 的话,安装起来会比较便捷,可参考如下文章:

  • 《Kong 与 Konga 之 Docker 部署》
  • 《Kong 文档 —— Docker 方式安装》

2.1 安装 PostgreSQL

相比 Cassandra 来说,我们会更加熟悉 PostgreSQL,所以我们采用 PostgreSQL 作为 Kong 的数据存储。在《Kong 文档 —— CentOS 安装》提到,PostgreSQL 最低要求 9.5+ 版本,这里我们采用 12 版本。

友情提示:如下所有的命令行操作,是在 root 用户下执行。如果胖友使用非 root 用户,请额外增加 sudo 命令。

2.1.1 安装

① 打开《PostgreSQL 文档 —— CentOS 安装》,选择 PostgreSQL 12 + CentOS 7 后获得安装方式。如下图所示:

又肝了下微服务 API 网关“金刚”,也是蛮香的~
PostgreSQL 安装步骤

② 执行如下命令,进行 PostgreSQL 的安装:

# 添加 PostgreSQL 的 RPM
$ yum install https://download.postgresql.org/pub/repos/yum/reporpms/EL-7-x86_64/pgdg-redhat-repo-latest.noarch.rpm

# 安装 PostgreSQL Server 12
$ yum install postgresql12-server

# 初始化数据库
$ /usr/pgsql-12/bin/postgresql-12-setup initdb
又肝了下微服务 API 网关“金刚”,也是蛮香的~
PostgreSQL 安装成功

③ 执行如下命令,进行 PostgreSQL 的启动:

# 设置 PostgreSQL 开机启动服务
$ systemctl enable postgresql-12

# 启动 PostgreSQL 服务
$ systemctl start postgresql-12

# 查看 PostgreSQL 状态
$ systemctl status postgresql-12
又肝了下微服务 API 网关“金刚”,也是蛮香的~
PostgreSQL 启动成功

2.1.2 配置

安装完成之后,会自动创建如下:

  • 在 Linux 中,创建一个 Linux 系统用户 postgres【管理 PostgreSQL 数据库的 系统管理员】。
  • 在 PostgreSQL 中,创建 PostgreSQL 用户 postgres数据库超级管理员】,以及数据库 postgres用户 postgres 的默认数据库】。

① 使用 passwd postgres 命令,我们来初始化下 postgres 用户的密码。详细如下图所示:

又肝了下微服务 API 网关“金刚”,也是蛮香的~
修改 postgres 用户的密码

② 为了安全以及满足 Kong 初始化的需求,需要创建一个 Linux 用户 kong,并创建对应的 PostgreSQL 用户 kong 和数据库 kong。操作命令如下:

# 创建一个 Linux 用户 `kong`
$ adduser kong

# 切换到 Linux 系统用户 `postgres`,因为它是 PostgreSQL 数据库的系统管理员
$ su postgres

# 进入 PostgreSQL 控制台
$ psql

# 设置用户 `postgres` 的密码【仅仅首次需要】
$ \password postgres # 注意开头的 \ 必须有!

# 创建一个 PostgreSQL 用户 `kong`,和上面创建的 Linux 用户 `kong` 对应。
$ create user kong with password '123456'# 密码 '123456' 根据自己需要,进行随机生成~
# 创建一个 PostgreSQL 数据库 `kong`
$ create database kong owner kong;
# 将数据库 `kong` 授权给 PostgreSQL 用户 `kong`
$ grant all privileges on database kong to kong;

# 退出 PostgreSQL 控制台
$ \q
又肝了下微服务 API 网关“金刚”,也是蛮香的~
新建 kong 数据库

③ PostgreSQL 有四种身份认证方式:

  • trust:凡是连接到服务器的,都是可信任的。只需要提供 PostgreSQL 用户名,可以没有对应的操作系统同名用户。
  • password 和 md5:对于远程访问,需要提供 PostgreSQL 用户名和密码。对于本地连接,提供 PostgreSQL 用户名密码之外,还需要有操作系统访问权(用操作系统同名用户验证)。password 和 md5 的区别,就是远程访问时传输的密码是否用 md5 加密。
  • ident:对于远程访问,从 ident 服务器获得客户端操作系统用户名,然后把操作系统作为数据库用户名进行登录对于本地连接,实际上使用了 peer。
  • peer:对于本地访问,通过客户端操作系统内核来获取当前系统登录的用户名,并作为 PostgreSQL 用户名进行登录。

/var/lib/pgsql/12/data/pg_hba.conf 文件中,PostgreSQL 可以看到目前的配置情况。如下图所示:

又肝了下微服务 API 网关“金刚”,也是蛮香的~
/var/lib/pgsql/12/data/pg_hba.conf 配置文件(默认)

默认配置下,我们无法在本地或者远程使用 PostgreSQL 用户名和密码直接连接,因为本地使用 peer 认证方式,远程使用 ident 认证方式。解决方法比较简单,将本地和远程的认证方式修改成 trust 或者 password 即可。

下面,我们修改 /var/lib/pgsql/12/data/pg_hba.conf 文件,注释掉所有默认配置,并添加一条 host all all 0.0.0.0/0 trust 默认,无论远程还是本地访问,任何 PostgreSQL 用户和数据库,都使用 trust 认证方式。最终如下图所示:

又肝了下微服务 API 网关“金刚”,也是蛮香的~
/var/lib/pgsql/12/data/pg_hba.conf 配置文件(修改)

友情提示:线上环境,考虑到安全性,建议使用相对细粒度的配置。例如说,将 0.0.0.0/0 修改成指定的内网网段。

修改完成后,执行 sudo systemctl restart postgresql-12 命令,重启 PostgreSQL 数据库。重启完成后,执行 psql -U kong -d kong -h 127.0.0.1 -p 5432 命令,使用 PostgreSQL 用户名 kong 连接 PostgreSQL 数据库 kong,又因为是 trust 认证方式,所以无需附带密码。

④ 默认配置下,PostgreSQL 只允许本地连接,所以我们需要修改 /var/lib/pgsql/12/data/postgresql.conf 文件,添加 listen_address 配置项为 *,允许远程连接。如下图所示:

又肝了下微服务 API 网关“金刚”,也是蛮香的~
/var/lib/pgsql/12/data/postgresql.conf 配置文件(修改)

修改完成后,执行 sudo systemctl restart postgresql-12 命令,重启 PostgreSQL 数据库。重启完成后,使用 Navicat 了解 PostgreSQL 数据库,如下图所示:

又肝了下微服务 API 网关“金刚”,也是蛮香的~
Navicat 连接 PostgreSQL 数据库

2.2 安装 Kong

《Kong 文档 —— CentOS 安装》,进行 CentOS 系统下的 Kong 的安装。

2.2.1 安装

又肝了下微服务 API 网关“金刚”,也是蛮香的~
Kong RPM 包下载

然后,执行 wget 命令,进行 Kong 的 RPM 包的下载。操作命令如下:

$ wget -O "kong.rpm" https://bintray.com/kong/kong-rpm/download_file?file_path=amazonlinux/amazonlinux/kong-2.0.4.aws.amd64.rpm
  • 其中 -O "kong.rpm" 代表下载文件的 命名。
  • 最后一串 URL 代表下载文件的 地址,

② 执行 yum install kong.rpm --nogpgcheck 命令,进行 Kong 的安装。

2.2.2 配置

① Kong 的默认配置文件是 /etc/kong/kong.conf.default,使用 cp /etc/kong/kong.conf.default /etc/kong/kong.conf 命令,复制一份新的配置文件。

复制完成后,我们修改 /etc/kong/kong.conf 配置文件,设置使用 PostgreSQL 数据库。如下图所示:

又肝了下微服务 API 网关“金刚”,也是蛮香的~
/etc/kong/kong.conf 配置文件

② 执行 kong migrations bootstrap -c /etc/kong/kong.conf 命令,进行 Kong 的 PostgreSQL 数据库的表初始化。完成后,使用 Navicat 看到如下表:

又肝了下微服务 API 网关“金刚”,也是蛮香的~
初始化 PostgreSQL 表

③ 执行 kong start -c /etc/kong/kong.conf 命令,执行 Kong 的启动。启动成功时,会看到 Kong started 日志。

默认情况下,Kong 绑定 4 个端口:

  • Proxy 8000:接收客户端的 HTTP 请求,并转发到后端的 Upstream。
  • Proxy 8443:接收客户端的 HTTPS 请求,并转发到后端的 Upstream。
  • Admin 8001:接收管理员的 HTTP 请求,进行 Kong 的管理。
  • Admin 8444:接收管理员的 HTTPS 请求,进行 Kong 的管理。

简单测试如下:

# 请求 Proxy 端口
$ curl http://127.0.0.1:8000
{"message":"no Route matched with those values"
# 因为我们暂时没配置 Kong 路由。

# 请求 Admin 端口
$ curl http://127.0.0.1:8001
{"plugins":{"enabled_in_cluster":[],"available_on_server":{... // 省略 
# 注意,考虑到安全性,Admin 端口只允许本机访问。

3. Kong 控制台

Kong 分成免费版和企业版,毕竟都要吃饭的。免费版本的 Kong 是不提供 Kong 的控制台,只能通过 Kong Admin API 进行 Kong 的维护和管理,显然非常不方便。所幸开源社区提供了两个做的不错的 Kong 控制台项目:

  • Kong Dashboard,已经有 15 个月左右未维护,不支持 Kong 2.x 版本。
  • Konga,更新频繁,支持 Kong 2.X 版本。

因此,现在一般采用 Konga 作为 Kong 的控制台。界面如下图所示:

又肝了下微服务 API 网关“金刚”,也是蛮香的~
Konga 界面
  • 基于 Kong Admin API 管理所有 Kong 的对象。
  • 支持从数据库、文件、API 等远程数据源导入 Consumer。
  • 管理多个 Kong 界面。
  • 备份,恢复,通过快照迁移 Kong 节点。
  • 通过健康检查监控 Kong 节点和 API 状态。
  • 支持 Email 和 Slack 消息通知方式。
  • 支持多用户,可以设置不同的权限。
  • 支持 MySQL、PostgreSQL、MongoDB 数据库。

下面,我们来一起进行 Konga 的安装与学习。

友情提示:如果胖友会使用 Docker 的话,安装起来会比较便捷,可参考如下文章:

  • 《Kong 与 Konga 之 Docker 部署》
  • 《Konga 文档 —— Production Docker Image》

3.1 安装 NodeJS 环境

因为 Konga 是基于 NodeJS 开发的项目,所以需要安装 NodeJS 相关的环境。执行命令如下:

Node 的安装,可参考 https://github.com/nodesource/distributions 仓库。

# 安装 NodeJS 14.x 和 NPM
$ curl -sL https://rpm.nodesource.com/setup_12.x | bash -
$ yum install nodejs npm -y

# 打印版本
$ node --version
v12.17.0
$ npm --version
6.14.5

# 安装 gulp、bower、sails
$ npm install -g gulp
$ npm install -g bower
$ npm install -g sails
  • NodeJS:运行在服务端的 JavaScript。
  • npm:npm 是 JavaScript 世界的包管理工具,并且是 NodeJS 平台的默认包管理工具。通过 npm 可以安装、共享、分发代码,管理项目依赖关系。
  • gulp:一个自动化构建工具,开发者可以使用它在项目开发过程中自动执行常见任务。
  • bower:一个针对Web开发的包管理器。该工具主要用来帮助用户轻松安装 CSS、JavaScript、图像等相关包,并管理这些包之间的依赖。
  • sails:NodeJS 的 MVC 框架。

3.2 安装 Konga

① 克隆 Konga 的源码,并下载 NodeJS 相关依赖包,并进行操作命令如下:

# 安装 Git,已安装可忽略
$ yum install git
$ git clone https://github.com/pantsel/konga.git

# 下载 NodeJS 相关依赖包
cd kongga
$ npm i

# 解决 bower 相关依赖包
$ npm run bower-deps

目前 Konga 支持使用 MySQL、PostgreSQL、SQLServer、MongoDB 四种数据库。下面,我们以 PostgreSQL 作为 Konga 的数据库举例子。

② 创建 Konga 的 PostgreSQL 数据库 konga,命令行操作如下:

# 创建一个 Linux 用户 `konga`
$ adduser konga

# 进入 PostgreSQL 控制台
# 因为我们切换了 PostgreSQL 的认证方式为 trust 方式,所以可以这样连接
$ psql -U postgres -h 127.0.0.1 -p 5432

# 创建一个 PostgreSQL 用户 `konga`,和上面创建的 Linux 用户 `konga` 对应。
$ create user konga with password '123456'# 密码 '123456' 根据自己需要,进行随机生成~
# 创建一个 PostgreSQL 数据库 `konga`
$ create database konga owner konga;
# 将数据库 `konga` 授权给 PostgreSQL 用户 `konga`
$ grant all privileges on database konga to konga;

# 退出 PostgreSQL 控制台
$ \q
又肝了下微服务 API 网关“金刚”,也是蛮香的~
新建 konga 数据库

友情提示:Konga 暂时不支持 12 版本的 PostgreSQL,所以下面艿艿卒了,只是“演示”整个过程。

建议使用 9.x 版本的 PostgreSQL 哈!

③ 执行 cp .env_example .env 命令,复制出 .env 配置文件,接入 PostgreSQL 作为数据库。配置内容如下:

PORT=1337
NODE_ENV=production
KONGA_HOOK_TIMEOUT=120000
DB_ADAPTER=postgres
DB_URI=postgresql://konga:123456@localhost:5432/konga
KONGA_LOG_LEVEL=warn
TOKEN_SECRET=some_secret_token
又肝了下微服务 API 网关“金刚”,也是蛮香的~
.env 配置文件

④ 执行如下命令,初始化 PostgreSQL 数据库:

$ node ./bin/konga.js prepare [--adapter postgres --uri postgresql://konga:[email protected]:5432/konga]
又肝了下微服务 API 网关“金刚”,也是蛮香的~
初始化 PostgreSQL 数据库

= = 因为艿艿安装的 PostgreSQL 版本过高,所以后面艿艿临时先使用 MySQL 作为 Konga 的数据库。下图是艿艿使用 MySQL 时候的操作:

又肝了下微服务 API 网关“金刚”,也是蛮香的~
MySQL 示例

最终 PostgreSQL 数据库 konga 的表如下图所示:

又肝了下微服务 API 网关“金刚”,也是蛮香的~
konga

⑤ 执行如下命令,启动 Konga 服务:

$ npm run production
[email protected] production /root/konga
> node --harmony app.js --prod

默认配置下,Konga 启动在 1337 端口。

⑥ 使用浏览器,访问 <http://127.0.0.1:1337/> 地址,进入 Konga 首页。因为 Konga 暂无**默认**管理员,所以自动跳转创建页面。如下图所示:
又肝了下微服务 API 网关“金刚”,也是蛮香的~
Konga 注册界面
又肝了下微服务 API 网关“金刚”,也是蛮香的~
Konga 注册界面
又肝了下微服务 API 网关“金刚”,也是蛮香的~
Konga 初始化 Kong 界面
又肝了下微服务 API 网关“金刚”,也是蛮香的~
Kong 信息

至此,我们已经完成了 Konga 的安装,胖友可以自己点点 Konga 的界面,愉快的玩耍吧~

旁白君:后续,我们会一边进行 Kong 的学习,一边演示在 Konga 中的展示。

4. 动态负载均衡

本小节,我们来实现对后端服务提供的 API 接口进行负载均衡。考虑到方便,艿艿在 https://github.com/YunaiV/SpringBoot-Labs 仓库提供了一个 Spring Boot 项目 lab-56-demo01,如下图所示:

又肝了下微服务 API 网关“金刚”,也是蛮香的~
Spring Boot 项目

最终示例的效果,如下图所示:

又肝了下微服务 API 网关“金刚”,也是蛮香的~
项目效果

最终我们使用 Kong 实现负载均衡的效果等同于如下 Nginx 的配置:

upstream demo-upstream {
server localhost:18081 weight=100;
server localhost:18082 weight=50;
}

server {
listen 80;
location /demo-api/ {
proxy_pass http://demo-upstream;
}
}

下面,我们来通过 Kong Admin API 进行上述的负载均衡的配置。

4.1 创建 upstream 和 target

① 调用 Kong Admin API /upstreams,创建名字为 demo-upstreamupstream:

$ curl -X POST http://127.0.0.1:8001/upstreams --data "name=demo-upstream"
又肝了下微服务 API 网关“金刚”,也是蛮香的~
Kong upstream

② 调用 Kong Admin API /upstreams/{upstream}/targets,创建 Spring Boot 项目对应的 2 个 target:

注意,{upstream} 路径参数,为 upstream 的名字。

# 端口 18080 对应的 target
$ curl -X POST http://127.0.0.1:8001/upstreams/demo-upstream/targets --data "target=10.8.8.34:18080" --data "weight=100"
# 端口 28080 对应的 target
$ curl -X POST http://127.0.0.1:8001/upstreams/demo-upstream/targets --data "target=10.8.8.34:28080" --data "weight=50"

友情提示:艿艿这里 Spring Boot 项目启动在 IP 为 10.8.8.34 的服务器上。

又肝了下微服务 API 网关“金刚”,也是蛮香的~
Kong target

③ 如上的配置,效果等同于如下 Nginx 的配置:

upstream demo-upstream {
server localhost:18081 weight=100;
server localhost:18082 weight=50;
}

4.2 创建 service 和 route

① 调用 Kong Admin API /services,创建名字为 demo-serviceservice:

$ curl -X POST http://127.0.0.1:8001/services --data "name=demo-service" --data "host=demo-upstream" 
  • host 参数,用于设置对应的 upstream 的名字。
又肝了下微服务 API 网关“金刚”,也是蛮香的~
Kong service

② 调用 Kong Admin API services/${service}/routes,创建一个请求路径为 pathroute:

注意,{service} 路径参数,为 upstream 的名字。

$ curl -X POST http://localhost:8001/services/demo-service/routes --data "name=demo-route" --data "paths[]=/demo-api"
又肝了下微服务 API 网关“金刚”,也是蛮香的~
Kong route
又肝了下微服务 API 网关“金刚”,也是蛮香的~
Kong route

③ 如上的配置,效果等同于如下 Nginx 的配置:

server {
listen 80;
location /demo-api/ {
proxy_pass http://demo-upstream;
}
}

4.3 简单测试

不断执行 curl http://127.0.0.1:8000/demo-api/demo/echo 命令,请求 Kong 网关来负载均衡转发到后端的 Spring Boot 项目,结果如下:

echo:18080
echo:18080
echo:28080

...

负载均衡请求到多个节点,符合预期~

4.4 简单小结

在上面,我们看到了 Kong 的 upstream、target、service、route 四个对象,一起来简单小节下:

又肝了下微服务 API 网关“金刚”,也是蛮香的~
service + route + upstream + target
Kong 组件 说明
service service 对应服务,可以直接指向一个 API 服务节点(host 参数设置为 ip + port),也可以指定一个 upstream 实现负载均衡。简单来说,服务用于映射被转发的后端 API 的节点集合
route route 对应路由,它负责匹配实际的请求,映射到 service 中
upstream upstream 对应一组 API 节点,实现负载均衡
target target 对应一个 API 节点

在 Kong 中,还有 Consumer、Plugin、Tag、Certificate、Target 等等对象,胖友可以阅读《Kong 文档 —— Admin API》了解更多。

另外,胖友如果想用 Konga 通过图形界面来配置,可以参考阅读《Kong 配置 service 和 route 实现简单 API 代理》文章。

5. 限流限速

Kong 提供了 Rate Limiting 插件,实现对请求的限流功能,避免过大的请求量过大,将后端服务打挂。

Rate Limiting 支持秒/分/小时/日/月/年多种时间维度的限流,并且可以组合使用。例如说:限制每秒最多 100 次请求,并且每分钟最多 1000 次请求。

Rate Limiting 支持 consumercredentialip 三种基础维度的限流,默认为 consumer。例如说:设置每个 IP 允许每秒请求的次数。计数的存储,支持使用 localclusterredis 三种方式进行存储,默认为 cluster

  • local:存储在 Nginx 本地,实现单实例限流。
  • cluster:存储在 Cassandra 或 PostgreSQL 数据库,实现集群限流。
  • redis:存储在 Redis 数据库,实现集群限流。

Rate Limiting 采用的限流算法是计数器的方式,所以无法提供类似令牌桶算法的平滑限流能力。

友情提示:Kong 企业版提供了 [https://docs.konghq.com/hub/kong-inc/rate-limiting-advanced/](Rate Limiting Advanced) 插件,提供平滑限流的功能,且性能更加优秀。

The Rate Limiting Advanced plugin for Kong Enterprise is a re-engineered version of the incredibly popular Kong Rate Limiting plugin, with greatly enhanced configuration options and performance.

下面,我们在「4. 动态负载均衡」小节的基础上,对名字为 demo-serviceservice 进行限流。

5.1 创建 Rate Limiting 插件

调用 Kong Admin API services/${service}/plugins,创建 Rate Limiting 插件的配置:

$ curl -X POST http://127.0.0.1:8001/services/demo-service/plugins \
    --data "name=rate-limiting"  \
    --data "config.second=1" \
    --data "config.limit_by=ip"
  • name 参数,设置为 rate-limiting 表示使用 Rate Limiting 插件。
  • config.second 参数,设置为 1 表示每秒允许 1 次请求。
  • config.limit_by 参数,设置为 ip 表示使用 IP 基础维度的限流。
又肝了下微服务 API 网关“金刚”,也是蛮香的~
Kong Rate Limiting 01
又肝了下微服务 API 网关“金刚”,也是蛮香的~
Kong Rate Limiting 02

友情提示:Rate Limiting 插件还支持给 route、consumer 设置限流配置,胖友可以阅读《Kong 文档 —— Rate Limiting》学习。

5.2 简单测试

快速使用 curl http://127.0.0.1:8000/demo-api/demo/echo 命令 2 次,会被 Kong 限流,返回结果如下:

{"message":"API rate limit exceeded"}

6. JWT 身份验证

Kong 提供了 JWT 插件,实现使用 JWT 进行认证,保护后端服务的安全性。

可能有胖友不了解 JWT 认证方式,可以先阅读如下文章:

  • 《JSON Web Token - 在Web应用间安全地传递信息》
  • 《八幅漫画理解使用 JSON Web Token 设计单点登录系统》

下面,我们在「4. 动态负载均衡」小节的基础上,对名字为 demo-serviceservice 进行 JWT 身份认证。

6.1 创建 JWT 插件

① 调用 Kong Admin API services/${service}/plugins,创建 JWT 插件的配置:

$ curl -X POST http://127.0.0.1:8001/services/demo-service/plugins \
    --data "name=jwt"
  • name 参数,设置为 jwt 表示使用 JWT 插件。
又肝了下微服务 API 网关“金刚”,也是蛮香的~
Kong JWT 01
又肝了下微服务 API 网关“金刚”,也是蛮香的~
Kong JWT 02

② 使用 curl http://127.0.0.1:8000/demo-api/demo/echo 命令,会被 Kong 安全拦截。返回结果如下:

{"message":"Unauthorized"}

友情提示:JWT 插件还支持给 route、consumer 设置 JWT 认证方式,胖友可以阅读《Kong 文档 —— JWT》学习。

6.2 创建用户

① 调用 Kong Admin API consumers,创建一个 Consumer 消费者(用户):

$ curl -i -X POST http://localhost:8001/consumers/ \
    --data "username=yunai"
  • username 参数,设置用户名为 yunai
又肝了下微服务 API 网关“金刚”,也是蛮香的~
Kong Consumer 01
又肝了下微服务 API 网关“金刚”,也是蛮香的~
Kong Consumer 02

② 调用 Kong Admin API consumers/{username}/{plugin}生成该消费者的 JWT 信息:

{username} 路径参数,为 Consumer 的用户名。
{plugin} 路径参数,为 Plugin 的插件名。

$ curl -i -X POST http://localhost:8001/consumers/yunai/jwt/
{
 "rsa_public_key": null,
 "created_at": 1590943621,
 "consumer": {
  "id""8fa7e054-9cda-486f-b611-229bf7780969"
 },
 "id""1af4ee95-f5fb-484c-97da-b5b205bd07c8",
 "tags": null,
 "key""VbC63YmEg57fgVSLsKsrBHcVe9nu9XLX",
 "secret""xtgiCmCLtF7khq7SoAsrZDfVCQGHk5Pl",
 "algorithm""HS256"
}
  • 注意 keysecret 的结果,稍后会使用到。

使用 JWT Debugger 功能,生成 JWT Token。示例如下图所示:

JWT Debugger 生成 Token
$ curl http://127.0.0.1:8000/demo-api/demo/echo \
    -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJWYkM2M1ltRWc1N2ZnVlNMc0tzckJIY1ZlOW51OVhMWCJ9.rbWcXb-c1AwA3haiMWKStOcTCjkgVw1gmYMFeV8In6w"
echo:18080

成功!美滋滋~

666. 彩蛋

至此,我们已经完成 Kong 的初步学习。想要进一步深入的胖友,除了可以阅读《Kong 文档》之外,也可以阅读如下系列:

  • 《Kong(一)简介及部署》
  • 《Kong(二)admin-api(结合实例比官网还详细)》
  • 《Kong(三))Proxy 规则》
  • 《Kong(四)负载均衡理论及实现)》
  • 《Kong(五)CentOS7 部署 PostgreSQL 和 kong 总结)》
  • 《Kong(六)集群搭建部署》
  • 《Kong(七)认证》
  • 《Kong(八)配置说明》




已在知识星球更新源码解析如下:

最近更新《芋道 SpringBoot 2.X 入门》系列,已经 20 余篇,覆盖了 MyBatis、Redis、MongoDB、ES、分库分表、读写分离、SpringMVC、Webflux、权限、WebSocket、Dubbo、RabbitMQ、RocketMQ、Kafka、性能测试等等内容。

提供近 3W 行代码的 SpringBoot 示例,以及超 4W 行代码的电商微服务项目。

兄弟,一口,点个👇