Gateway新一代网关

概述简介

官网:

zuul 1.X : https://github.com/Netflix/zuul/wiki
Gateway: http://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html

是什么

cloud全家桶中有个很重要的组件就是网关,在1.X版本中都采用了zuul网关;
但在2.x版本中,zuul的升级一直在跳票,SpringCloud最后自己研发了一个网关代替zuul. gateway是原zuul1.x版的替代.

在这里插入图片描述
Gateway是在Spring生态系统之上构建的API网关服务,基于Spring5,SpringBoot 2 和Project Reactor等技术.
Gateway旨在提供一种简单而有效的方式来对API进行路由,以及提供一些强大的过滤器功能,例如: 熔断,限流,重试等.
在这里插入图片描述
Spring Cloud Gateway作为Spring Cloud生态系统中的网关,目标是代替zuul.在Spring Cloud 2.0以上版本中,没有对新版本的zuul2.0以上最新高性能版本进行集成,仍然还是使用了zuul 1.x非Reactor模式的老版本,而为了提供网关的性能,Spring Cloud Gateway是基于WebFlux框架实现的,而WebFlux框架底层则使用了高性能的Reactor模式通信框架Netty.

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

能干嘛

反向代理:
鉴权;
流量控制
熔断
日志监控

微服务架构中网关在哪里

在这里插入图片描述

有zuul了怎么又出来了Gateway

Zuul 1.0 已经进入了维护阶段,而且Gateway是SpringCloud团队研发的,而且很多功能Zuul都没有用起来也非常的简单便捷.

Gateway是基于异步非阻塞模型上进行开发的,性能方面不要担心,虽然Netfix早就发不了最新的Zuul 2.x,但是Spring Cloud没有整合,而且Netflix相关组件都宣布进入维护期;不知前景如何?

Spring Cloud Gateway具有如下特性:
基于Spring Framework 5,Project Reactor 和 Spring Boot2.0进行构建;
动态路由: 能够匹配任何请求属性;
可以对路由指定Predicate(断言) 和 Filter(过滤器);
集成Hystrix的断路器功能;
集成Spring Cloud服务发现功能;
易于编写Predicate(断言) 和 Fiter(过滤器);
请求限流功能;
支持路径重写.
Spring Cloud Gateway 与Zuul的区别:
在Spring Cloud Finchley 正式版之前,Spring Cloud推荐的网关是Netflix 提供Zuul:

  1. Zuul 1.x 是基于阻塞 I/O 的API Gateway
  2. Zuul1.x 基于Servlet 2.5使用阻塞架构,它不支持任何长连接(如 WebSocket) Zuul 的涉及模式和Nginx较像,每次 I/O 操作都是从工作线程中选择一个执行,请求线程被阻塞到工作线程完成,但是差别是Nginx用C++实现,Zuul用java实现,而JVM本身会有第一次加载比较慢的情况,是的Zuul的性能相对交差.
  3. Zuul 2.x理念更加先进,想基于Netty非阻塞和支持长连接,但SpringCloud目前还没有整合.Zuul 2.x的性能较Zuul 1.x有较大提升,在性能方面,根据官方提供的基准测试,Spring Cloud Gateway的RPS(每秒请求数)是Zuul的1.6倍.
  4. SpringCloud Gateway 建立在Spring Framework 5, Project Reactor 和 Spring boot 2 之上,使用非阻塞API.
  5. Spring Cloud Gateway 还支持webSocket,并且Spring 紧密集成拥有更好的开发体验.

Zuul 1.0模型 和 Gateway模型区别?
Spring cloud 中所集成的Zuu版本,采用的是Tomcat容器,使用的是传统的Servlet IO处理模型.
Servlet的生命周期?servlet由servlet container进行生命周期管理.
container启动时构造servlet对象并调用servlet init() 进行初始化;
container运行时接受请求,并为每个请求分配一个线程(一般从线程池中获取空闲线程) 然后调用service().
container关闭时调用servlet destory()销毁servlet;
在这里插入图片描述
传统定的web框架,比如说: strut2,springMVC等都是基于Servlet API与Servlet容器基础之上运行的.
但是
在servlet 3.1之后有了异步非阻塞的支持.而WebFlux是一个典型非阻塞异步的框架,它的核心是基于Reactor的相关API实现的.相对于在传统的web框架来说,它可以运行在诸如Netty,Undertow及支持Servlet3.1的容器上.非阻塞式+ 函数式编程(Spring5必须让你使用java8) Spring WebFlux是Spring 5.0引入的新的响应式框架,区别于SpringMVC,它不需要依赖Servlet API.它是完全异步非阻塞的,并且基于Reactor来实现响应式流规范.

三大核心概念

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

Predicate(断言)
参考的是JAVA8D的java,util.function.Predicatte
开发人员可以匹配Http请求中的所有内容(例如请求头或请求参数),如果请求与断言相匹配则进行路由
Filter(过滤)
指的是Spring框架中GatewayFiler的实例,使用过滤器,可以在请求被路由前或之后对请求进行修改.
在这里插入图片描述

