8、Gateway网关(个人学习笔记)

1、Gateway概述简介

官网:Gateway网关官网

在这里插入图片描述

Gateway是什么

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

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

  • SpringCloud GatewaySpring Cloud的一个全新项目,基于Spring 5.0+Spring Boot 2.0和Project Reactor等技术开发的网关,它 旨在为微服务架构提供—种简单有效的统一的API路由管理方式

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

  • Spring Cloud Gateway的目标是提供统一的路由方式且基于 Filter链的方式提供了网关基本的功能,例如:安全,监控/指标,和限流

Gateway能干什么

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

Gateway网关在微服务架构中的位置

在这里插入图片描述

GateWay是基于异步非阻塞模型上进行开发的, 它的特性都有什么呢?

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

Spring Cloud Gateway与Zuul的区别

  • SpringCloud Finchley正式版之前,Spring Cloud推荐的网关是Netflix提供的Zuul
  • Zuul 1.x,是一个基于阻塞I/O的API Gateway
  • Zuul 1.x基于Servlet 2.5使用阻塞架构它不支持任何长连接(如WebSocket)Zuul的设计模式和Nginx较像,每次I/О操作都是从工作线程中选择一个执行,请求线程被阻塞到工作线程完成,但是差别是Nginx用C++实现,Zuul用Java实现,而JVM本身会有第-次加载较慢的情况,使得Zuul的性能相对较差
  • Spring Cloud Gateway建立在Spring Framework 5、Project Reactor和Spring Boot2之上,使用非阻塞API
  • Spring Cloud Gateway还支持WebSocket,并且与Spring紧密集成拥有更好的开发体验

2、三大核心概念

Route路由

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

Predicate断言

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

Filter过滤

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

在这里插入图片描述

  • web请求,通过一些匹配条件,定位到真正的服务节点。并在这个转发过程的前后,进行一些精细化控制。

  • predicate就是我们的匹配条件;fliter就可以理解为一个无所不能的拦截器。有了这两个元素,再加上目标url,就可以实现一个具体的路由了

3、Gateway工作流程

