ICode9

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

【博学谷学习记录】超强总结,用心分享|狂野架构师SpringCloud-Gateway

2022-09-05 16:00:30  阅读:330  来源: 互联网

标签:lb SpringCloud driver uri hailtaxi 过滤器 架构师 Gateway 路由


目录

微服务网关就是一个系统,通过暴露该微服务网关系统,方便我们进行相关的鉴权,安全控制,日志统一处理,易于监控,限流等相关功能

SpringCloud Gateway的工作流程

1:Gateway的客户端回向Spring Cloud Gateway发起请求,请求首先会被HttpWebHandlerAdapter进行提取组装成网关的上下文,然后网关的上下文会传递到DispatcherHandler。

2:DispatcherHandler是所有请求的分发处理器,DispatcherHandler主要负责分发请求对应的处理器,比如将请求分发到对应RoutePredicateHandlerMapping(路由断言处理器映射器)。

3:路由断言处理映射器主要用于路由的查找,以及找到路由后返回对应的FilteringWebHandler。

4:FilteringWebHandler主要负责组装Filter链表并调用Filter执行一系列Filter处理,然后把请求转到后端对应的代理服务处理,处理完毕后,将Response返回到Gateway客户端。
在Filter链中,通过虚线分割Filter的原因是,过滤器可以在转发请求之前处理或者接收到被代理服务的返回结果之后处理。所有的Pre类型的Filter执行完毕之后,才会转发请求到被代理的服务处理。被代理的服务把所有请求完毕之后,才会执行Post类型的过滤器。

网关重要概念:路由、断言、过滤器

Gateway路由配置分为基于配置的静态路由设置和基于代码动态路由配置。

静态路由是指在application.yml中把路由信息配置好了,而动态路由则支持在代码中动态加载路由信息,更加灵活,我们接下来把这2种路由操作都实现一次。

Gateway动态路由配置中基于Path的路由方式

使用代码进行配置

/***
 * 路由配置
 * @param builder
 * @return
 */
@Bean
public RouteLocator routeLocator(RouteLocatorBuilder builder) {

    return builder.routes()
        .route("hailtaxi-driver", r -> r.path("/driver/**").uri("lb://hailtaxi-driver"))
        .route("hailtaxi-order", r -> r.path("/order/**").uri("lb://hailtaxi-order"))
        .route("hailtaxi-pay", r -> r.path("/pay/**").uri("lb://hailtaxi-pay"))
        .build();
}

使用配置文件进行配置

spring: 
    cloud: 
        gateway:
          #路由配置
          routes:
            #唯一标识符
            - id: hailtaxi-driver
              uri: lb://hailtaxi-driver
              #路由断言
              predicates:
                - Path=/driver/**
            #唯一标识符
            - id: hailtaxi-order
              uri: lb://hailtaxi-order
              #路由断言
              predicates:
                - Path=/order/**
            #唯一标识符
            - id: hailtaxi-pay
              uri: lb://hailtaxi-pay
              #路由断言
              predicates:
                - Path=/pay/**

配置参数说明:

routes:路由配置
- id:唯一标识符
uri:路由地址,可以是 lb://IP:端口     也可以是   lb://${spring.application.name}
predicates:断言,是指路由条件
- Path=/driver/**:路由条件。
Predicate 接受一个输入参数,返回一个布尔值结果。这里表示匹配所有以driver开始的请求。
filters:过滤器
- StripPrefix=1:真实路由的时候,去掉第1个路径,路径个数以/分割区分

这里表示请求携带了cookie为username的数据,并且值为itheima,就允许通过。

gateway:
      routes:
      - id: hailtaxi-driver
        uri: lb://hailtaxi-driver
        predicates:
        - Path=/driver/**
        - Cookie=username,itheima

下面的匹配规则,就是请求头要有token属性,并且值必须为数字和字母组合的正则表达式,例如携带token=19and30就可以通过访问。

gateway:
      routes:
      - id: hailtaxi-driver
        uri: lb://hailtaxi-driver
        predicates:
        - Path=/driver/**
        - Method=GET,POST

实现全局过滤器和局部过滤器的创建和使用

过滤器

分类

默认过滤器:出厂自带,实现好了拿来就用,不需要实现
  全局默认过滤器
  局部默认过滤器
  
自定义过滤器:根据需求自己实现,实现后需配置,然后才能用哦。
  全局过滤器:作用在所有路由上。
  局部过滤器:配置在具体路由下,只作用在当前路由上。

常见默认过滤器

过滤器名称 说明 对应的类 父类
AddRequestHeader 对匹配上的请求加上Header AddRequestHeaderGatewayFilterFactory AbstractNameValueGatewayFilterFactory
AddRequestParameters 对匹配上的请求路由 AddRequestHeaderGatewayFilterFactory AbstractNameValueGatewayFilterFactory
AddResponseHeader 对从网关返回的响应添加Header AddResponseHeaderGatewayFilterFactory AbstractNameValueGatewayFilterFactory
StripPrefix 对匹配上的请求路径去除前缀 StripPrefixGatewayFilterFactory AbstractGatewayFilterFactory

添加响应头

响应数据添加了X-Response-Default-MyName: itheima

spring:
  cloud:
    gateway:
     # 配置全局默认过滤器 作用在所有路由上,也可单独为某个路由配置
      default-filters:
      # 往响应过滤器中加入信息
        - AddResponseHeader=X-Response-Default-MyName,itheima

前缀处理

- StripPrefix=1表示真实请求地址是当前用户请求以/api开始的uri中去除第1个路径/api.

gateway:
      routes:
      - id: hailtaxi-driver
        uri: lb://hailtaxi-driver
        predicates:
        - Path=/api/driver/**
        filters:
          - StripPrefix=1
配置 路由地址 访问地址
StripPrefix=1 http://localhost:8001/api/driver/info/2 http://localhost:18081/driver/info/2
StripPrefix=2 http://localhost:8001/api/suri/driver/info/2 http://localhost:18081/driver/info/2

增加前缀

使用PrefixPath过滤器增加前缀

gateway:
      routes:
      - id: hailtaxi-driver
        uri: lb://hailtaxi-driver
        predicates:
        - Path=/**
        filters:
          - PrefixPath=/driver
配置 路由地址 访问地址
- PrefixPath=/driver http://localhost:8001/info/2 http://localhost:18081/driver/info/2

自定义过滤器

1、实现GatewayFilter接口

GatewayFilter 一般作用在某一个路由上,需要实例化创建才能使用,局部过滤器需要实现接口GatewayFilter、Ordered

public class PayFilter implements GatewayFilter,Ordered {

    /***
     * 过滤器执行拦截
     * @param exchange
     * @param chain
     * @return
     */
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        System.out.println("GatewayFilter拦截器执行---pre-----PayFilter");
        return chain.filter(exchange).then(Mono.fromRunnable(()->{
            System.out.println("GatewayFilter拦截器执行---post-----PayFilter");
        }));
    }

    @Override
    public int getOrder() {
        return 0;
    }
}

