gateway 不拦截指定路径_Gateway新一代网关

  • Post author:
  • Post category:其他





Gateway新一代网关






zuul路由网关



zuul核心人员走了两个,zuul2的研发过久,spring公司等不及,自己研发的Gateway网关。





简介



Cloud全家桶有个狠重要的组件就是网关,在1.x版本中都是采用Zuul网关;但是在2.x版本中,zuul的升级一致跳票,SpringCloud最后自己研发了一个网关替代Zuul, 那就是SpringCloud Gateway

bd7320526d0031eee35cbc093de22684.png
sada
  • Gateway是在Spring生态之上构建的API网关服务,基于Spring 5,Spring Boot 2和Project Reactor 等技术。

  • Gateway旨在提供一种简单而有效 等方式来对API 进行路由,以及提供一些强大对过滤器,例如:熔断、限流、重试等

  • Gateway 作为SpringCloud 等目标提供统一等路由方式且基于Filter 链的方式提供了网关基本的功能,例如:安全,监控。限流

  • SpringCloud Gateway 使用的Webflux中的 reactor-netty 响应式的编程,底层使用了Netty通讯框架

  • 2436c3a5d0f7db6fa498fcfa6f308caa.png
    在这里插入图片描述

6c2b34386b3e6a3c52bd487de5b83f71.png
![在这里插入图片描述](https://img-blog.csdnimg.cn/
854ad2bedaf4a88e94f3b8abe3bee720.png

因为Zuul1.0 进入了维护阶段,而且Gateway 是SpringCloud 团队开发,比Zuul更加的便捷

Gateway 是基于异步非阻塞模型上进行开发的,性能方面不需要担心

d1ff4469d1ac68b398f7d7f4031879de.png
在这里插入图片描述




SpringCloud Gateway 与 Zuul 的区别



d9108c301874a4219913d66864f52698.png
在这里插入图片描述




三大核心概念






Route (路由)



  • 路由是构建网关的基本模块,它由ID,目标URL,一系列的断言和过滤器组成,如果断言为true则匹配该路由



Predicate (断言)



  • 参考的是Java8的java.util.function.predicate
  • 开发人员可以匹配HTTP请求中的所有内容(例如请求头或请求参数),如果请求与断言相匹配则进行路由



Filter (过滤)



  • 指的是Spring框架中的GatewayFilter 的实例,使用过滤器,可以在请求被路由前或者之后请求进行修改。



总体



69cef00bfd1daa9f1dbbd05cc80124d3.png
在这里插入图片描述
  • web请求,通过一些匹配条件,定位到真正的服务节点。并在这个妆发过程的前后,进行一些精细化控制。
  • predicate就是我们匹配条件;而filter ,就可以理解为一个无所不能的拦截器,有了这两个元素,在加上目标uri,就可以实现一个具体的路由了




Gateway工作流程



(官网总结)

5ba17dbbe706047814f3d23ae589f78b.png
21833b42047f40042026c72c671cde54.png
87068deadd9b389e8e9f4181d1290545.png




Demo



  1. 新建模块cloud-gateway-gateway9527
  2. 引入pom
                org.springframework.cloud        spring-cloud-starter-gateway                    com.angenin.springcloud        cloud-api-commons        ${project.version}                    org.springframework.cloud        spring-cloud-starter-netflix-eureka-client                    org.springframework.boot        spring-boot-devtools        runtime        true                org.projectlombok        lombok        true                org.springframework.boot        spring-boot-starter-test        test    
  1. yml文件
server:  port: 9527spring:  application:    name: cloud-gateway  cloud:    gateway:      routes:        - id: payment_route # 路由的id,没有规定规则但要求唯一,建议配合服务名          uri: http://localhost:8001          predicates:            - Path=/payment/get/** # 断言,路径相匹配的进行路由        - id: payment_route2          uri: http://localhost:8001          predicates:             Path=/payment/lb/** #断言,路径相匹配的进行路由eureka:  instance:    hostname: cloud-gateway-service  client:    fetch-registry: true    register-with-eureka: true    service-url:      defaultZone: http://eureka7001.com:7001/eureka/
  1. 主启动类
@SpringBootApplication@EnableEurekaClientpublic class GatewayMain9527 {    public static void main(String[] args) {        SpringApplication.run(GatewayMain9527.class, args);    }}
  1. 启动微服务 Eureka server 7001   client  8001 + Gateway 9527

1368c473cb2f275116a134729a480284.png
fca405a70dafb5f802585382f609613b.png
通过我们 9527 网关访问 8001的接口

25601f46f85c855d90bab7b910ed6db5.png
这里起到了作用




Gateway网关路由的两种配置方式



  1. 在配置文件中配置 在配置文件yml中配置

  2. 在配置类中配置 代码中注入RouteLocator的Bean

8df8bb08dffe25312fadfb1a3eda640f.png



案例(访问百度)



新建config.GatewayConfig

package com.yxl.cloud.config;import org.springframework.cloud.gateway.route.RouteLocator;import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;@Configurationpublic class GatewayConfig {    @Bean    public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder){        RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();        routes.route("path_route_angenin",  //id                r -> r.path("/guonei")  //访问 http://localhost:9527/guonei                        .uri("http://news.baidu.com/guonei"));  //就会转发到 http://news.baidu.com/guonei        routes.route("path_route_angenin2",  //id                r -> r.path("/guoji")  //访问 http://localhost:9527/guoji                        .uri("http://news.baidu.com/guoji"));  //就会转发到 http://news.baidu.com/guonji        return routes.build();    }}

访问:http://localhost:9527/guonei
2bc74d5da7cd2ef01dedcfc5ea766797.png




通过微服务名实现动态路由



server:  port: 9527spring:  application:    name: cloud-gateway  cloud:    gateway:      discovery:        locator:          enabled: true  #开启从注册中心动态创建路由的功能,利用微服务名称进行路由(默认false)      routes:        - id: payment_route #路由的id,没有规定规则但要求唯一,建议配合服务名          #          uri: http://localhost:8001  #匹配后提供服务的路由地址          uri: lb://cloud-provider-hystrix-payment          predicates:            - Path=/payment/get/** #断言,路径相匹配的进行路由        - id: payment_route2          #          uri: http://localhost:8001          uri: lb://cloud-provider-hystrix-payment          predicates:            - Path=/payment/lb/** #断言,路径相匹配的进行路由eureka:  instance:    hostname: cloud-gateway-service  client:    fetch-registry: true    register-with-eureka: true    service-url:      defaultZone: http://eureka7001.com:7001/eureka/

5623ae6b379363dfba44af8d4517329c.png
a2e05b7eaf3810280405beddab4b7cde.png




Predicate的使用



f760acdc87bb4f8f78fdfd31a54f7ef6.png
官网:https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/#gateway-request-predicates-factories

3c48e9662b50e7f96d3462e7d3ee199e.png
SpringCloud Gateway 将路由匹配作为Spring WebFlux HandlerMapping 基础架构的一部分。

SpringCloud Gateway 包括许多内置的Route Predicate工厂。所有这些Predicate 都与HTTP请求的不同属性匹配。多个Route Predicate工厂可以进行组合

SpringCloud Gateway 创建Route 对象时,使用RoutePredicateFactory 创建 Predicate,Predicate 对象可以赋值给Route。Springcloud Gateway 包含许多内置的 Route Predicate Factories.

所有这些动词 都匹配HTTP请求的不同属性,多种谓词工厂可以组合,通过逻辑and

5107807836bbff1e090a52eb67cd4133.png
在这里插入图片描述



简单使用



public class T2 {    public static void main(String[] args) {    	//获取当前时间串        ZonedDateTime now = ZonedDateTime.now();        System.out.println(now);        //2020-06-17T11:53:40.325+08:00[Asia/Shanghai]    }}

0c134bbfae6faa141704a5bceeb43329.png
231467e7a1443983d4ceb1d2354dc971.png

	#指定时间前才能访问(Before)   - Before=2020-06-17T11:53:40.325+08:00[Asia/Shanghai]    #指定时间内才能访问(Between)   - Between=2020-06-17T11:53:40.325+08:00[Asia/Shanghai],2020-06-17T12:53:40.325+08:00[Asia/Shanghai]



Cookie



c2c23bd3bed8718de0a2fc2de14ce105.png
在这里插入图片描述

yml 设置 cookie

         - Cookie=username,angenin   #带Cookie,并且username的值为angenin

不带cookie 直接访问失败
a59407ffffb547ec9613461568bc0ace.png




Header



5854fac2e72ac8d3d4ee91b695806920.png
在这里插入图片描述
#            - After=2020-06-17T12:53:40.325+08:00[Asia/Shanghai]#            - Cookie=username,angenin   #带Cookie,username的值为angenin            - Header=X-Request-Id, \d+   #请求头要有 X-Request-Id属性并且值为整数的正则表达式




Method



9a60772841a4c02da5e78ffa42181360.png
在这里插入图片描述
- Method=GET	#只允许get请求访问



总结



e6486944d98fb7477f9402325eaf756d.png
在这里插入图片描述




Filter的使用



f9166cba5fa84cfa5b710396b7ed7e40.png
在这里插入图片描述

路由过滤器可用于修改进入的HTTP请求和返回的HTTP响应,路由过滤器只能指定路由进行使用。

SpringCloud Gateway 内置了多种路由过滤器,他们都由GatewayFilter的工厂类来产生

d30b97029e61c8d53ccf6c1b1fe0a6f7.png
GatewayFilter(31种) Global Filter(10种)

7c86ed4f9a84ce7edb2d7c2c0a9d6cea.png
arameter为代表。
package com.yxl.cloud.config;import lombok.extern.slf4j.Slf4j;import org.springframework.cloud.gateway.filter.GatewayFilterChain;import org.springframework.cloud.gateway.filter.GlobalFilter;import org.springframework.core.Ordered;import org.springframework.http.HttpStatus;import org.springframework.stereotype.Component;import org.springframework.web.server.ServerWebExchange;import reactor.core.publisher.Mono;import java.util.Date;@Component@Slf4jpublic class MyLogGateWayFilter implements GlobalFilter, Ordered {    @Override    public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {        log.info("**************come in MyLogGateWayFilter:" + new Date());        String uname = exchange.getRequest().getQueryParams().getFirst("uname");        if(uname ==null){            log.info("*******用户名为null,非法用户!!");            //设置响应,不被接受            exchange.getResponse().setStatusCode(HttpStatus.NO_CONTENT);            return exchange.getResponse().setComplete();    }        //返回chain.filter(exchange),放行        return chain.filter(exchange);    }    @Override    public int getOrder() {        return 0;    }}

http://localhost:9527/payment/lb?xxx=111
97f9d4164e25a51c771f16187c35abaa.png


  • 个人博客: http://blog.yanxiaolong.cn/



版权声明:本文为weixin_35655990原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。