ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

springcloud-一篇搞定GateWay

2022-04-07 15:32:03  阅读:205  来源: 互联网

标签:搞定 匹配 springcloud payment gateway cloud SpringCloud GateWay 路由


SpringCloud GateWay简介

SpringCloud Gateway 是 Spring Cloud 的一个全新项目,基于 Spring 5.0+Spring Boot 2.0 和 Project Reactor 等技术开发的网关,它旨在为微服务架构提供一种简单有效的统一的 API 路由管理方式。

SpringCloud Gateway 作为 Spring Cloud 生态系统中的网关,目标是替代 Zuul,在Spring Cloud 2.0以上版本中,没有对新版本的Zuul 2.0以上最新高性能版本进行集成,仍然还是使用的Zuul 1.x非Reactor模式的老版本。而为了提升网关的性能,SpringCloud Gateway是基于WebFlux框架实现的,而WebFlux框架底层则使用了高性能的Reactor模式通信框架Netty。

Spring Cloud Gateway的目标提供统一的路由方式且基于 Filter 链的方式提供了网关基本的功能,例如:安全,监控/指标,和限流。

SpringCloud GateWay基本组件

  1. Route(路由)
  2. Predicate(断言)
  3. Filter(过滤器)

Route(路由)

路由是构建网关的基本模块,它由路由ID,需转发到目标微服务URI,以及一系列的Predicate(断言)和Filter(过滤)组成,如果请求符合Predicate,则匹配该路由,按该路由来处理请求

Predicate(断言)

断言说简单点,就是请求匹配条件。断言是定义匹配条件,如果请求符合条件,则该请求匹配断言所属的路由

Filter(过滤器)

在SpringCloud GateWay这里的Filter的使用场景是:当请求匹配了某个路由后,需要转发到某个微服务之前或之后做一些事情

image

SpringCloud GateWay基本使用

SpringCloud GateWay是以微服务模块作为载体的(也会注册到注册中心上),需要创建一个maven项目作为微服务启动。关于pom.yml、主启动省略,主要说下application.yml的配置,如下:

server:
  port: 9527

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

        - id: payment_routh2 #payment_route    #路由的ID,没有固定规则但要求唯一,建议配合服务名
          uri: http://localhost:8001          #匹配后提供服务的路由地址
          predicates:
            - Path=/payment/lb/**         # 断言,路径相匹配的进行路由

上面gateway的配置大致说明下:有两个路由,分别是payment_routh和payment_routh2;以payment_routh为例,如果请求是匹配predicates的path,则由该路由进行处理并转发到http://localhost:8001

总结

上面的是基本的gateway配置,不过还存在问题:实际项目中某个微服务是作为集群来部署的,因此不能只写死一台服务器的地址,需要负载均衡转发到相同服务但不同实例上。下面则是动态路由的实现方式,能够解决此问题

SpringCloud GateWay之动态路由

动态路由只是uri发生了变化,如下:

server:
  port: 9527

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

        - id: payment_routh2 #payment_route    #路由的ID,没有固定规则但要求唯一,建议配合服务名
          uri: lb://cloud-payment-service          #匹配后提供服务的路由地址
          predicates:
            - Path=/payment/lb/**     # 断言,路径相匹配的进行路由

uri配置为: lb://服务名

SpringCloud GateWay之Predicate(断言)详细配置

上面示例的Predicate,只演示了path,这只是匹配条件之一,还有其他匹配条件,如下:
image
下面就一些例子,如下:

spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      routes:
        - id: payment_routh #payment_route    #路由的ID,没有固定规则但要求唯一,建议配合服务名
          uri: lb://cloud-payment-service          #匹配后提供服务的路由地址
          predicates:
            - Path=/payment/get/**         # 断言,路径相匹配的进行路由
            - After=2020-02-05T15:10:03.685+08:00[Asia/Shanghai]
            - Before=2020-02-05T15:10:03.685+08:00[Asia/Shanghai]
            - Cookie=username,zzyy
            - Host=**.atguigu.com
            - Query=username, \d+  # 要有参数名username并且值还要是整数才能路由
            - Method=GET

上面的例子表示请求必须:请求的时间在before时间之前,after时间之后,携带key为username,value为zzyy的Cookie,客户端域名需要匹配**.atguigu.com,请求参数中得有username,且值为正整数,请求方式为get。满足上述的条件,此断言才为true,才匹配此路由

SpringCloud GateWay之Filter(过滤器))详细使用

在SpringCloud GateWay的Filter分为:GatewayFilter 和 GlobalFilter;

  1. GatewayFilter只针对指定的路由生效。
  2. GlobalFilter对全部路由生效。

GatewayFilter示例

server:
  port: 9588

spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true #开启从注册中心动态创建路由的功能
          lower-case-service-id: true #使用小写服务名,默认是大写
      routes:
        - id: payment_routh #payment_route #路由的ID,没有固定规则但要求唯一,建议配合服务名
          uri: lb://cloud-provider-payment #匹配后的目标服务地址,供服务的路由地址
          #uri: http://localhost:8001 #匹配后提供服务的路由地址
          filters:
            - AddRequestParameter=X-Request-Id,1024 #过滤器工厂会在匹配的请求头加上一对请求头,名称为X-Request-Id值为1024
          predicates:
            - Path=/paymentInfo/**        # 断言,路径相匹配的进行路由
            - Method=GET,POST

当请求匹配了payment_routh路由,就会执行AddRequestParameter这个过滤器进行过滤

GlobalFilter示例

@Component //必须加,必须加,必须加
@Slf4j
public class MyLogGateWayFilter implements GlobalFilter, Ordered
{
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain)
    {
        log.info("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);
    }

    @Override
    //指定过滤器在过滤器的执行顺序,数值越小执行顺序越优先
    public int getOrder()
    {
        return 0;
    }
}

不管请求匹配了哪个路由,都会执行gateway全局的过滤器。

总结

实际开发,GlobalFilter用的比较多,常用的使用场景是:全局日志,跨域处理,统一鉴权...

标签:搞定,匹配,springcloud,payment,gateway,cloud,SpringCloud,GateWay,路由
来源: https://www.cnblogs.com/ibcdwx/p/16112582.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有