SpringCloud_Gateway服务网关

本文详细介绍了SpringCloudGateway服务网关的核心概念,包括路由、断言的使用,动态路由的实现,以及过滤器在鉴权、限流等方面的应用。文中还涉及到动态路由的配置,如Path、After、Before、Between等断言的使用,以及Cookie、Header等断言的验证。此外,文章讨论了如何通过自定义过滤器和全局过滤器实现用户鉴权,包括JWT的使用以及如何在服务网关中实现用户登录验证和权限控制。
摘要由CSDN通过智能技术生成

一、SpringCloudGateway服务网关概论

1、SpringCloudGateway服务网关概论

Spring Cloud Gateway 用"Netty + Webflux"实现,不需要导入Web依赖。

  1. Webflux模式替换了旧的Servlet线程模型。用少量的线程处理request和response io操作,这些线程称为Loop线程,而业务交给响应式编程框架处理,响应式编程是非常灵活的,用户可以将业务中阻塞的操作提交到响应式框架的work线程中执行,而不阻塞的操作依然可以在Loop线程中进行处理,大大提高了Loop线程的利用率。
    即Webflux中的Loop线程不仅可以处理请求和响应请求,还可以对业务中不阻塞的操作进行处理,从而提高它的利用率。阻塞的操作由work线程进行处理。
  2. Webflux虽然可以兼容多个底层的通信框架,但是一般情况下,底层使用的还是Netty,毕竟,Netty是目前业界认可的最高性能的通信框架。
    Netty 是一个基于NIO的客户、服务器端的编程框架。提供异步的、事件驱动的网络应用程序框架和工具,用以快速开发高性能、高可靠性的网络服务器和客户端程序。
  3. Spring Cloud Gateway特点
    1)易于编写谓词( Predicates )和过滤器( Filters ) 。其Predicates和Filters
    可作用于特定路由。
    2)支持路径重写。
    3)支持动态路由。
    4)集成了Spring Cloud DiscoveryClient。

2、SpringCloudGateway的三大核心概念

  1. 路由(Route)
    这是网关的基本构建块。它由一个ID,一个目标URI,一组断言和一组过滤器定义。如果断言为真,则路由匹配。
    即根据URL请求去匹配路由。
  2. 断言(predicate)
    输入类型是一个ServerWebExchange。我们可以使用它来匹配来自HTTP请求的任何内容,例如headers或参数。匹配请求内容。
    匹配完路由后,每个路由上面都会有断言,然后根据断言来判断是否可以进行路由。
  3. 过滤(filter)
    在匹配完路由和断言为真后,可以在请求被路由前或者之后对请求进行修改。
    即根据业务对其进行监控,限流,日志输出等等。

二、SpringCloudGateway的路由及断言

1、子模块项目SpringCloudGateway的搭建

  1. 在cloud父项目中新建一个模块Module,创建子模块网关cloud-gateway-gateway9527

  2. 在POM文件中添加如下依赖

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <parent>
            <artifactId>cloud</artifactId>
            <groupId>com.zzx</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>cloud-gateway-gateway9527</artifactId>
    
        <properties>
            <maven.compiler.source>17</maven.compiler.source>
            <maven.compiler.target>17</maven.compiler.target>
        </properties>
        <dependencies>
            <!--  引入网关Gateway依赖   -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-gateway</artifactId>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.22</version>
            </dependency>
            <!--  引入Eureka client依赖 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
            </dependency>
            <!-- actuator监控信息完善 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-actuator</artifactId>
            </dependency>
        </dependencies>
    
    
    </project>
    
  3. 在gateway子模块中创建包com.zzx,在包下创建主启动类GatewayMain9527

    package com.zzx;
    
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    @Slf4j
    public class GatewayMain9527 {
         
        public static void main(String[] args) {
         
            SpringApplication.run(GatewayMain9527.class,args);
            log.info("************ GatewayMain9527服务 启动成功 *************");
        }
    }
    
    
  4. 在resources目录下创建application.yml文件,配置如下

    server:
      port: 9527
    spring:
      cloud:
        gateway:
          routes:
            # 路由ID,没有固定规则但要求唯一,建议配合服务名
            - id: cloud-payment-provider
              # 匹配后提供服务的路由地址 (即目标服务地址)
              uri: http://localhost:8001
              # 断言会接收一个输入参数,返回一个布尔值结果
              predicates:
                # 路径相匹配的进行路由
                - Path=/payment/*
    
    
  5. 测试
    1)先开启7001和7002的Eureka服务,payment8001服务提供者和gateway9527服务。
    2)在浏览器使用9527端口,也就是网关进行访问payment8001服务即可。
    在浏览器输入:http://localhost:9527/payment/index

2、SpringCloudGateway_Java API构建路由

  1. 在子模块cloud-gateway-gateway9527中的com.zzx包下,创建包config,并在包下创建GatewayConfig

    package com.zzx.config;
    
    import org.springframework.cloud.gateway.route.RouteLocator;
    import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class GatewayConfig {
         
        @Bean
        public RouteLocator routeLocator(RouteLocatorBuilder builder){
         
            //获取路由
            RouteLocatorBuilder.Builder routes = builder.routes();
            /**
             * 设置路由
             * 1.路由id
             * 2.路由匹配规则
             * 3.目标地址
             */
            routes.route("path_route",r->r.path("/payment/*").uri("http://localhost:8001/")).build();
            return routes.build();
        }
    }
    
    
  2. 测试
    1)将yml文件中的gateway配置注释掉,然后重启该服务。
    2)在浏览器上访问:http://localhost:9527/payment/index

