网关是什么
百度百科:网关(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_route uri: https://example.org predicates: - Query=red, gree. #包含请求参数red并且参数值满足正则表达式gree。如green,geet都匹配
-
Method
spring: cloud: gateway: routes: - id: method_route uri: https://example.org predicates: - Method=GET,POST #GET,POST方法匹配
-
DateTime
spring: cloud: gateway: routes: - id: after_route uri: https://example.org predicates: - After=2017-01-20T17:42:47.789-07:00[America/Denver] #该时间之后
spring: cloud: gateway: routes: - id: before_route uri: https://example.org predicates: - Before=2017-01-20T17:42:47.789-07:00[America/Denver] #该时间之前
spring: cloud: gateway: routes: - id: between_route uri: https://example.org predicates: #该时间之间 - 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_route uri: https://example.org predicates: - RemoteAddr=192.168.1.1/24 #请求地址匹配到
-
Header
spring: cloud: gateway: routes: - id: header_route uri: https://example.org predicates: - Header=X-Request-Id, \d+ #请求头包含
-
weight
spring: cloud: gateway: routes: - id: weight_high uri: https://weighthigh.org predicates: - Weight=group1, 8 #group1组80%的流量 - id: weight_low uri: https://weightlow.org predicates: - 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 , 交给容器会自动生效,不需要配置.