Gateway工作流程

在这里插入图片描述

入门配置

  1. 建立网关工程
    cloud-Gateway-Gateway9527
  2. pom.xml
<dependencies>
        <!--引入自己的公共api-->
        <!--        <dependency>-->
        <!--            <groupId>org.springframework.boot</groupId>-->
        <!--            <artifactId>spring-boot-starter-web</artifactId>-->
        <!--        </dependency>-->
        <!--        <dependency>-->
        <!--            <groupId>org.springframework.boot</groupId>-->
        <!--            <artifactId>spring-boot-starter-actuator</artifactId>-->
        <!--        </dependency>-->
        <!--热部署-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </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>
        </dependency>
        <!--eureka-client-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
    </dependencies>
  1. yml
server:
  port: 9527

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

        - id: payment_routh2
          uri: http://localhost:8001
          predicates:
            - Path=/payment/lb/**
eureka:
  instance:
    hostname: cloud-gateway-service
  client:
    service-url:
      register-with-eureka: true
      fetch-registry: true
      defaultZone: http://eureka7001.com:7001/eureka

  1. 主启动类
@SpringBootApplication
@EnableEurekaClient
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class,args);
    }
}

  1. 业务类, 省略…
    Gateway 不涉及业务, 后续写过滤器
  2. 启动测试
    先测试:正常服务是否启动正常
    http://localhost:8001/payment/get/1在这里插入图片描述
    网关测试:
    http://localhost:9527/payment/get/1
    在这里插入图片描述
    2.用代码方式配置:
    案例,访问百度新闻地址: http://news.baidu.com/guonei
    a. 在业务类写配置baen的方法:
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;

@Configuration
public class GatewayConfig {

    /*
     * 配置了一个id 为routes_01的路由规则
     * 当访问地址http://localhost:9527/guonei时会自行转发到地址: http://news.baidu.com/guonei
     */
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder){
        RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
        routes.route("routes_01",
                r -> r.path("/guonei")  // 访问网关的guonei,将会路由到uri指定的地址
                        .uri("http://news.baidu.com/guonei")).build(); // http://news.baidu.com/guonei
        return routes.build();
    }

b. 测试:
测试地址:http://localhost:9527/guonei
在这里插入图片描述

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

上述配置的是单机版模式,如果服务提供方式集群方式的话,我们需要在yml文件上配置动态路由的访问方式.
a. 加依赖,所有的微服务都需要加gateway 依赖.
b. 配置yml
b.1 开启从注册中心动态创建路由的功能,利用微服务名进行路由

 discovery:
        locator:
          enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由

b.2 匹配后提供服务名的路由地址

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

        - id: payment_routh2
          # uri: http://localhost:8001
          uri: lb://cloud-payment-service # 匹配后提供服务的路由地址
          predicates:
            - Path=/payment/lb/**

c. 整体的效果如下:

server:
  port: 9527

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

        - id: payment_routh2
          # uri: http://localhost:8001
          uri: lb://cloud-payment-service # 匹配后提供服务的路由地址
          predicates:
            - Path=/payment/lb/**
      discovery:
        locator:
          enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
eureka:
  instance:
    hostname: cloud-gateway-service
  client:
    service-url:
      register-with-eureka: true
      fetch-registry: true
      defaultZone: http://eureka7001.com:7001/eureka

e. 测试
测试http://localhost:9527/payment/get/1
返回的端口不一致在这里插入图片描述

Predicate的使用

Spring Cloud Gateway将路由匹配作为Spring WebFlux HandlerMapping基础框架的一部分.
Spring Cloud Gateway 包括许多内置的Route Predicate工厂,所有这些Predicate 都与Http请求的不同属性匹配,多个Route Predicate工厂可以进行组合.

在这里插入图片描述
官网:
在这里插入图片描述

Filter的使用

Filter:指的是Spring 框架GatewayFilter的实例,使用过滤器,可以在请求被路由前或之后对请求进行修改.
路由过滤器可用于修改进入的Http请求和返回的Http响应,路由过滤器只能指定路由进行使用.
Spring Cloud Gateway内置了多种路由过滤器,他们都由GatewayFilter的工厂类来产生.

Filter的生命周期:
Only Two
pre 业务逻辑之前
post 业务逻辑之后
种类:
Only Two
GatewayFilter 单一的 官网31种之多
GlobalFilter 全局的
自定义过滤器
需要实现两个接口: implements GlobalFilter,Ordered
作用:全局日志记录
统一网关鉴权
自定义过滤器器
在业务类写一个拦截器
在这里插入图片描述

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
public class MyLogGateWayFilter implements GlobalFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        System.out.println("**************" +new Date());
        String key = exchange.getRequest().getQueryParams().getFirst("key");
        if (key == null){
            System.out.println("*****用户名为空: "+key+"*******");        // 如果key值为空
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);  // 进行拦截
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange); // 如果key不为空 放行.
    }

    @Override
    public int getOrder() {  // 加载执行顺序
        return 0;    // 数值越小,越先执行.
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值