3、SpringCloudGateway的动态路由功能

  1. 再添加一个服务提供者,用以实现Gateway网关的动态路由的功能。
    1)复制payment8001服务,然后点击cloud父工程,ctrl+v进行粘贴,修改名字为8002
    2)修改POM文件:

    <artifactId>cloud-provider-payment8002</artifactId>
    

    3)将POM右键,选择添加为Maven项目Add as Maven Project
    在这里插入图片描述
    4)修改com.zzx包下的启动类的名字以及类中的名字

    package com.zzx;
    
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    /**
     * 主启动类
     */
    @SpringBootApplication
    @Slf4j
    public class PaymentMain8002 {
         
        public static void main(String[] args) {
         
            SpringApplication.run(PaymentMain8002.class,args);
            log.info("****** PaymentMain8002服务启动成功 *****");
        }
    }
    
    

    5)将yml文件的端口号port和instance-id的名字有8001部分都修改为8002
    然后在启动类中运行该payment8002服务。

  2. 修改gateway9527项目的yml文件

    server:
      port: 9527
    
    eureka:
      instance:
        # 注册名
        instance-id: cloud-gateway-gateway9527
      client:
        service-url:
          # Eureka server的地址
          #集群
          defaultZone: http://localhost:7001/eureka,http://localhost:7002/eureka
          #单机
          #defaultZone: http://localhost:7001/eureka/
    spring:
      application:
        #设置应用名
        name: cloud-gateway
      cloud:
        gateway:
          routes:
            # 路由ID,没有固定规则但要求唯一,建议配合服务名
            - id: cloud-payment-provider
              # 匹配后提供服务的路由地址 (即目标服务地址) lb后跟提供服务的微服务的名字
              uri: lb://CLOUD-PAYMENT-PROVIDER
              # 断言会接收一个输入参数,返回一个布尔值结果
              predicates:
                # 路径相匹配的进行路由
                - Path=/payment/*
    
  3. 注释之前的配置文件GatewayConfig中的方法。

  4. 在服务提供者payment8001和payment8002中的com.zzx.controller的PaymentController类中添加如下代码

    @Value("${server.port}")
    private String port;
    @GetMapping("lb")
    public String lb(){
         
        return port;
    }
    

    即通过该lb的url请求来测试动态路由是否配置生效。

  5. 测试动态路由是否配置生效。
    1)重启payment8001和payment8002以及gateway9527服务
    2)浏览器中访问:http://localhost:9527/payment/lb
    在这里插入图片描述
    在这里插入图片描述
    此时刷新后随即出现8001或8002,估计是轮询的策略。

4、SpringCloudGateway的路由断言

  1. UTC时间格式的时间参数时间生成方法

    package demo;
    
    import java.time.ZonedDateTime;
    
    public class Test1 {
         
    	public static void main(String[] args) {
         
    		ZonedDateTime now = ZonedDateTime.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值