gateway笔记TODO

Gateway

有一部分没搞明白,路过的朋友有不错的学习资料,麻烦发一下留给我学习学习

扩展

Reactor

Reactive-Programming响应式编程、反应式编程。ES6通过Promise引入类似的异步编程方式。

spring5 加入了响应式编程实现了Reactive、programming

WebFlux

Spring WebFlux 是 spring5.0引入的响应式框架,区别于Spring MVC(同步阻赛I/O),它不需要依赖Servlet API ,采用异步非阻赛结构,底层基于Reactor来实现响应式流规范。

后续在 Servlet 3.1 支持了异步非阻塞。

Spring WebFlux 不是 Spring MVC 的替代方案Spring WebFlux可以运行在 Servlet 3.1 上,主要还是应用异步非阻塞的业务。(网关 就很好的实现)

在这里插入图片描述

  • Spring WebFlux 默认情况下使用 Netty 作为服务器
  • Spring WebFlux 暂时不支持 MySQL,支持 Redis、MongoDB、PostgreSQL
  • Spring WebFlux 使用的响应式流并不是用 JDK 9 提供的,而是基于 Reactor 响应式流库
  • Spring WebFlux 也可以使用 Spring MVC 注解,如 @Controller,方便在两个 Web 框架中自由转换
  • Spring WebFlux 与 Spring MVC 都可以使用 Tomcat、Jetty、Undertow 等 Servlet 容器(Servlet 3.1+)
  • Spring MVC 因为是使用的同步阻塞式 I/O 模型,更方便开发人员开发和测试代码;一般来说,如果 Spring MVC 能够满足的场景,就尽量不要用 Spring WebFlux

正文

Spring Cloud Gateway 是基于 Spring 5.x 、SpringBoot 2.x 、Spring WebFlux 、Reactor实现 的网关。

Gateway 提供了统一的路由方式,基于Filter链 提供了,熔断、重试、安全、监控/指标、限流等
官网

网关提供API全托管服务,协议匹配、协议转发、安全策略(WAF)、防刷、流量、监控日志等。网关对外暴露URL或接口信息,统称为路由信息。

  • 路由(route): 网关的基础部分,路由信息由一个ID、一个目的URL、一组断言工厂和一组Filter组成;路由断言为真,则URL和配置路由匹配。
  • 断言(predicate): java8中的断言函数,Gateway中的断言函数输入类型是,Spring 5.0 中的 ServerWebExchange断言函数允许开发者去定义匹配来自于Http Request 中的任何信息,比如请求头和参数等。
  • 过滤器(filter): Gateway中的Filter分两种类,Gateway Filter 和 Global Filter ,过滤器会对请求和响应进行修改处理。

在这里插入图片描述

  1. Gateway客户端向 Spring Cloud Gateway 发起请求
    请求被HttpWebHanderAdapter提取组成网关对上下文,传递给DispatcherHandler
  2. DispatcherHandler (请求分发处理器) 吧请求分发到对应的处理器,例如 RoutePredicateHandlerMapping
  3. RoutePredicateHandlerMapping (路由断言处理映射器) 找到路由后返回对应的 FilteringWebHandler
  4. FilteringWebHandler 负责组装Filter 链表并调用Filter执行一系列的Filter处理,然后把请求转到后端对应的代理服务,服务处理结束后,将Response返回到Gateway客户端
    1. Filter 链虚线,是过滤前,响应返回后
    2. Pre 类的Filter 执行完毕后,才会将请求转发到代理服务器
    3. Post 类的Fiter 等代理服务器吧请求处理完后才会生效

路由断言

断言可以通过 java代码的方式写成 配置类,但是这种方法,可读性,维护性比较差。
这里只记录 配置文件的实现

