SpringCloud gateway的使用

1 是什么

API网关:在微服务之前增加一个前置节点,这个节点就是网关。网关的角色是作为一个 API 架构,用来保护、增强和控制对于 API 服务的访问。
Spring Cloud Gateway是Spring官方基于Spring 5.0,Spring Boot 2.0和Project Reactor等技术开发的网关,Spring Cloud Gateway旨在为微服务架构提供一种简单而有效的统一的API路由管理方式。

1.1 网关的作用

性能:API高可用,负载均衡,容错机制。
安全:权限身份认证、脱敏,流量清洗,后端签名(保证全链路可信调用),黑名单(非法调用的限制)。
日志:日志记录(spainid,traceid)一旦涉及分布式,全链路跟踪必不可少。
缓存:数据缓存。
监控:记录请求响应数据,api耗时分析,性能监控。
限流:流量控制,错峰流控,可以定义多种限流规则。
灰度:线上灰度部署,可以减小风险。
路由:动态路由规则。

2 怎么用

2.1 怎么用

最重要的几个概念:
Route(路由):它是网关的基础元素,包含ID、目标URI、断言、过滤器组成,当前请求到达网关时,会通过Gateway Handler Mapping,基于断言进行路由匹配,当断言为true时,匹配到路由进行转发。
Predicate(断言) :我们可以使用它来匹配来自HTTP中的任何请求,例如Headers或参数,一旦匹配为true,则表示匹配到合适的路由进行转发。
Filter(过滤器): 可以在请求发出的前后进行一些业务上的处理,比如授权、埋点、限流等。

  1. 创建gateway工程,添加gateway依赖
<dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-gateway</artifactId>
 </dependency>
  1. 配置文件中添加路由规则
server:
  port: 8083
spring:
  application:
    name: spring-cloud-gateway
  cloud:
    gateway:
      routes: #路由
        - predicates:  #断言
           - Path=/gateway/**
          filters:
           - StripPrefix=1  #转发时跳过Path中的前缀gateway
          uri: http://localhost:8082/ #拦截之后转发到哪个地址
  1. 启动项目
    输入http://localhost:8083/gateway/config

如果想配置多个路由:

spring:
  application:
    name: spring-cloud-gateway
  cloud:
    gateway:
      routes:
        - id: config_route
          predicates:
            - Path=/gateway/**
          filters:
            - StripPrefix=1
          uri: http://localhost:8082/
        - id: cookie_route
          predicates: 
            - Cookie=name,xiaohou
          filters:
            - StripPrefix=1
          uri: http://localhost:8082/

3自定义断言

例如判断请求头中是否包含Authorization值为yuanxiaohou的数据,如果包含进行拦截

创建java类 必须以RoutePredicateFactory结尾,如AuthRoutePredicateFactory.java 继承AbstractRoutePredicateFactory
重写构造器,apply方法

@Component
public class AuthRoutePredicateFactory extends AbstractRoutePredicateFactory<AuthRoutePredicateFactory.Config>{
    private  static final String NAME_KEY="name";
    private  static final String VALUE_KEY="value";
    public AuthRoutePredicateFactory() {
        super(Config.class);
    }

    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList(NAME_KEY,VALUE_KEY);
    }

    @Override
    public Predicate<ServerWebExchange> apply(Config config) {
        return serverWebExchange -> {
            HttpHeaders headers = serverWebExchange.getRequest().getHeaders();
            List<String> headerList = headers.get(config.getName());
            return headerList.size()>0;
        };
    }

    public static class Config{
        private String name;
        private String value;

        public String getName() {
            return name;
        }

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

        public String getValue() {
            return value;
        }

        public void setValue(String value) {
            this.value = value;
        }
    }
}

application.yml中设置Auth ,注意Auth是自定义断言AuthRoutePredicateFactory类名的前缀部分,必须保持一致
在这里插入图片描述
使用postman工具请求头中携带Authorization=yuanxiaohou
在这里插入图片描述
返回报文中路由到百度首页,说明自定义断言生效。

4 自定义filter

和自定义断言类似,创建java类,类名以GatewayFilterFactory结尾,继承AbstractGatewayFilterFactory类,重写构造器,apply方法。

@Component
public class DefineGatewayFilterFactory extends AbstractGatewayFilterFactory<DefineGatewayFilterFactory.Config> {
    private static final String NAME_KEY="name";

    Logger logger= LoggerFactory.getLogger(DefineGatewayFilterFactory.class);

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

    @Override
    public List<String> shortcutFieldOrder() {
        return Arrays.asList(NAME_KEY);
    }
    @Override
    public GatewayFilter apply(Config config) {
        return ((exchange,chain)->{
            logger.info("[pre] Filter Request, name:"+config.getName());
            //TODO 请求前做的操作
            return chain.filter(exchange).then(Mono.fromRunnable(()->{
                //TODO 返回前做的操作
                logger.info("[post]: Response Filter");
            }));
        });
    }

    public static class Config{
        private String name;

        public String getName() {
            return name;
        }

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

在application.yml中增加拦截器,其中Define是类名的前缀,根据自己的类名来写。
在这里插入图片描述
在浏览器中输入http://localhost:8083/config 进行验证

5 通过Eureka进行转发

  1. gateway工程添加eureka-client依赖
<dependency>
     <groupId>org.springframework.cloud</groupId>
     <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
 </dependency>
  1. 添加Eureka服务注册中心
server:
  port: 8083
spring:
  application:
    name: spring-cloud-gateway
  cloud:
    gateway:
      routes: 
        - id: lb_routes
          predicates:
            - Path=/lb/**
          filters:
            - StripPrefix=1
          uri: lb://spring-cloud-order-service/ #填写在Eureaka上的服务名
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true
eureka:
  client:
    service-url:
      defaultZone: http://localhost:9090/eureka

官网上关于filter还有很多例子,例如限流RequestRateLimiter,具体请参考
gateway官网学习地址

5 动态路由

有些项目路由规则需要动态增加或删除,这事需要增加acuator依赖

  1. gateway工程添加actuator依赖包
<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
  1. application.yml中打开端点
management:
  endpoints:
    web:
      exposure:
        include: "*"
  1. 输入地址:http://localhost:8083/actuator/gateway/routes,(IP和端口根据自己的实际项目来写,后面路径是固定的)可查看配置的路由规则
    在这里插入图片描述

  2. 使用postman工具动态添加或删除路由
    http://localhost:8083/actuator/gateway/routes/baidu_route
    4.1 增加路由,选择post请求,创建请求报文,如请求http://localhost:8083/first时跳转到百度首页。
    在这里插入图片描述
    请求报文如下:

{
  "id": "baidu_route",
  "predicates": [{
    "name": "Path",
    "args": {"_genkey_0":"/first"}
  }],
  "filters": [{
  	"args":{
  		"_genkey_0":1
  	},
  	"name":"StripPrefix"
  	}],
  "uri": "https://www.baidu.com",
  "order": 0
}

同样post请求发送刷新报文 http://localhost:8083/actuator/gateway/refresh
再次在浏览器输入地址 http://localhost:8083/actuator/gateway/routes可看到新增加的路由:
在这里插入图片描述

发送配置的地址:http://localhost:8083/first。跳转到百度首页说明增加路由成功:
在这里插入图片描述
4.2 删除路由:发送DELETE请求 http://localhost:8083/actuator/gateway/routes/baidu_route
在这里插入图片描述
注意:此种方法添加的路由只是存到了内存中,如果重启项目,新添加的路由不存在,如果需要持久化可以存到数据库中,这种方法先不介绍了,下次再研究。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值