网关是什么
百度百科:网关(Gateway)又称网间连接器、协议转换器,在网络层以上实现,连接两个或者多个广域网或者局域网。
我们这里说的是API网关,指的是所有api调用的统一入口。
api网关的在架构中的位置,如下图
图1
为什么需要网关
随着微服务的增多,如果跟之前一样还是客户端直接对接不同的微服务,会有很多不便:
- 客户端多次请求不同的服务,增加了客户端的复杂性
- 可能存在跨域问题
- 每个服务都需要独立身份认证
- 随着项目的发展,将难以重构
网关的功能
-
安全防护
- 防刷,黑白名单
-
协议适配
- 封闭内部不同的协议实现,对外提供统一的协议
-
流量监控和容错
- 限流,降级,熔断
-
统一接入
- 统一认证鉴权
- 统一限流
- 避免新增服务还需要新分配域名,配置nginx,服务拆分还需要客户端配合改造。
-
其他:日志,缓存(幂等接口的缓存)
常见的网关实现
zuul
基于web servlet,核心是一系列的filtres,无缝集成hystrix,zuul1是单线程接收转发处理,阻塞IO,不支持长连接。目前已有zuul2.
kong
本质基于nginx+lua(略)
traefik
go语言开发,目前比较适合k8s。
gateway
组成部分:
- 路由:最基础部分,唯一的ID对应的目的URL,包含若干断言和过滤器。
- 断言:根据配置的路由规则,对http request进行断言匹配。(if else)
- 过滤器:对请求和响应进行修改。
工作原理:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KvGkzEjz-1644834368139)(images/image-20210606214157231.png)]
客户端向Spring Cloud Gateway发出请求。如果gateway handler mapping确定了一个请求与路由匹配,它将被发送到gateway Web handler。过滤器被虚线分隔的原因是,过滤器可以在发送代理请求之前和之后运行逻辑。执行所有的“pre”过滤逻辑。然后发出代理请求。代理请求发出后,将运行“post”筛选逻辑。
servicemesh
去中心化的方案(略)
怎么使用网关
以spring cloud gateway为例
路由规则
-
Path
spring:cloud:gateway:routes:- id: baidu_ # 路由ID唯一uri: http://baidu.com # 路由URI,路由到的服务地址predicates: # 断言判断Path=/baidu/** # 匹配对应的URl请求,将匹配的请求加到URI后面
-
Query
spring:cloud:gateway:routes:- id: query_routeuri: https://example.orgpredicates:- Query=red, gree. #包含请求参数red并且参数值满足正则表达式gree。如green,geet都匹配
-
Method
spring:cloud:gateway:routes:- id: method_routeuri: https://example.orgpredicates:- Method=GET,POST #GET,POST方法匹配
-
DateTime
spring:cloud:gateway:routes:- id: after_routeuri: https://example.orgpredicates:- After=2017-01-20T17:42:47.789-07:00[America/Denver] #该时间之后
spring:cloud:gateway:routes:- id: before_routeuri: https://example.orgpredicates:- Before=2017-01-20T17:42:47.789-07:00[America/Denver] #该时间之前
spring:cloud:gateway:routes:- id: between_routeuri: https://example.orgpredicates:#该时间之间- Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]
-
RemoteAddr
spring:cloud:gateway:routes:- id: remoteaddr_routeuri: https://example.orgpredicates:- RemoteAddr=192.168.1.1/24 #请求地址匹配到
-
Header
spring:cloud:gateway:routes:- id: header_routeuri: https://example.orgpredicates:- Header=X-Request-Id, \d+ #请求头包含
-
weight
spring:cloud:gateway:routes:- id: weight_highuri: https://weighthigh.orgpredicates:- Weight=group1, 8 #group1组80%的流量- id: weight_lowuri: https://weightlow.orgpredicates:- Weight=group1, 2 #group1组20%的流量
动态路由
根据服务名称路由
spring:cloud:gateway:routes:- id: baidu_ #路由ID唯一uri: lb://customer-service #动态路由,根据注册中心的服务名称自动选择predicates: # 断言判断Path=/baidu/** # 匹配对应的URl请求,将匹配的请求加到URI后面
根据serviceId自动路由
spring:cloud:gateway:discovery:locator:enabled: true #从注册中心自动获取
过滤器
网关过滤器(gatewayFilter)
只作用在当前路由上或者通过spring.cloud.default-filters配置在全局,作用在所有路由上.
https://docs.spring.io/spring-cloud-gateway/docs/2.2.8.RELEASE/reference/html/#gatewayfilter-factories
全局过滤器(globalFilter)
不需要在配置文件里配置,作用在所有的路由上,最终通过gatewayFilterAdapter包装程gatewayfilterChain可识别的过滤器.
https://docs.spring.io/spring-cloud-gateway/docs/2.2.8.RELEASE/reference/html/#global-filters
自定义过滤器
自定义网关过滤器
实现接口: GatewayFilter,Ordered
自定义全局过滤器
实现接口:GlobalFilter, Ordered , 交给容器会自动生效,不需要配置.