目 录CONTENT

文章目录

API 网关

Sakura
2023-10-30 / 0 评论 / 0 点赞 / 59 阅读 / 18706 字 / 正在检测是否收录...

API 网关

1. API 网关介绍

作用: 用来接收客户端的请求,把这些请求转发给后端服务

当前端客户端请求代理向后端发出请求的时候,这个请求先由 API 网关接收,然后 API 网关把请求转发个对应的服务

无论服务有多少个,反应给用户端的只有一个接口

核心作用: 转发请求

现代的 API 网关,除了具备基本的转发功能外,通常还具有:

  • 多协议支持:tcp,http、https、websock、gRPC

  • 负载均衡 ( 将多个请求进行负载均衡 )

  • 身份验证 ( 访问控制 : 判断请求有没有权限访问对应的服务 )

  • 监控、日志 ( 监控服务正常不正常 )

  • 缓存 ( 可以缓存一部分服务的数据,有些请求就不要请求打到对应的服务了 )

  • 熔断、限流

2. Kong 介绍

The fastest, most-adopted API gateway is just the start.

以上是 Kong 官网的口号。最快、使用最多的 API 网关仅是个开始。

网址:https://docs.konghq.com/

Kong 是一个可扩展的开源 API 平台(也称为 API 网关或 API 中间件)。Kong 最初由 Kong Inc.(以前称为 Mashape)构建,用于为其 API Marketplace 保护,管理和扩展超过15,000 个微服务,每月产生数十亿个请求。

Kong 是一个在 Nginx 中运行的 Lua 应用程序,可以通过 lua-nginx 模块实现。但是 Kong 不是用这个模块编译 Nginx 的,而是与 OpenRestry 一起发布,OpenRestry 已经包含了 lua-nginx-module。OpenRestry 是Nginx 的一组扩展功能模块。

  • 特性:

    • 云原生:平台无关,支持任意平台,裸机容器或云平台

    • 服务发现:通过第三方 DNS 解析做服务发现,如consul

    • 各种协议支持:ws、wss、gRPC、HTTP、HTTPs、RestAPI

    • 支持分布式集群部署、节点恢复等

    • 支持多种负载均衡实现:Hash-Based(cookie、ip),多个 upstream

    • 日志、监控

    • SSL 证书

    • 支持多种认证机制:OAuth2.0、JWT、HMAC、Basic 等

    • 性能高,基于 Nginx,支持缓存等

    • 支持服务检测,心跳、断路、限流等

    • 支持插件功能扩展

3. Kong docker 方式yunx

3.1 非数据环境启动

不推荐

3.2 数据库环境启动

  1. 初始化数据库

sudo docker pull postgres

sudo docker run -d --name kongDatabaseDev \
  --net=host \
  -p 5432:5432 \
  -e "POSTGRES_USER=kong" \
  -e "POSTGRES_DB=kong" \
  -e "POSTGRES_PASSWORD=kong" \
  postgres
  1. 在数据库里面初始化 kong 所需要的数据库结构

指定 kong 这个镜像怎么找到 postgres 这个数据库,同时要指定数据库的密码

sudo docker run  \
  --net=host \
  -e "KONG_DATABASE=postgres" \
  -e "KONG_PG_HOST=localhost" \
  -e "KONG_PG_USER=kong" \
  -e "KONG_PG_PASSWORD=kong" \
  kong kong migrations bootstrap

docker run  \
  --net=host \
 -e "KONG_DATABASE=postgres" \
 -e "KONG_PG_HOST=localhost" \
 -e "KONG_PG_USER=kong" \
 -e "KONG_PG_PASSWORD=kong" \
kong/kong-gateway:3.5.0.1 kong migrations bootstrap

执行完成说明,在 postgres 这个数据库中已经构建好了 Kong 所依赖的数据结构

  1. 启动 Kong

https://docs.konghq.com/gateway/3.5.x/reference/configuration

sudo docker run -it -d --rm --name kongDev \
     --net=host \
     -p 8000:8000 \
     -p 8443:8443 \
     -p 8001:8001 \
     -p 8444:8444 \
     -e "KONG_DATABASE=postgres" \
     -e "KONG_PG_HOST=localhost" \
     -e "KONG_PG_USER=kong" \
     -e "KONG_PG_PASSWORD=kong" \
     -e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \
     -e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \
     -e "KONG_PROXY_ERROR_LOG=/dev/stderr" \
     -e "KONG_ADMIN_ERROR_LOG=/dev/stderr" \
     -e "KONG_DNS_RESOLVER=127.0.0.1:8600" \
     -e "KONG_ADMIN_LISTEN=0.0.0.0:8001, 0.0.0.0:8444 ssl" \
     kong

docker run -d --name kong-Dev \
	--net=host \