spring:
  cloud:
    gateway:
      routes:
        - id: baidu_route  #唯一ID
          uri: lb:http://www.baidu.com #lb 开启负载均衡,动态寻址
          predicates:     # 断言匹配 可以有多个 符合条件放行 
            - Path=/baidu/test/**   # Path 是断言类型

After 请求在UTC 时间之后

After 路由断言 会提取一个 UTC 时间格式参数,当请求进来的时间在 配置时间之后,匹配成功

//生成时间 例如 前一个小时
ZonedDateTime.now().minusHours(1).format(DateTimeFormatter.ISO_ ZONED_DATE_TIME);
spring:
  cloud:
    gateway:
      routes:
        - id: after_route  #断言工厂
          uri: http://baidu.com  #匹配成功 访问百度
          predicates:
            - After=2022-05-17T21:55:18.146+08:00[Asia/Shanghai]

Before 请求在UTC 时间之前

Before 路由断言工厂 提取一个 UTC 时间格式参数,请求访问时间在配置UTC时间之后,匹配成功

spring:
  cloud:
    gateway:
      routes:
        - id: before_route  #断言工厂
          uri: http://baidu.com  #匹配成功 访问百度
          predicates:
            - After=2022-05-17T21:55:18.146+08:00[Asia/Shanghai]

Between 请求在 UTC 时间之间

spring:
  cloud:
    gateway:
      routes:
        - id: between_route  #断言工厂
          uri: http://baidu.com  #匹配成功 访问百度
          predicates:
            - After=2022-05-17T21:55:18.146+08:00[Asia/Shanghai],
After=2022-05-18T21:55:18.146+08:00[Asia/Shanghai] # 17日 - 18日

Cookie

根据cookie 的key value 来匹配

例如 Cookie key = lf value = weixiao

spring:
  cloud:
    gateway:
      routes:
        - id: cookie_route  #断言工厂
          uri: http://baidu.com  #匹配成功 访问百度
          predicates:
            - Cookie=lf, weixiao

Header 请求头断言

路由工厂根据配置路由 header 信息进行断言匹配路由,匹配成功转发。

请求头中添加 X-Request-Id=Peter

spring:
  cloud:
    gateway:
      routes:
        - id: header_route  #断言工厂
          uri: http://baidu.com  #匹配成功 访问百度
          predicates:
            - Header=X-Request-Id, Peter

Host

访问 例如: www.lf.com

spring:
  cloud:
    gateway:
      routes:
        - id: host_route  #断言工厂
          uri: http://baidu.com  #匹配成功 访问百度
          predicates:
          	- Host = **.lf.com

Method 请求方式

根据请求方式 get、post、update等

spring:
  cloud:
    gateway:
      routes:
        - id: method_route  #断言工厂
          uri: http://baidu.com  #匹配成功 访问百度
          predicates:
          	- Method=GET

Query 请求中参数

例如 :localhsot ?lf=weixiao

spring:
  cloud:
    gateway:
      routes:
        - id: query_route  #断言工厂
          uri: http://baidu.com  #匹配成功 访问百度
          predicates:
          	- Query=lf,weixiao

Path 请求路径

/lf/weixiao/** 多级匹配

/lf/weixiao/ 需要以/结尾 lf/weixiao 会匹配失败

spring:
  cloud:
    gateway:
      routes:
        - id: path_route  #断言工厂
          uri: http://baidu.com  #匹配成功 访问百度
          predicates:
          	- Path=/lf/weixiao/**

Weight 权重

添加了两个/test路由配置,把两个路由分配到同一个路由分组 分组名 group其中60%的流量分给V1

spring:
  cloud:
    gateway:
      routes:
        - id: provider_service-v1  #断言工厂 
          uri: http://baidu.com  #匹配成功 访问百度
          predicates:
          	- Path=/test				#路径
          	- Weight=group, 60	# 权重
        - id: provider_service-v2 
        	uri: http://cn.bing.com/
        	predicated:
        		- Path/test
        		-	Weight=group, 40

RemoteAddr ip网段

通过 Ipv4或Ipv6 来匹配,192.168.0.1/16网段 , 192.168.0.1ip地址,16是子网掩码,也可以直接配置一个ip

spring:
  cloud:
    gateway:
      routes:
        - id: remoteaddr_route  #断言工厂 
          uri: http://baidu.com  #匹配成功 访问百度
          predicates:
          	- RemoteAddr=127.0.0.1

内置Filter

Spring Cloud Gateway 中内置很多路由过滤工厂,也可以自定义过滤工厂。路由过滤工厂允许以某种方式来修改HTTP请求,或HTTP响应。主要有七类过滤器Header、Parameter、Path、Status、Redirect跳转、Hytrix熔断、RateLimiter限流

AddRequestHeader 匹配的请求添加 Header

@Configuration
public class CommonConfiguration {

    @Bean
    public RouteLocator routeLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route("add_request_header_route", r ->
                        r.path("/addRequestHeader")
                                .filters(f -> f.addRequestHeader("X-Request-Id", "Peter"))
                                .uri("http://127.0.0.1:8080/addRequestHeader/")
                ).build();
    }
}

AddRequestParameter 匹配请求添加请求参数

@Configuration
public class CommonConfiguration {

    @Bean
    public RouteLocator routeLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route("add_request_parameter_route", r ->
                        r.path("/addRequestParameter")
                                .filters(f -> f.addRequestParameter("book", "java"))
                                .uri("http://127.0.0.1:8080/addRequestParameter/")
                ).build();
    }
}

RewritePath 改写请求路径

请求结尾不能是 /

访问 http://127.0.0.1:9092/foo/cache/sethelp/help.html,路由会转发到 http://www.baidu.com/cache/sethelp/help.html,这里相当于把 foo 前缀去掉。

@Configuration
public class CommonConfiguration {

    @Bean
    public RouteLocator routeLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route("rewrite_path_route", r ->
                        r.path("/foo/**")
                                .filters(f -> f.rewritePath("/foo/(?<segment>.*)", "/$\\{segment}"))
                                .uri("http://www.baidu.com")
                ).build();
    }
}

AddResponseHeader 网关返回的响应添加 Header

@Configuration
public class CommonConfiguration {

    @Bean
    public RouteLocator routeLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route("add_response_header_route", r ->
                        r.path("/addResponseHeader")
                                .filters(f -> f.addResponseHeader("X-Request-Id", "Peter"))
                                .uri("http://www.baidu.com/")
                ).build();
    }
}

StripPrefix 前缀

StripPrefixGatewayFilterFactory URL前缀去除

PrefixPathGatewayFilterFactoryURL前缀增加

例如: http://localhost:8080/baidu/test 去除前缀后 访问 https://www.baidu.com 去除 了前缀 /baidu/test

spring:
  cloud:
    gateway:
      routes:
        - id: baidu_route
          uri: http://www.baidu.com
          predicates:
            - Path=/baidu/test/**
          filters:
            - StripPrefix=2

Retry 重试

接口需要做幂等(同一个请求多次访问)处理。

config.setRetries(2).setStatus(INTERNAL_SERVER_ERROR) 重试2次,调用失败,返回状态码500

@Configuration
public class CommonConfiguration {

    @Bean
    public RouteLocator routeLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route("retry_route", r -> r.path("/test/retry")
                        .filters(f -> f.retry(config -> config.setRetries(2)
                                .setStatuses(HttpStatus.INTERNAL_SERVER_ERROR)))
                        .uri("http://127.0.0.1:8080/retry?key=abc&count=2"))
                .build();
    }
}

Hystrix 熔断

TODO

Global Filters

官网

GateWay Filter Factories 是内部定义好的过滤器,一般用的不多

Global Filters 自定义过滤规则,全局规则(生效 所有接口,路由),需要实现GlobalFilter接口、Ordered接口(顺序)

底部

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值