SpringCloud-Gateway网关

一.网关概念

  1.网关作为系统的唯一流量入口,封装内部系统的架构,所有请求都先经过网关,由网关将请求路由到合适的微服务

01d6fa6b3143481489b113827078c870.png2.各个组件的对比

7264a3622376410f886d8c899de0427a.png

二.网关的搭建

1.引入依赖

<dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>

2.在启动类上加上注解

@EnableDiscoveryClient

3.在配置文件中填写信息

server:
  port: 8888


spring:
  application:
    name: gateway-service
  cloud:
    nacos:
      server-addr: localhost:8848
    gateway:
      routes:
        - id: path
          predicates:
            - Path=/gateway/**
          uri: lb://user-service
        - id: query
          predicates:
            - Query=name,jjh
          uri: lb://user-service
        - id: tobaidu
          uri: http://www.baidu.com
          predicates:
            - Path=/to/**
      default-filters:
        - AddRequestHeader=JJH,is NB!
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true

id:   每个路由的唯一值,不重复即可

predicates:  断言,一共有十一种断言,例如path,montheds,query等,具体可以到官网查询

uri:   要转发的具体地址, lb 代表负载均衡 ,后面跟上服务名称,也可以是具体的ip地址

三.断言

 

1.断言的类型

  Path: 路径断言,

- Path=/gateway/** ,则只要是gateway开头的请求都将被转发,

  Query: 查询参数断言,

-Query=name,jjh ,只要在请求路径上包含参数name=jjh时,进行匹配,

可以支持正则表达式,如jjh.表示最后一个字母是任意的

  Method: 请求方法断言,

-Method=GET ,当请求是GET时,进行匹配

  Header: 请求头断言,

-Header=header-name,jjh, 当携带请求头时,进行匹配

2.自定义断言

自定义断言需要继承AbstractRoutePredicateFactory类,重写apply()方法,通过serverWebExchange.getRequest()获取请求信息

  (1)自定义查询参数断言

public class MyRoutePredicateFactory extends AbstractRoutePredicateFactory<
        MyRoutePredicateFactory.MyConfig> {
    
    public MyRoutePredicateFactory() {
        super(MyConfig.class);
    }
    /**
     * 将配置文件中的值按返回集合的顺序,赋值给配置类
     * @return
     */
    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList(new String[]{"name"});
    }

    @Override
    public Predicate<ServerWebExchange> apply(MyConfig config) {
        
        return (ServerWebExchange exchange) ->{
            System.out.println("自定义路由断言");
            String name = exchange.getRequest().getQueryParams().getFirst("name");
            if(name.equals(config.getName())){
                return true;
            }else {
                return false;
            }
        };
        
    }
    public static class MyConfig{
        private String name;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }
    }
}

 

这里定义了一个静态内部类,用来提供获取配置文件的参数,表示查询参数为name,

主要是重写了shortcutFieldOrder()方法,它将配置文件中的参数赋值给配置类,返回一个String的集合,

然后在断言里配置上该类的前面部分名称My

 - id: nameQuery
          uri: lb://user-service
          predicates:
            - My=JJh

这样在请求时加上?name=JJh,就会转发,否则不转发

(2)自定义年龄范围断言

public class AgeRoutePredicateFactory extends AbstractRoutePredicateFactory<
        AgeRoutePredicateFactory.MyConfig> {


    public AgeRoutePredicateFactory() {
        super(MyConfig.class);
    }

    @Override
    public Predicate<ServerWebExchange> apply(MyConfig config) {

        return (ServerWebExchange exchange) ->{
            String age = exchange.getRequest().getQueryParams().getFirst("age");

            assert age != null;
            if(!age.matches("[0-9]+")){
                return false;
            }
            int Age = Integer.parseInt(age);

            if(Age >= config.getMaxAge() && Age < config.getMinAge()){
                return true;
            }else {
                return false;
            }

        };
    }
    @Override
    public List<String> shortcutFieldOrder() {
        return super.shortcutFieldOrder();
    }

     public static class MyConfig{
        private int minAge;
        private int maxAge;

         public int getMinAge() {
             return minAge;
         }

         public void setMinAge(int minAge) {
             this.minAge = minAge;
         }

         public int getMaxAge() {
             return maxAge;
         }

         public void setMaxAge(int maxAge) {
             this.maxAge = maxAge;
         }
     }
}

在配置文件里写上:

 - id: ageQuery
          predicates:
            - Age=1,9
          uri: lb://user-service

这样就会对年龄的范围做校验,在这个范围内,符合将被转发,否则不会转发

四.过滤器

1.请求头过滤器

  - id: path
          predicates:
            - Path=/gateway/**
          uri: lb://user-service
          default-filters:
        - AddRequestHeader=JJH,is NB!

添加该配置,将对该路径添加头信息

2.移除请求头过滤器

filters:

 - RemoveRequestHeader=X-header-age

会移除该X-header-age请求头

3.状态码设置

filters:

 - SetStatus=401

4.重定向设置

filters:

 - RedirectTo=302,http://www.baidu.com

该请求将重定向到百度去

5.全局过滤器

网关需要做一些全局性的限制,例如限流,IP黑名单等,可以设置一个全局过滤器

@Configuration
public class GlobalCustomFilter {
    
    
    @Bean
    @Order(-1)
    public GlobalFilter zero(){
        return ((exchange, chain) -> {
            return chain.filter(exchange)
                    .then(Mono.fromRunnable(()->{ System.out.println("-1号过滤器");  
                    }));
        });
    }
    @Bean
    @Order(0)
    public GlobalFilter second(){
        return ((exchange, chain) -> {
            return chain.filter(exchange)
                    .then(Mono.fromRunnable(()->{ System.out.println("0号过滤器");
                    }));
        });
    }
    @Bean
    @Order(1)
    public GlobalFilter first(){
        return ((exchange, chain) -> {
            return chain.filter(exchange)
                    .then(Mono.fromRunnable(()->{ System.out.println("1号过滤器");
                    }));
        });
    }
}

这样就可以实现一个全局过滤的效果,order的数字越小,越先执行

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值