-e "KONG_DATABASE=postgres" \
-e "KONG_PG_HOST=localhost" \
-e "KONG_PG_USER=kong" \
-e "KONG_PG_PASSWORD=kong" \
-e "KONG_PROXY_ACCESS_LOG=/dev/stdout" \
-e "KONG_ADMIN_ACCESS_LOG=/dev/stdout" \
-e "KONG_PROXY_ERROR_LOG=/dev/stderr" \
-e "KONG_ADMIN_ERROR_LOG=/dev/stderr" \
-e "KONG_ADMIN_LISTEN=0.0.0.0:8001" \
-e "KONG_DNS_RESOLVER=127.0.0.1:8600" \
-e "KONG_ADMIN_GUI_URL=http://localhost:8002" \
-p 8000:8000 \
-p 8443:8443 \
-p 8001:8001 \
-p 8444:8444 \
-p 8002:8002 \
-p 8445:8445 \
-p 8003:8003 \
-p 8004:8004 \
kong/kong-gateway:3.5.0.1

KONG_DNS_RESOLVER 重要 ! ! !

说明:

  • -e "KONG_DATABASE=postgres",postgres 数据库

  • -e "KONG_PG_HOST=localhost", 数据库信息,host、user、password

  • -e "KONG_PG_USER=kong"

  • -e "KONG_PG_PASSWORD=kong"

  • -e "KONG_PROXY_ACCESS_LOG=/dev/stdout",代理访问日志

  • -e "KONG_ADMIN_ACCESS_LOG=/dev/stdout",Admin 访问日志

  • -e "KONG_PROXY_ERROR_LOG=/dev/stderr",代理错误日志

  • -e "KONG_ADMIN_ERROR_LOG=/dev/stderr", Admin 错误日志

  • -e "KONG_DNS_RESOLVER=127.0.0.1:8600",DNS 解析服务器

  • -e "KONG_ADMIN_LISTEN=0.0.0.0:8001, 0.0.0.0:8444 ssl",Admin 监听

  • -e "KONG_ADMIN_GUI_URL=http://..:8002" GUI 界面

  • 暴露端口,我们使用 --net=host 模式,可以忽略端口映射

先安装数据库,再安装数据库结构,最后再初始化 Kong

  1. 测试

# 1.首页
localhost:8001/

# 2.所有服务
localhost:8001/services

# 3.GUI界面
http://...:8002/workspaces

4. 配置基于 Counsul 的转发服务

利用 Kong 的 Admin API 完成配置服务,完成对服务的转发

步骤:

前端通过 8000 端口请求 Kong API 网关请求 Product 服务 ( 自己定义的微服务 ) ,Kong 五服务注册中心找到 Product 服务的地址,然后将这个地址转发到对应的服务上

其中 Admin API 负责管理请求路由

4.1 添加一个 service

curl -i -X POST \
  --url http://localhost:8001/services/ \
  --data 'name=product-service' \
  --data 'url=http://product.service.consul'

也可以通过 APIfox 发送请求

到这里服务就添加完毕了,但是还不知道服务具体的地址,这个需要 consul 来配置

4.2 添加一个路由 route

  1. serveces/ 后面添加对应的服务名product—service,表示针对product-service 处理路由

  2. /product 开头的请求都应该转发到 service 上

curl -i -X POST \
  --url http://localhost:8001/services/product-service/routes \
  --data 'paths[]=/product'

访问:8001/route 可以看到路由定义成功

4.3 启动 consul 服务中心

sudo docker run  -it -d  \
--net=host \
-p 8500:8500 \
-p 8600:8600 \
--name=ConsulDevServer \
consul:1.15.4 agent -dev -client=0.0.0.0

# 验证是否能进入ui界面
http://....:8500/
  • 通过 Go 代码注册服务 ( 在服务发现博客中 )

// 启动三个服务
// addr 使用服务器内网IP
go run ServiceHealthCheck.go -addr 10.0.8.13 -port 9000
go run ServiceHealthCheck.go -addr 10.0.8.13 -port 9001
go run ServiceHealthCheck.go -addr 10.0.8.13 -port 9002

root@VM-8-13-debian:~# curl http://10.0.8.13:9000/info
Product Service, 10.0.8.13:9000 
root@VM-8-13-debian:~# curl http://10.0.8.13:9001/info
Product Service, 10.0.8.13:9001 
root@VM-8-13-debian:~# curl http://10.0.8.13:9002/info
Product Service, 10.0.8.13:9002

会随机在三个服务中选择一个为当前请求进行服务

目前的负载均衡是 consul 做的

一定要给 kong 配置 dns_resolver , 并且端口为 8600 ( 因为 consul 的 dns 默认监听在 127.0.0.1:8600 )

5. Kong 核心对象

  • Sevice : 某个服务

  • Route : 路由,接收前端请求

  • Consumer : 消费者 , 服务的使用者 ( 使用网站/APP的登录之后的用户信息 )

  • Plugin : 插件 , 附加在消费者 , 路由 , 服务上的扩展功能 ( Kong 的核心功能是请求转发,除此之外的大部分功能都是以插件的形式扩展到 Kong )

  • Certificate : 证书

  • SNI : 服务器名称指示

  • Upstream : 虚拟主机名 , 可用于通过多个服务 ( 目标 ) 对传入请求进行负载均衡

    • 一个服务可以对应一个 Upstream 服务地址,一个 Upstram 对应多个 Target ,在其中做负载均衡

  • Target : 目标 IP 地址 / 主机名 , 其端口表示后端服务的实力 , 每个 upstream 都可以有多个 target,支持负载均衡