使用局部过滤器:(使用下面RouteLocator的时候,配置文件中的路由记得注释或删除)

/***
 * 路由配置
 * @param builder
 * @return
 */
 @Bean
    public RouteLocator routeLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route("hailtaxi-driver", r -> r.path("/api/driver/**")
                        .and().cookie("username","itheima")
                        .and().header("token","123456")
                                .filters(f->f.filter(new PayFilter()).addResponseHeader("X-Response-Default-MyName", "itheima")
                                        .addRequestHeader("myheader", "1234567")
                                .stripPrefix(1)
                                )
                       // .and().method(HttpMethod.POST)
                        .uri("lb://hailtaxi-driver")
                        //.filter(new PayFilter())
                 )
                .route("hailtaxi-order", r -> r.path("/order/**").uri("lb://hailtaxi-order"))
                .route("hailtaxi-pay", r -> r.path("/pay/**").uri("lb://hailtaxi-pay"))
                .build();
    }

2、继承GatewayFilterFactory

@Slf4j
@Component //一定要将其交给spring容器管理
public class PayMethodGatewayFilterFactory extends AbstractGatewayFilterFactory<PayMethodGatewayFilterFactory.Config> {

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

    @Override
    public GatewayFilter apply(Config config) {
        return (exchange, chain) -> {
            String paymethod = config.getPayMethod();
            String msg = config.getMsg();
            log.info("PayMethodGatewayFilterFactory 加载到的配置信息为:{}---{}",paymethod,msg);
            //将paymethod添加到请求头中
            exchange.getRequest().mutate().header("paymethod",paymethod);
            return chain.filter(exchange);
        };
    }

    @Override
    public List<String> shortcutFieldOrder() {
        return  Arrays.asList("payMethod","msg");//指定从yml中提前出来的配置信息填充到配置类中哪个属性,按规则配置
    }

    @Override
    public ShortcutType shortcutType() {
        return ShortcutType.DEFAULT;//默认规则
    }

    /**
     * 加载从yml中提取出来的配置信息
     */
    @Data
    public static class Config {
        private String payMethod;
        private String msg;
    }
}

配置文件

    gateway:
      #路由配置
      routes:
        #唯一标识符
        - id: hailtaxi-driver
          uri: lb://hailtaxi-driver
          #路由断言
          predicates:
            - Path=/driver/**
            - Cookie=username,itheima
            - Header=token,^(?!\d+$)[\da-zA-Z]+$
            - Method=GET,POST
            - Token=Authorization
          filters:
            - PayMethod=alipay,业务整合

跨域配置

gateway:
      globalcors:
        corsConfigurations:
          '[/**]':
            allowedOrigins: "*"
            allowedMethods:
              - GET
              - POST
              - PUT

创建CorsWebFilter过滤器,代码

/**
 * 配置跨域
 * @return
 */
@Bean
public CorsWebFilter corsFilter() {
    CorsConfiguration config = new CorsConfiguration();
    //允许哪种方法类型跨域 get post delete put
    config.addAllowedMethod("*");
    // 允许哪些请求源跨域
    config.addAllowedOrigin("*");
    //允许哪种请求头跨域
    config.addAllowedHeader("*");
    // 配置前端js允许访问的自定义响应头
    config.addExposedHeader("Authorization");
    // 是否携带cookie跨域
    config.setAllowCredentials(true);

    UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
    //允许跨域的路径
    source.registerCorsConfiguration("/**", config);
    return new CorsWebFilter(source);
}

漏桶算法

1、所有的请求在处理之前都需要拿到一个可用的令牌才会被处理;
2、根据限流大小,设置按照一定的速率往桶里添加令牌;
3、桶设置最大的放置令牌限制,当桶满时、新添加的令牌就被丢弃或者拒绝;
4、请求达到后首先要获取令牌桶中的令牌,拿着令牌才可以进行其他的业务逻辑,处理完业务逻辑之后,将令牌直接删除;
5、令牌桶有最低限额,当桶中的令牌达到最低限额的时候,请求处理完之后将不会删除令牌,以此保证足够的限流

标签:lb,SpringCloud,driver,uri,hailtaxi,过滤器,架构师,Gateway,路由
来源: https://www.cnblogs.com/xieshier/p/16652670.html

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

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

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

ICode9版权所有