SpringCloud-Gateway新一代网关

概述

  • zuul官网:2.0还没出来

  • gateway官网:spring等不及自己研发的

  • gateway是原zuul1.x的替代
    在这里插入图片描述

  • Gateway是Spring生态系统之上构建的API网关服务,基于Spring5,Spring Boot2和Project Reactor等技术

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

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

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

在这里插入图片描述

微服务架构中网关的作用和位置

  • 反向代理
  • 鉴权
  • 流量监控
  • 熔断
  • 日志监控

在这里插入图片描述

Spring Cloud GateWay特性

  • 基于SpringFrame 5,Project Reactor和Spring Boot2.0进行构建
  • 动态路由:能够匹配任何请求属性
  • 可以对路由指定Predicate(断言)和Filter(过滤器)
  • 集成Hystrix的断路器功能
  • 集成Spring Cloud服务发现功能
  • 易于编写的Predicate(断言)和Filter(过滤器)
  • 请求限流功能
  • 支持路径重写

Spring Cloud Gateway 与Zuul的区别
在SpringCloud Finchley正式版之前,Spring Cloud推荐的网关是Netflix提供的Zuul:

  • Zuul1.x是一个基于阻塞I/O的APIGateway
  • Zuul1.x基于Servlet2.5使用阻塞架构,它不支持任何长连接(如websocket)Zuul的涉及模式和Nginx较像,每次I/O操作都是从工作线程中选择一个执行,请求线程被阻塞到工作线程完成,但是差别是Nginx用C++实现,Zuul用Java实现,而JVM本身会又第一次加载较慢的情况,所以Zuul的性能相对较差。
  • Zuul2.x理念更先进,想基于Netty非阻塞和支持长连接,但是Spring Cloud目前还没有整合
  • Spring Cloud Gateway建立在Spring Framework5,Project Reactor和Spring boot2之上,使用非阻塞API。
  • Spring Cloud Gateway支持WebSocket,并且与Spring紧密集成拥有更好的开发体验。

webflux

  • 传统的Web框架,如springmvc基于Servlet API与Servlet容器基础之上运行的,Servlet3.1之后有了异步非阻塞的支持,而WebFlux是一个点典型非阻塞异步的框架,它的核心是基于Reacotr的相关API实现的,相对于传统的web框架来说,它可以运行诸如Netty,Undertow及支持Servlet3.1的容器上。非阻塞式+函数式编程
  • WebFlux是Spring5.0引入的新的响应式框架,区别于Spring MVC,它不需要依赖Servlet API,是完全异步非阻塞的,并且基于Reactor来实现响应式流规范。

三大核心概念

Route(路由)

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

Predicate(断言)

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

Filter(过滤)

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

web请求,通过一些匹配条件,定位到真正的服务节点。并在这个转发过程的前后进行一些精细化控制。
predicate相当于匹配条件,filter可以理解为一个无所不能的拦截器。有了这两个元素再加上目标uri,就可以实现一个具体路由了

Gateway工作流程

在这里插入图片描述

  • 客户端向Spring Cloud Gateway发出请求,然后在Gateway Handler Mapping中找到与请求相匹配的路由,将其发送到GatewayWebHandler
  • Hadler再通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回
  • 过滤器之间用虚线分开是因为过滤器可能会再发送代理请求之前(pre)或之后(post)执行业务逻辑
  • Filter再pre类型的过滤器可以做参数校验,权限校验,流量监控,日志输出,协议转换等
  • 再post类型的过滤器中还可以做响应内容,响应头的修改,日志的输出,流量监控等

入门案例

建module
编pom

 <dependencies>
<!--        gateway-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <!--监控-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <!--eureka client-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.hsw.cloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

写yml

在这里插入图片描述
主启动

在这里插入图片描述
需求,如何做路由映射

  • cloud-provider-payment8001看看controller的访问地址有get访问和lb访问
  • 我们目前不想暴露8001端口,希望在8001外面套一层9527
    在这里插入图片描述添加配置

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
显示实际端口是8001
在这里插入图片描述
Gateway网关路由有两种配置方式:

  • 配置文件yml中配置,如上所示
  • 代码中注入RouteLocator的Bean

在这里插入图片描述

  • 自己实现一个访问9527,跳到百度页面
    在这里插入图片描述/guonei,映射百度新闻的国内

在这里插入图片描述

通过服务名实现动态路由

  • 默认情况下Gatway会根据注册中心注册的服务列表, 以注册中心上微服务名为路径创建动态路由进行转发,从而实现动态路由的功能

yml配置注意下

![在这里插入图片描述](https://img-blog.csdnimg.cn/20210303205759286.png?x-oss-process=image在这里插入图片描述

Predicate

  • 启动项目时会发现

在这里插入图片描述Route Predicate Factories是啥?

在这里插入图片描述
常用的Route Predicate

可以参考中文文档:地址

  • 1.After Route Predicate
  • 2.Before Route Predicate
  • 3.Between Route Predicate
  • 4.Cookie Route Predicate
  • 5.Header Route Predicate
  • 6.Host Route Predicate
  • 7.Method Route Predicate
  • 8.Path Route Predicate
  • 9.Query Route Predicate
  • 10.RemoteAddr Route Predicate
  • 11.Weight Route Predicate

After Route Predicate Factory采用一个参数——日期时间。在该日期时间之后发生的请求都将被匹配。

application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: http://example.org
        predicates:
        - After=2017-01-20T17:42:47.789-07:00[America/Denver]

时间的获取方式:

在这里插入图片描述
Cookie 路由断言 Factory

  • Cookie 路由断言 Factory有两个参数,cookie名称和正则表达式。请求包含次cookie名称且正则表达式为真的将会被匹配。

application.yml

spring:
  cloud:
    gateway:
      routes:
      - id: cookie_route
        uri: http://example.org
        predicates:
        - Cookie=chocolate, ch.p    //这里就要求请求必须带cookie,key为chocolate,value为ch.p

说白了,Predicate就是为了实现一组匹配规则, 让请求过来找到对应的Route进行处理

Filter的使用

  • 路由过滤器可用于修改进入的HTTP请求和返回的HTTP响应,路由过滤器只能指定路由进行使用
  • Spring Cloud Gateway内置了多种路由过滤器,他们都由GatewayFilter的工厂类来产生

Spring Cloud Gateway的filter

自定义全局GlobalFilter

  • 两个主要接口GlobalFilter,OrderId

  • 可用于全局日志记录,统一网关鉴权等

@Component
@Slf4j
public class MyLogGatewayFilter implements GlobalFilter, Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("come in global filter: {}", new Date());

        ServerHttpRequest request = exchange.getRequest();
        String uname = request.getQueryParams().getFirst("uname");
        if (uname == null) {
            log.info("用户名为null,非法用户");
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
            return exchange.getResponse().setComplete();
        }
        // 放行
        return chain.filter(exchange);
    }

    /**
     * 过滤器加载的顺序 越小,优先级别越高
     *
     * @return
     */
    @Override
    public int getOrder() {
        return 0;
    }
}
 
 
  • 此时访问localhost:9527/payment/lb

在这里插入图片描述

  • 如果带uname
    在这里插入图片描述
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值