Spring Cloud学习笔记【网关-Gateway】

Gateway概述

Gateway是什么

Spring Cloud Gateway是Spring Cloud生态系统中的一种轻量级网关解决方案。它是基于Spring Framework 5、Spring Boot 2和Project Reactor等技术构建的,可用于构建高效、可扩展的微服务架构。
在这里插入图片描述
Spring Cloud Gateway的主要作用是对来自客户端的请求进行路由和转发,它可以根据请求的URL、请求头、请求参数等信息来判断请求的目标服务,并将请求转发给相应的服务。同时,Spring Cloud Gateway还提供了一些常用的过滤器,如路由、限流、重试、缓存等,这些过滤器可以帮助开发人员实现一些常见的功能,如访问控制、安全认证等。

具体功能

  1. 路由功能:Spring Cloud Gateway可以根据请求的URI、请求头、请求参数等信息进行路由转发,支持多种路由规则,如Path Route、Host Route、Predicate Route等。
  2. 过滤器功能:Spring Cloud Gateway提供了一些内置的过滤器,如Request Header、Response Header、Rewrite Path等,同时也支持开发人员自定义过滤器。
  3. 动态路由:Spring Cloud Gateway支持动态路由,可以动态地添加、删除和修改路由规则,而无需重新启动网关实例。
  4. 熔断功能:Spring Cloud Gateway支持熔断器,可以对后端服务进行熔断,防止服务雪崩,提高系统的可用性。
  5. 限流功能:Spring Cloud Gateway可以基于QPS、并发数等指标来进行限流,防止系统被过载。
  6. 安全认证功能:Spring Cloud Gateway支持各种安全认证机制,如OAuth2、JWT等。
  7. 日志和监控功能:Spring Cloud Gateway提供了丰富的日志和监控功能,可以方便地监控网关的运行状况和处理性能,便于排查问题和优化性能。
  8. 集成Spring Cloud:Spring Cloud Gateway可以轻松地集成Spring Cloud体系中的各种组件,如Eureka、Consul、Zipkin等,为微服务架构提供完整的解决方案。

Gateway与Zuul的区别

Gateway和Zuul都是Spring Cloud提供的网关组件,它们之间的主要区别在于以下几个方面:

  1. 技术栈不同:Gateway基于Spring WebFlux和Reactor框架,采用异步非阻塞式I/O操作,而Zuul基于Servlet API和阻塞式I/O操作。
  2. 性能不同:Gateway相比Zuul在性能方面更优秀,主要是因为它采用了异步非阻塞式I/O操作,可以提供更高的并发性能和吞吐量。
  3. 功能不同:Gateway提供了丰富的路由规则和过滤器,支持动态路由和限流等功能,而Zuul相对较为简单,只支持一些基本的路由和过滤功能。
  4. 适用场景不同:Gateway适用于高性能和高可伸缩性的场景,而Zuul则适用于一些中小型项目。
  5. 维护和支持不同:Spring Cloud Gateway是Spring Cloud团队的新一代网关组件,受到了官方更好的维护和支持,而Zuul则逐渐被淘汰,不再得到官方的维护和更新。

三大核心概念

Route(路由)

Route指定了请求应该如何被路由,它包括目标URL、路由规则和一些可选的过滤器。通过配置Route,可以将所有的请求映射到对应的微服务实例。

Predicate(断言)

Predicate定义了一个逻辑条件,用于匹配来自客户端的请求。它可以基于请求的URL、请求头、请求参数等信息进行匹配,只有满足条件的请求才会被路由到对应的微服务。

Filter(过滤器)

Filter用于在路由请求之前或之后执行一些额外的逻辑,比如鉴权、流量控制、日志监控等。Gateway提供了很多内置的过滤器,还支持开发人员自定义过滤器。

Gateway的工作流程

在这里插入图片描述

Spring Cloud Gateway的工作流程可以简单地概括为:接收请求、匹配路由、执行过滤器、转发请求。具体来说,它的工作流程如下:

  1. 接收请求:当客户端发送请求到Gateway时,Gateway会将请求接收并将其转发到路由处理器进行处理。
  2. 匹配路由:Gateway会根据请求的URI、请求头、请求参数等信息进行匹配,找到合适的Route。
  3. 执行过滤器:Gateway会按照在Route中配置的顺序执行一系列的Filter,对请求进行处理和转换。过滤器可以在请求被路由到后端服务之前或之后对请求进行修改、转换和增强等操作。
  4. 转发请求:当过滤器处理完请求之后,Gateway会将请求转发到对应的后端服务进行处理。后端服务返回响应后,Gateway会将响应转发给客户端。