在这里插入图片描述

  • 客户端向Spring Cloud Gateway发出请求。然后在Gateway Handler Mapping 中找到与请求相匹配的路由,将其发送到GatewayWeb Handler

  • Handler再通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回

  • 过滤器之间用 虚线分开 是因为过滤器可能会在发送代理请求之前(“pre”)或之后(“post")执行业务逻辑

  • Filter“pre”类型(之前) 的过滤器可以做 参数校验、权限校验、流量监控、日志输出、协议转换等,在 “post”类型(之后) 的过滤器中可以做 响应内容、响应头的修改,日志的输出,流量监控等

  • 核心逻辑:路由转发 + 执行过滤链

4、Gateway入门配置

新建spring-cloud-starter-gateway项目

修改pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>cloud2020</artifactId>
        <groupId>com.springcloud</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-gateway-gateway9572</artifactId>

    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <!--eureka-client-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!--   引入自己定义的api通用包,可以使用Paymeny支付Entity     -->
        <dependency>
            <groupId>com.springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>
    </dependencies>

</project>

写yml文件

server:
  port: 9527

spring:
  application:
    name: cloud-gateway

eureka:
  instance:
    hostname: cloud-gateway-service
  client:
    service-url:
      register-with-eureka: true
      fetch-registry: true
      defaultZone:
        http://eureka7001.com:7001/eureka

主启动类

@SpringBootApplication
@EnableEurekaClient
public class GateWayMain9527 {
    public static void main(String[] args) {
        SpringApplication.run(GateWayMain9527.class, args);
    }
}

yml文件中新增网关配置

那么spring-cloud-starter-gateway如何做路由映射呢?我们目前不想暴露8001端口,希望在8001外面套一层9527

server:
  port: 9527

spring:
  application:
    name: cloud-gateway
###############################新增网关配置####################################
  cloud:
    gateway:
      routes:  # 网关可以配置多个
        - id: payment_routh   # 路由的id,没有固定的规则但要求唯一,建议配合服务名
          uri: http://localhost:8001 # 匹配后提供服务的路由地址
          predicates:
            - Path=/payment/get/**
##############################################################################
eureka:
  instance:
    hostname: cloud-gateway-service
  client:
    service-url:
      register-with-eureka: true
      fetch-registry: true
      defaultZone:
        http://eureka7001.com:7001/eureka

启动测试:启动7001,8001,9527

在这里插入图片描述

  • 添加网关前:http://localhost:8001/payment/get/1
    在这里插入图片描述

  • 添加网关后:http://localhost:9527/payment/get/1
    在这里插入图片描述

  • 结论:两者访问成功,并且返回结果相同

5、Gateway配置路由的两种方式

  • 在配置文件中yml文件中配置

  • 代码中实现:注入RouteLocator的Bean

  • 官网的实现方式:实现方式

RemoteAddressResolver resolver = XForwardedRemoteAddressResolver
    .maxTrustedIndex(1);

...

.route("direct-route",
    r -> r.remoteAddr("10.1.1.1", "10.10.1.1/24")
        .uri("https://downstream1")
.route("proxied-route",
    r -> r.remoteAddr(resolver, "10.10.1.1", "10.10.1.1/24")
        .uri("https://downstream2")
)

我们通过代码去实现——通过9527网关访问到一个网址

@Configuration
public class GateWayConfig {

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

测试

访问http://localhost:9527/guonei,返回http://news.baidu.com/guonei相同的页面。

6、GateWay常用的Predicate(断言)

Spring Cloud Gateway matches routes as part of the Spring WebFlux HandlerMapping infrastructure. Spring Cloud Gateway includes many built-in route predicate factories. All of these predicates match on different attributes of the HTTP request. You can combine multiple route predicate factories with logical and statements.

  • Spring Cloud GateWay将路由匹配作为Spring WebFlux HandlerMapping基础架构的一部分。

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

  • Spring Cloud GateWay创建Route对象时,使用RoutePredicateFactory创建Predicate对象, Predicate对象可以赋值给RouteSpring Cloud GateWay包含许多内置的 RoutePredicateFactory

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

  • 常用的Route Predicate Factory

    • The After Route Predicate Factory
    • The Before Route Predicate Factory
    • The Between Route Predicate Factory
    • The Cookie Route Predicate Factory
    • The Header Route Predicate Factory
    • The Host Route Predicate Factory
    • The Method Route Predicate Factory
    • The Path Route Predicate Factory
    • The Query Route Predicate Factory
    • The RemoteAddr Route Predicate Factory
    • The weight Route Predicate Factory

The After Route Predicate Factory

  • 官网配置示例:
spring:
  cloud:
    gateway:
      routes:
      - id: after_route
        uri: https://example.org
        predicates:
         # 在这个时间之后才会生效
        - After=2017-01-20T17:42:47.789-07:00[America/Denver]
  • 2017-01-20T17:42:47.789-07:00[America/Denver]:美国时间
  • ZonedDateTime.now():从默认时区中的系统时钟获取当前日期时间。
  • 2022-02-25T16:50:23.358+08:00[Asia/Shanghai]:当前时间

The Cookie Route Predicate Factory

The cookie route predicate factory takes two parameters, the cookie name and a regular expression. This predicate matches cookies that have the given name and whose values match the regular expression. The following example configures a cookie route predicate factory

  • 官网配置示例:
spring:
  cloud:
    gateway:
      routes:
      - id: cookie_route
        uri: https://example.org
        predicates:
        - Cookie=chocolate, ch.p
  • Cookie Route Predicate需要两个参数,一个是Cookie name,一个是正则表达式
  • 路由规则会通过获取对应的 Cookie name值和正则表达式 去匹配,如果匹配上就会执行路由,如果没有匹配上则不执行
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值