简介

https://mp.weixin.qq.com/s/f2hepLraaqUgRKqq9ZKKsQ

基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等技术, 目标是替代 Netflix ZUUL
千万不要依赖 引入spring-boot-starter-web包

在这里插入图片描述

  1. 客户端向 Spring Cloud Gateway 发出请求。
  2. 路由判断 :在 Gateway Handler Mapping 中找到与请求相匹配的路由,
  3. 请求过滤:将其发送到 Gateway Web Handler。Handler 再通过指定的过滤器链对请求进行拦截和修改
  4. 服务处理:请求发送到我们实际的服务执行业务逻辑
  5. 响应过滤:后端处理完结果后,返回给 Gateway 的过滤器再次做处理
  6. 然后返回。

简单来说就是 把符合 {匹配规则} 的请求 发给 {服务地址} ,请求与返回 期间经过 {过滤处理}

routes 路由服务

Spring Gateway支持两种方式提供路由服务,其一是配置文件启用,其二则是通过代码达到目的

spring:
  application:
    name: xxxx
  cloud:
    # 配置 路由网关
    gateway:
      # 配置路由规则
      routes:
      - id: {路由id}
        uri: {服务地址}
        predicates:
        - {匹配规则}
        filters:
        - {过滤处理}

1. 配置文件方式

spring:
  application:
    name: xxxx
  cloud:
    # 配置 服务注册发现
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
    # 配置 路由网关
    gateway:
      # 设置与服务注册发现组件结合,这样可以采用服务名的路由策略
      discovery:
        locator:
          enabled: true
      # 配置路由规则
      routes:
        # 路由 ID,不同的 id 有不同的功能
      - id: activity-route
        #  要使用nacos服务注册中心的服务:lb://{注册的服务名}
        uri: lb://activity
        # 路由断言Factories
        predicates:
        - Path=/activity/**
      - id: search-route
        uri: http://localhost:8081
        predicates:
        - Method=GET
        filters:
          # 转发请求时去掉1级前缀
        - StripPrefix=1

表示 以/activity/**开头的请求 转发到 lb://activity服务

Gateway默认转发是全路径的,
设置 StripPrefix =1 表示从二级url路径转发,即http://ip:port/1/2/3会转发到http://ip:port/2/3

2. Java DSL方式

@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
        		//一个 .route 就是一个路由规则
                .route(r -> r.path("/activity/**")
                        .filters(f -> f.stripPrefix(1).filter(new TestGetWayFilter()).addResponseHeader("X-Response-Default-Foo", "Default-Bar"))
                        .uri("lb://activity")
                        .order(0) //如果路由需要有顺序匹配的,需要使用 order 方法 值越小优先匹配
                        .id("activity-route")
                )
                .route(r -> r.path("/activity/**")
                		//使用
                        .filters(f ->  f.filter(new myFilter()))
                        .uri("lb://activity")
                        .order(0) //如果路由需要有顺序匹配的,需要使用 order 方法 值越小优先匹配
                        .id("activity-route")
                )
                .build();
 }

动态路由

  • 基于 Nacos 注册中心
    Spring Cloud Gateway可以从注册中心获取服务的元数据(例如服务名称、路径等),然后根据这些信息自动生成路由规则

通过 Nacos Server 和 Spring Cloud Alibaba Nacos Config 即可实现配置的动态变更,官方文档地址:https://github.com/alibaba/spring-cloud-alibaba/wiki/Nacos-configopen in new window

predicates 路由断言

Spring会根据名称去查找对应的FilterFactory,目前支持的名称有:After、Before、Between、Cookie、Header、Host、Method、Path、Query、RemoteAddr。

predicates:
		# 在该日期时间之后发生的请求都将被匹配
        - After=2017-01-20T17:42:47.789-07:00[America/Denver]
		# 在该日期时间之前发生的请求都将被匹配。
        - Before=2017-01-20T17:42:47.789-07:00[America/Denver]
        # 在datetime1和datetime2之间的请求将被匹配
        - Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]
		# 请求包含此cookie名称且正则表达式为真的将会被匹配
		- Cookie=chocolate, regular expression
		- Header=X-Request-Id, \d+
		- Host=**.somehost.org,**.anotherhost.org
		- Method=GET
		- Path=/foo/{segment},/bar/{segment}
		- Query=baz
		- Query=foo, ba.
		- RemoteAddr=192.168.1.1/24

过滤器

  • 分类
    1. 请求 Pre 类型
      参数校验、权限校验、流量监控、日志输出以及协议转换等操作
    2. 响应 Post 类型
      修改响应内容或响应头、日志输出、流量监控等。
    3. 全局 过滤器 GlobalFilter
      用作负载均衡
    4. 局部 过滤器 GatewayFilter

filters 过滤功能

在这里插入图片描述

filters:
          # 转发请求时去掉1级前缀
        - StripPrefix=1
          # 给请求的Header中添加: X-Request-Foo, Bar 
        - AddRequestHeader=X-Request-Foo, Bar
          # 给响应的Header中添加: X-Request-Foo, Bar 
        - AddResponseHeader=X-Response-Foo, Bar

自定义过滤器

实现 GlobalFilter, Ordered 接口并在类上增加 @Component 注解就可以使用过滤功能

import .......

/**
 * 过滤器
 */
@Component
public class myFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        String path = request.getPath().pathWithinApplication().value();
		//TODO
		
        return chain.filter(exchange);
    }

    /**
    * 设置过滤器的执行顺序
    * @return 
    */
    @Override
    public int getOrder() {
        return 1;
    }
}

限流过滤器

Spring Cloud Gateway 自带了限流过滤器,对应的接口是 RateLimiter,RateLimiter 接口只有一个实现类 RedisRateLimiter (基于 Redis + Lua 实现的限流),提供的限流功能比较简易且不易使用。

从 Sentinel 1.6.0 版本开始,Sentinel 引入了 Spring Cloud Gateway 的适配模块,可以提供两种资源维度的限流:route 维度和自定义 API 维度。也就是说,Spring Cloud Gateway 可以结合 Sentinel 实现更强大的网关流量控制

异常处理

Spring Cloud Gateway 提供了多种全局处理的方式,比较常用的一种是实现ErrorWebExceptionHandler并重写其中的handle方法。

不能用SpringBoot 的@RestControllerAdvice和 @ExceptionHandler

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