微服务之网关
API网关除了提供对外部http接口统一管理,还需要实现动态路由、限流管理等能力。
网关能力
服务路由
- 静态路由策略配置
- 后端服务的软负载均衡
- 后端服务的心跳检查
- 参数分流
- 流量的镜像复制
服务治理
- 后端服务的故障隔离
- 网关、服务、API 级别的限流和熔断
- 固定时段和周期时段的 API 维护开关
服务治理框架层的服务治理和流量管理:
服务治理
- 服务限流,支持 QPS、Thread 等多种限流方式
- 降级与熔断,支持基于RT、错误率的熔断策略以及手动降级策略
- 服务容错,支持 failover、failfast、failback等多种容错机制
流量管理
- 路由管理,支持基于黑白名单的路由规则
- 负载均衡,支持多种负载均衡规则,兼容 Spring Cloud Ribbon
- 参数分流,支持参数取模、名单分流、权重分流等
技术选型
这里使用Kong
作为演示
Kong
Kong是一个云原生,快速,可扩展和分布式微服务抽象层(也称为API网关,API中间件或某些情况下的Service Mesh)。作为2015年的开源项目,其核心价值在于高性能和可扩展性。
安装
这里使用postgres
作为后端存储,为了后续网络通信方便,使用新创建的网桥网络
1 | docker network create kong-net |
如果使用默认网络,使容器可以相互互通即可(官方提供自定义网桥,可以实现通过容器直接通信,如果使用默认bridge
,则需要通过--link name:name
通信)
1 | docker run -d --name kong-database \ |
初始化数据库
1 | docker run --rm --network=kong-net \ |
启动 Kong Gateway
服务
1 | docker run -d --name kong-gateway \ |
- 8001 管理端口
- 8002 管理员访问页面端口(功能较少,后续使用
konga
) - 8000 用户访问的端口
通过8081
端口查看服务是否正常
1 | curl -i -X GET --url http://localhost:8001/services |
1 | HTTP/1.1 200 OK |
安装konga
kongga
是一个操作kong
的图形化界面,也支持通过docker
安装
1 | docker run -d -p 1337:1337 \ |
通过 http://ip地址:1337/register
打开首次登录注册页面,注册之后,登录
通过 8001
端口配置
定义
Service 服务
顾名思义,服务实体是每个上游服务的抽象。举个例子,services 可以是一个数据转换微服务,一个计费api等等。
Service 的主要属性是其URL(Kong应该将流量代理到的地方),可以设置为单个字符串,也可以单独指定其
protocol
,host
,port
和path
。Service 与 router 相关联(一个 Service 可以有许多与之关联的 router)。router 是Kong的入口点,并定义匹配客户端请求的规则。一旦 router 匹配,Kong就会将请求代理到其关联的服务。有关Kong代理流量的详细说明,请参阅代理参考。
Route 路由
路由实体定义规则以匹配客户端请求。每个Route与一个服务相关联,一个服务可能有多个与之关联的路由。匹配给定路由的每个请求都将代理到其关联的服务。
Routes 和 Services 的组合(以及它们之间的关注点分离)提供了一种强大的路由机制,通过它可以在 Kong 中定义细粒度的入口点,从而导致基础架构的不同上游服务。Upstream 上游
上游对象表示虚拟主机名,可用于通过多个服务(目标)对传入请求进行负载均衡。例如,对于主机为
service.v1.xyz
的 Service 对象,上游名为service.v1.xyz
。对此服务的请求将代理到上游定义的目标。上游还包括健康检查程序,该检查程序能够基于其能力或无法提供请求来启用和禁用目标。运行状况检查程序的配置存储在上游对象中,并应用于其所有目标。
plugin 插件
插件实体表示将在HTTP请求/响应生命周期期间执行的插件配置。它是如何为在Kong后面运行的服务添加功能的,例如 Authentication 或 Rate Limiting 。您可以访问Kong Hub,获取有关如何安装以及每个插件所需值的更多信息。
将插件配置添加到服务时,客户端向该服务发出的每个请求都将运行所述插件。如果某个特定消费者需要将插件调整为不同的值,您可以通过创建一个单独的插件实例来实现,该实例通过
service
和consumer
这两个字段指定服务和消费者。consumer 消费者
Consumer对象表示Service服务的使用者或用户。您可以依靠Kong作为主数据存储,也可以将使用者列表与数据库映射,以保持Kong与现有主数据存储之间的一致性。
基础操作
新增service
点击 service-add service
Url:http://192.168.41.68:8080
代表转发到的Url
upstream
可进行健康检查和负载均衡,在结合consul
后,可以更好的实时变更后端服务状态。
设置dns_resolver
为consul
的地址,将Url
改为consul
的域名。
新增route
在新增的service中,点击名称-routes-add route即可
需要注意,点击path
后,需要通过回车,将该路径加入到Paths
中
通过Kong
的8000
端口,以及对应服务的path
,访问测试接口
1 | curl http://192.168.41.68:8000/api/v1/version |
1 | {"code":200, "result":{"go_version":"go1.16.7"}}% |
配置jwt的插件
JWT 插件
在Consumers
中创建一个consumer
为这个consumer
添加jwt
点击credentials
,点击JWT
,点击Create JWT
添加全局JWT
,点击plugins-add global plugins-jwt
设置header
,与后端服务保持一致,通过回车添加。
在jwt.io中生成jwt
需要注意,在payload
中添加iss
,与创建全局jwt
时默认的 key claim name
保持一致
拷贝consumer
中创建jwt
时生成的secret
作为生成jwt的secret
当没有配置jwt时发送请求
在header
中配置x-token: Bearer
配置之后
推荐阅读:
API 网关能做什么?](https://www.redhat.com/zh/topics/api/what-does-an-api-gateway-do)
Goku
Apinto
微服务 API 网关 Kong 中文文档