需要注意的是,Gateway的核心流程是异步非阻塞式的,它采用了基于Reactor的响应式编程模型,可以提供更高的并发性能和吞吐量。同时,Gateway还支持动态路由和限流等功能,可以满足不同场景下的需求。

网关DEMO配置

yml文件配置路由

新建Gateway的module cloud-gateway-gateway9527
在这里插入图片描述
pom.xml

<dependencies>
        <!--gateway-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <!--eureka-client-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!-- 引入自己定义的api通用包,可以使用Payment支付Entity -->
        <dependency>
            <groupId>com.atguigu.springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>
        <!--一般基础配置类-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

application.yml
主要关注gateway的配置,定义一个路由规则user_routh,可以通过网关访问user服务的接口:

server:
  port: 9527

spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      routes:
        - id: user_routh #user_routh    #路由的ID,没有固定规则但要求唯一,建议配合服务名
          uri: http://localhost:9001          #匹配后提供服务的路由地址
          predicates:
            - Path=/user/info/**         # 断言,路径相匹配的进行路由

eureka:
  instance:
    # 配置eureka的状态显示
    hostname: localhost
    instance-id: ${
    
    eureka.instance.hostname}:${
    
    spring.application.name}:${
    
    server.port}
  client: #服务提供者provider注册进eureka服务列表内
    service-url:
      register-with-eureka: true
      fetch-registry: true
      defaultZone: http://eureka7001.com:7001/eureka

启动类GateWayMain9527

@SpringBootApplication
@EnableEurekaClient
public class GateWayMain9527 {
    
    
    public static void main(String[] args) {
    
    
        SpringApplication.run(GateWayMain9527.class, args);
    }
}

启动项目测试
直接访问9001端口
在这里插入图片描述
通过网关9527 访问,也可以跳转到9001上
在这里插入图片描述

配置类配置路由

举个栗子,新建一个配置类,配置路由到百度新闻。。。

@Configuration
public class GateWayConfig {
    
    
    /**
     * 配置了一个id为route-name的路由规则,
     * 当访问地址 http://localhost:9527/guonei时会自动转发到地址:http://news.baidu.com/guonei
     *
     * @param builder
     * @return
     */
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
    
    
        RouteLocatorBuilder.Builder routes = builder.routes();

        routes.route("path_route_atguigu",
                r -> r.path("/guonei")
                        .uri("http://news.baidu.com/guonei")).build();

        return routes.build();
    }

    @Bean
    public RouteLocator customRouteLocator2(RouteLocatorBuilder builder) {
    
    
        RouteLocatorBuilder.Builder routes = builder.routes();
        routes.route("path_route_atguigu2",
                r -> r.path("/guoji")
                        .uri("http://news.baidu.com/guoji")).build();
        return routes.build();
    }
}

通过微服务名实现动态路由

之前我们的路由uri是写死的地址
在这里插入图片描述
下面我们改为服务名,当服务端有多个服务时可以负载均衡调用
需要注意的是uri的协议为lb,表示启用Gateway的负载均衡功能
更新后:
uri: lb://lf-user
在这里插入图片描述
测试:
9001和9011的两个端口服务轮询调用
在这里插入图片描述
在这里插入图片描述

Predicate

Predicate是什么

在Spring Cloud Gateway中,Predicate是指用于匹配请求的逻辑条件,它是一个函数式接口,用于根据请求的URL、请求头、请求参数等信息判断是否要对当前请求进行处理。Predicate可以通过Gateway的路由规则配置,根据不同的请求条件匹配不同的Route。

在Spring Cloud Gateway中,Predicate可以根据请求的路径、请求参数、请求头、请求方法等信息进行匹配,它可以实现各种复杂的请求匹配逻辑,比如模糊匹配、正则表达式匹配、多个条件的组合匹配等。

常见Route Predicate

  1. Path:根据请求的路径进行匹配,支持Ant风格的路径匹配。
    例如,下面的配置表示只有当请求的路径以/api/user开头时,才会匹配当前的Route:
spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service
          predicates:
            - Path=/api/user/**

  1. Query:根据请求的参数进行匹配,支持参数名和参数值的匹配。
    例如,下面的配置表示只有当请求的参数中包含userId且userId的值不为空时,才会匹配当前的Route:
spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service
          predicates:
            - Query=userId,*
  1. Method:根据请求的方法进行匹配,支持HTTP请求方法的匹配。
    例如,下面的配置表示只有当请求的方法为GET时,才会匹配当前的Route:
spring:
  cloud:
    gateway:
      routes:
        - id: user-service
          uri: lb://user-service
          predicates:
            - Method=GET
  1. Host Predicate:根据请求的Host头进行匹配。例如,Host=example.com表示匹配所有请求的Host头为example.com的请求。
  2. RemoteAddr Predicate:根据请求的远程IP地址进行匹配。例如,RemoteAddr=192.168.0.1/24表示匹配所有IP地址在192.168.0.1子网内的请求。
  3. After Predicate:根据请求的时间进行匹配。例如,After=2021-10-01T00:00:00.000Z表示匹配所有发生时间在2021-10-01之后的请求。
  4. Weight Predicate:根据请求的权重进行负载均衡。例如,Weight=group1,2表示将请求发送到名为group1的服务组中,并且其中有2个实例参与负载均衡。

这些Route Predicate可以组合使用,以实现更加复杂的请求匹配逻辑。同时,Spring Cloud Gateway还支持自定义Route Predicate,开发人员可以根据实际需求自行实现Predicate接口,以实现更加灵活和可定制的网关服务。

Filter

Filter是什么

在Spring Cloud Gateway中,Filter是指用于在请求被路由到目标服务之前或之后对请求和响应进行修改或者处理的组件。它可以对请求进行修改、转换、增强或者根据需要拦截请求或者响应。

Filter是Spring Cloud Gateway的核心组件之一,它可以实现很多网关功能,比如路由转发、请求/响应日志记录、请求鉴权、请求限流、请求重试等。Filter是实现网关自定义功能的关键,可以根据实际需求自定义Filter,满足业务上的特定需求。

Filter接口定义了两个主要的方法:filter()和order()。其中,filter()方法是过滤器的具体实现逻辑,用于对请求进行处理;order()方法则是过滤器的执行顺序,值越小越先执行。

Spring Cloud Gateway内置了很多Filter,例如,RequestRateLimiterGatewayFilterFactory、RetryGatewayFilterFactory、AddRequestHeaderGatewayFilterFactory、HystrixGatewayFilterFactory等等。此外,开发人员也可以根据实际需求自定义Filter,通过实现GatewayFilter或GlobalFilter接口来实现。

常用的GatewayFilter

  1. AddRequestHeader:用于添加请求头。
  2. RemoveRequestHeader:用于删除请求头。
  3. AddResponseHeader:用于添加响应头。
  4. RemoveResponseHeader:用于删除响应头。
  5. SetPath:用于设置请求路径。
  6. RewritePath:用于重写请求路径。
  7. Retry:用于请求重试。
  8. RequestRateLimiter:用于请求限流。
  9. Hystrix:用于熔断保护。
  10. ModifyResponseBody:用于修改响应体。
  11. ModifyResponseHeader:用于修改响应头。
  12. SaveSession:用于在请求处理过程中保存Session。
  13. ForwardPath:用于将请求转发到指定的路径。

自定义过滤器

自定义全局MyLogGateWayFilter
主要实现两个接口implements GlobalFilter, Ordered

具体代码:

@Component
public class MyLogGateWayFilter implements GlobalFilter, Ordered {
    
    

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
    
    
        System.out.println("time:" + new Date() + "\t 执行了自定义的全局过滤器: " + "MyLogGateWayFilter" + "hello");

        String uname = exchange.getRequest().getQueryParams().getFirst("uname");
        if (uname == null) {
    
    
            System.out.println("****用户名为null,无法登录");
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }

    /**
     * 这个返回的数值越小,上面的filter优先级就越高
     *
     * @return
     */
    @Override
    public int getOrder() {
    
    
        return 0;
    }

}

测试

带参数uname 可以正常访问在这里插入图片描述
不带uname 报错
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_33129875/article/details/129727780
今日推荐