Spring Cloud Gateway
API网关
微服务架构中存在的问题
在微服务架构中,一个系统往往由多个微服务组成,每个服务都只会完成特定领域的功能,在这种情况下就产生了一些问题
- 所有微服务分布在不同的服务器,可能是不同的ip、不同的端口
- 服务的鉴权会分布在每个微服务中处理,对于每个服务的调用都需要重复的鉴权
- 在后端的微服务架构中,可能采用不同的协议,比如HTTP\RPC等。客户端调用不多个服务,需要对不同服务协议进行适配
API网关
API网关就是为了解决上述问题, 在客户端与服务端增肌了一个API网关。
API网关有如下几个作用
- 请求接入,作为所有API接口服务的请求接入点,聚合所有后端业务服务
- 针对所有请求进行统一的鉴权,限流,熔断,日志记录
- 对所有Api 进行管理,统一的错误码处理
- 灰度发布,对较大功能性改动版本一般采用灰度发布(金丝雀发布),在网关层可以通过灰度规则进行部分流量的路由
Spring Cloud Gateway
Spring Cloud Gateway 旨在提供一种简单而有效的途径来发送 API,并为它们提供横切关注点,例如:安全性,监控/指标和弹性。
Spring Cloud Gateway功能:
- 建立在Spring Framework 5,Project Reactor和Spring Boot 2.0之上
- 能够匹配任何请求属性上的路由。
- 断言和过滤器特定于路由。
- 断路器集成。
- Spring Cloud DiscoveryClient集成
- 易于编写的谓词和过滤器
- 请求速率限制
- 路径改写
Spring Cloud Gateway 中的几个概念
- Route (路由):网关最基本的模块。它由一个 ID、一个目标 URI、一组断言(Predicate)和一组过滤器(Filter)组成。
- Predicate(谓词):路由转发的判断条件,我们可以通过 Predicate 对 HTTP 请求进行匹配,例如请求方式、请求路径、请求头、参数等,如果请求与断言匹配成功,则将请求转发到相应的服务。
- Filter(过滤器):过滤器,我们可以使用它对请求进行拦截和修改,还可以使用它对上文的响应进行再处理
Gataway 工作流程
Gataway 实战
-
创建一个springboot 工程增加如下依赖
采用nacos为注册中心,配置中心,sentinel进行流控<!-- SpringCloud Gateway --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-datasource-nacos</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!--Nacos Config--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> <!--SpringBoot Test--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- SpringCloud Alibaba Sentinel --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> </dependency> <!-- hutool--> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.8.5</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency>
-
创建一个rest服务增加 如下接口 和配置
```java @RestController @RequestMapping("/order") @RequiredArgsConstructor public class OrderController { @GetMapping public ResponseEntity<Object> get () { Map<String,String> map = new HashMap<>(); map.put("name","zcct"); return new ResponseEntity<>( map, HttpStatus.OK) ; } } ```
# Tomcat server: port: 9002 # Spring spring: application: # 应用名称 name: zcct-rest profiles: # 环境配置 active: dev cloud: nacos: discovery: # 服务注册地址 server-addr: 127.0.0.1:8848 namespace: zcctConfig group: zcct config: # 配置中心地址 server-addr: 127.0.0.1:8848 # 配置文件格式 file-extension: yml # 共享配置 namespace: zcctConfig group: zcct shared-configs: - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
-
gateway配置文件 增加如下配置
spring: redis: host: localhost port: 6379 password: cloud: gateway: discovery: locator: lowerCaseServiceId: true enabled: true routes: - id: zcct-rest uri: lb://zcct-rest predicates: - Path=/rest/** filters: - StripPrefix=1
-
启动项目访问网关
Gateway 原理
Route Predicate Factory.
Predicate 是 java8 提供的一个函数式接口,它允许接收一个参数并返回一个布尔值,可以用于条件过滤、请求参数的校验/
在gateway中 Perdicate 提供了路由规则匹配机制。简单点说,Predicate 是路由转发的判断条件,请求只有满足了 Predicate 的条件,才会被转发到指定的服务上进行处理。
Spring Cloud Gateway中默认提供了很多 Route Predicate Factory.
图片引用
常见的 Predicate 断言
断言 | 示例 |
---|---|
Path | - Path=/dept/list/** |
Before | - Before=2021-10-20T11:47:34.255+08:00[Asia/Shanghai] |
After | - After=2021-10-20T11:47:34.255+08:00[Asia/Shanghai] |
Between | - Between=2021-10-20T15:18:33.226+08:00[Asia/Shanghai],2021-10-20T15:23:33.226+08:00[Asia/Shanghai] |
Cookie | - Cookie=name,c.biancheng.net |
Header | - Header=X-Request-Id,\d+ |
Method | - Method=GET |
GatewayFilter Factory.
Filter分为Pre类型的过滤器和Post类型的过滤器
- Pre类型的过滤器在请求转发到后端服务之前执行,在Pre类型的过滤器中可以做鉴权、限流等操作
- Post类型的过滤器在请求执行完之后,将结果返回给客户端之前执行。
在Spring Cloud Gateway中内置了很多Filter,Filter有两种实现,分别是GatewayFilter和GlobalFilter。
GlobalFilter会应用在所有路由上,而GatewayFilter会应用在单个或者一个分组路由上
常见的GatewayFilter
GlobalFilter
GlobalFilter 是一种作用于所有的路由上的全局过滤器,通过它,我们可以实现一些统一化的业务功能,例如权限认证、IP 访问限制等。当某个请求被路由匹配时,那么所有的 GlobalFilter 会和该路由自身配置的 GatewayFilter 组合成一个过滤器链。
- GatewayMetricsFilter,提供监控指标。
- LoadBalancerClientFilter,整合Ribbon针对下游服务实现负载均衡
- ForwardRoutingFilter,用本地Forwoard,请求不转发到下游服务器
- NettyRoutingFilter,使用Netty和httpClient转发HTTP、HTTPS请求