如图 : 消费发起请求,请求携带者消费者数据到路由,路由转发到服务,插件会部署到路由,服务,消费者上

对应关系:

  • service : route -> 1 : n

  • service, route, consumer : plugin -> 1 : n

  • service, upstram -> 1 : 1

  • upstream : target -> 1 : n

全部的对象支持 Admin API 管理,同时 API 为 Restful 风格

另外,非 DB 模式下面,所有修改类的 API 全部失效,只有在 DB 模式下面,才能做全部的 crud 操作

6. Kong 管理 consumer

Kong 管理 consumer : https://docs.konghq.com/gateway/latest/admin-api/#consumer-object

  • consumer 结构定义

{
   "id": "ec1a1f6f-2aa4-4e58-93ff-b56368f19b27",
   "created_at": 1422386534,
   "updated_at": 1422386534,
   "username": "my-username",
   "custom_id": "my-custom-id",
   "tags": ["user-level", "low-priority"]
}

7. Kong 管理 services

Kong 管理 services : https://docs.konghq.com/gateway/latest/admin-api/#service-object

  • service 结构定义

{
   "id": "9748f662-7711-4a90-8186-dc02f10eb0f5",
   "created_at": 1422386534,
   "updated_at": 1422386534,
   "name": "my-service",
   "retries": 5,
   "protocol": "http",
   "host": "example.com",
   "port": 80,
   "path": "/some_api",
   "connect_timeout": 60000,
   "write_timeout": 60000,
   "read_timeout": 60000,
   "tags": ["user-level", "low-priority"],
   "client_certificate": {"id":"4e3ad2e4-0bc4-4638-8e34-c84a417ba39b"},
   "tls_verify": true,
   "tls_verify_depth": null,
   "ca_certificates": ["4e3ad2e4-0bc4-4638-8e34-c84a417ba39b", "51e77dc2-8f3e-4afa-9d0e-0e3bbbcfd515"],
   "enabled": true
}

8. Kong 管理插件

官网列出了所有插件 : https://docs.konghq.com/hub/

Kong 管理插件 API : https://docs.konghq.com/gateway/latest/admin-api/#plugin-object

  • 插件结构定义

{
   "id": "ce44eef5-41ed-47f6-baab-f725cecf98c7",
   "name": "rate-limiting",
   "created_at": 1422386534,
   "updated_at": 1422386534,
   "route": null,
   "service": null,
   "consumer": null,
   "instance_name": rate-limiting-foo,
   "config": {"hour":500, "minute":20},
   "protocols": ["http", "https"],
   "enabled": true,
   "tags": ["user-level", "low-priority"],
   "ordering": {"before":["plugin-name"]}
}

插件有优先级,始终执行一次,并且每个请求仅运行一次

  • 在官网优优先级顺序,可以简单的记为消费者,路由,服务

9. Kong 负载均衡

限流 : 当请求当到一定规模时,控制 API 的请求量

对超出限制的请求量作出快速拒绝,快速失败,丢弃处理,以保证本服务以及下游资源系统的稳定

常用的限流算法有:

  • 固定窗口计数法 ( Fixed Window )

  • 滑动窗口计数法 ( Sliding Window )

  • 漏桶算法 ( Leaky Bucket )

  • 令牌桶算法 ( Token Bucket )

kong 网关中实现了固定窗口计数法和滑动窗口计数法

10.1 固定窗口计数法

在固定的时间内,比如 5s 内只能处理 10000 个请求,在该窗口时间段内,每来一个请求,计数器加 1,当请求数达到限额时,窗口时间内之后的请求都讲被丢弃

  • 优点:实现容器,资源使用率低

  • 缺点

    • 如果在前半段时间内达到了请求阈值,那个后半段时间内该服务无法使用

  • 瞬时流量可能产生两倍于阈值的问题

10.2 滑动窗口计数法

滑动窗口计数法是固定窗口计数法的改进,解决了切换窗口可能会产生两倍与请求阈值的问题,TCP 协议中的数据包传输,同样采用滑动窗口进行流量控制

滑动窗口的窗口时间段是随着时间向下滑动的,而滑动的时间段就是滑动周期,将 5s 划分为 5个小窗口,每隔 1s 移动一次,子窗口划分的越多,则限流越精准,也称越平滑。

每个小区间单独统计请求次数,滑动窗口的次数为全部子区间次数之和。若超过最大限制,则本窗口后续请求会被限制。随着时间推移,进入下一个窗口期,重新计算全部子区间之和

实操时,超限后的请求往往会被缓存起来,后边慢慢处理,而不是直接丢弃,来提升应用可用性。

10.3 漏桶算法

10.4 令牌桶算法

11. 服务熔断和降级

11.1

 

0

评论区