SpringCloudAlibaba学习笔记(三)--SpringCloud Gateway

本文详细介绍了SpringCloud Gateway的使用,包括引入依赖、启动类配置,以及如何从Nacos获取服务信息。深入探讨了SpringCloud Gateway的执行流程、predicate断言(内置与自定义)和过滤器机制(局部与全局过滤器)。SpringCloud Gateway作为高性能的API网关,具有强大的功能,但也存在学习成本高等挑战。文章通过实例展示了自定义断言和过滤器的实现,有助于读者深入理解其工作原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

API网关,能替换Zuul。比Zuul强大。

优点:

性能强劲:是第一代网关Zuul的1.6倍;

功能强大:内置了很多实用的功能,例如转发、监控、限流等;

设计优雅,容易扩展;

缺点:

其实现依赖Netty与WebFlux,不是传统的Servlet模型,学习成本高;

不能将其部署在Tomcat、Jetty等Servlet容器中,只能打成jar包运行;

需要SpringBoot2.0及以上版本;

使用:

引入依赖:

        <!--    gateway  注意:此模块不能引入starter-web    -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

启动类:

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

配置文件:

server:
  port: 7000
spring:
  application:
    name: api-gateway
  cloud:
    #网关配置
    gateway:
      routes: #路由数组,可配置多个 【路由就是指当请求满足什么样的条件的时候转发到哪个服务】
        - id: product_route #当前路由的标识,唯一
          uri: http://127.0.0.1:8081 #请求最终要被转发到的地址
          order: 1 #路由的优先级,数字越小优先级越高
          predicates:  #断言(条件判断,返回值是boolean  转发请求要满足的条件)
            - Path=/product-serv/** #当请求路径满足Path指定的规则时,此路由信息才会正常转发
          filters: #过滤器(在请求传递过程中,对请求进行操作)
            - StripPrefix=1 #在请求转发之前去掉一层前缀路径  /product-serv/** --》**
          #metadata: #元数据

到此即可完成基本的gateway使用。

从Nacos中获取服务信息

上述配置中,配置文件以硬编码的方式将目标uri写死固定,非常不方便。

所以要从Nacos中获取服务信息。

步骤:

引入nacos依赖:

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        </dependency>

更新application.yml配置文件代码:

server:
  port: 7000
spring:
  application:
    name: api-gateway
  cloud:
    #网关配置
    gateway:
      routes: #路由数组,可配置多个 【路由就是指当请求满足什么样的条件的时候转发到哪个服务】
        - id: product_route #当前路由的标识,唯一
#          uri: http://127.0.0.1:8081 #请求最终要被转发到的地址
          uri: lb://shop-product # lb 指的是负载均衡,后面跟的是具体微服务在nacos中的服务名
          order: 1 #路由的优先级,数字越小优先级越高
          predicates:  #断言(条件判断,返回值是boolean  转发请求要满足的条件)
            - Path=/product-serv/** #当请求路径满足Path指定的规则时,此路由信息才会正常转发
          filters: #过滤器(在请求传递过程中,对请求进行操作)
            - StripPrefix=1 #在请求转发之前去掉一层前缀路径  /product-serv/** --》**
          #metadata: #元数据
      discovery:
        locator:
          enabled: true  # 让gateway从Nacos中获取服务信息

    nacos:
      discovery:
        server-addr: 127.0.0.1:8848

在配置类上开启服务发现:加上  @EnableDiscoveryClient 注解。

完成。

SpringCloud Gateway执行流程:

predicate断言详解:

内置断言:

自定义路由断言:

结构:

1、新建一个类,命名格式:XXX + RoutePredicateFactory;

2、继承抽象类 AbstractRoutePredicateFactory<XXXRoutePredicateFactory.Config>;

3、无参构造器

    public XXXRoutePredicateFactory() {
        super(XXXRoutePredicateFactory.Config.class);
    }

4、

    public List<String> shortcutFieldOrder() {
        //返回的是参数,例如下面这个返回的是"datetime"
        return Collections.singletonList("datetime");
    }

5、

    public Predicate<ServerWebExchange> apply(XXXRoutePredicateFactory.Config config) {
        return new GatewayPredicate() {
            public boolean test(ServerWebExchange serverWebExchange) {
                //判断逻辑,返回boolean值。
                
            }

        };
    }

    public static class Config {
        
        //config相应实体类

    }

例如:自定义一个限制年龄的断言:

@Component
public class AgeRoutePredicateFactory extends AbstractRoutePredicateFactory<AgeRoutePredicateFactory.Config> {

    //无参构造器
    public AgeRoutePredicateFactory() {
        super(AgeRoutePredicateFactory.Config.class);
    }


    //读取配置文件中的参数值,然后赋值到配置实体类属性上
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("minAge","maxAge");
    }

    //断言逻辑
    public Predicate<ServerWebExchange> apply(Config config) {
        return new Predicate<ServerWebExchange>() {
            @Override
            public boolean test(ServerWebExchange serverWebExchange) {
                //获取参数
                String age = serverWebExchange.getRequest().getQueryParams().getFirst("age");
                if (StringUtils.isNotEmpty(age)){
                    int i = Integer.parseInt(age);
                    if (i<config.getMaxAge() && i>config.getMinAge()){
                        return true;
                    }
                }
                return false;
            }
        };
    }

    //配置类,用于接受配置文件中的对应参数
    @Data
    public static class Config{
        private Integer minAge;
        private Integer maxAge;

//        public Integer getMinAge() {
//            return minAge;
//        }
//
//        public void setMinAge(Integer minAge) {
//            this.minAge = minAge;
//        }
//
//        public Integer getMaxAge() {
//            return maxAge;
//        }
//
//        public void setMaxAge(Integer maxAge) {
//            this.maxAge = maxAge;
//        }
    }
}

在配置文件中使用即可:

结果:

 

 

 

SpringCloud Gateway 过滤器:

1、作用:

对请求根据某些条件进行过滤。

2、生命周期:

Pre、Post

 

3、分类:

GatewayFilter局部过滤器:作用在特定的路由上;

GlobalFilter全局过滤器:作用在全部路由上

局部过滤器:

内置的局部过滤器:

有30种. 详情见官网.  Spring Cloud Gateway

自定义局部过滤器:

与自定义断言套路结构差不多:

1. 命名要以 Sign+GatewayFilterFactory为格式.

2. 继承抽象类: AbstractGatewayFilterFactory<XXXGatewayFilterFactory.Config>

3.无参构造器

4.模板:

public class XXXGatewayFilterFactory extends AbstractGatewayFilterFactory<XXXGatewayFilterFactory.Config> {



    //无参构造器
    public XXXGatewayFilterFactory() {
        super(XXXGatewayFilterFactory.Config.class);
    }


    //读取配置文件中参数,赋值到配置类中的相应参数
    public List<String> shortcutFieldOrder() {
        return Arrays.asList("要获取的参数名");//可获取多个
    }


    //逻辑
    public GatewayFilter apply(XXXGatewayFilterFactory.Config config) {
       
    }


    //配置类
    public static class Config {
       
    }
}

全局过滤器:

内置全局过滤器:

 见官网: 地址在上面...

自定义全局过滤器:

官方的一段代码:

public class CustomGlobalFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("custom global filter");
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return -1;
    }
}

由此可以看出,自定义的全局过滤器必须要实现两个接口:GlobalFilter和Ordered.

getOrder()方法用于设置返回过滤器执行的优先级, filter方法用于设置过滤的逻辑.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值