Gateway

简介

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

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

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

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

微服务中的网关位置

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/ O 操作都是从工作线程中选择一个执行,请求线程被阻塞到工作线程完成,但是差别是Nginx 用C++ 实现,Zuul 用 Java 实现,而 JVM 本身会有第一次加载较慢的情况,使得Zuul 的性能相对较差。
  • Zuul 2.x理念更先进,想基于Netty非阻塞和支持长连接,但SpringCloud目前还没有整合。 Zuul 2.x的性能较 Zuul 1.x 有较大提升。在性能方面,根据官方提供的基准测试,Spring Cloud Gateway 的 RPS 是 Zuul 的 1.6 倍。
  • Spring Cloud Gateway 建立在 Spring Framework 5,Project Reactor 和 Spring Boot 2 之上,使用非阻塞 API。
  • Spring Cloud Gateway 还支持 WebSocket,并且与 Spring 紧密集成拥有更好的开发体验。

WebFlux是什么?

传统的Web框架,比如说:struts2,springmvc等都是基于Servlet API与Servlet容器基础之上运行的。

但是在 Servlet3.1 之后有了异步非阻塞的支持。而 WebFlux 是一个典型非阻塞异步的框架,它的核心是基于Reactor 的相关 API 实现的。相对于传统的 web 框架来说,它可以运行在诸如 Netty,Undertow 及支持Servlet3.1 的容器上。非阻塞式+函数式编程( Spring5 必须让你使用 java8)

Spring WebFlux 是 Spring 5.0 引入的新的响应式框架,区别于 Spring MVC,它不需要依赖 Servlet API,它是完全异步非阻塞的,并且基于 Reactor 来实现响应式流规范。

Gateway 的核心概念

Route(路由)

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

Predicate(断言)

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

Filter(过滤)

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

总结

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

大致流程

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

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

过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前(”pre”)或之后(”post”)执行业务逻辑。Filter在”pre”类型的过滤器可以做参数校验、权限校验、流量监控、日志输出、协议转换等,在”post”类型的过滤器中可以做响应内容、响应头的修改,日志的输出,流量监控等有着非常重要的作用。

案例

导包


    org.springframework.cloud
    spring-cloud-starter-gateway

修改配置文件

spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
      routes:
        - id: payment_routh #payment_route    #路由的ID,没有固定规则但要求唯一,建议配合服务名
          #uri: http://localhost:8001          #匹配后提供服务的路由地址
          uri: lb://cloud-payment-service #匹配后提供服务的路由地址
          predicates:
            - Path=/payment/get/**         # 断言,路径相匹配的进行路由

        - id: payment_routh2 #payment_route    #路由的ID,没有固定规则但要求唯一,建议配合服务名
          #uri: http://localhost:8001          #匹配后提供服务的路由地址
          uri: lb://cloud-payment-service #匹配后提供服务的路由地址
          predicates:
            - Path=/payment/lb/**         # 断言,路径相匹配的进行路由
            #- After=2020-02-21T15:51:37.485+08:00[Asia/Shanghai]
            #- Cookie=username,zzyy
            #- Header=X-Request-Id, \d+  # 请求头要有X-Request-Id属性并且值为整数的正则表达式

配置类的方法

@Configuration
public class GatewayConfig {

    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder) {
        RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
        routes.route("path_route_atguigu",
                r -> r.path("/guonei")
                        .uri("https://news.baidu.com/guonei")).build();

        return routes.build();
    }
}

Predicate 使用

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

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

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

常用的Route Predicate

  • 请求时间校验条件(datetime):
  • After Route Predicate:请求时间满足在配置时间之后。
  • Before Route Predicate:请求时间满足在配置时间之前。
  • Between Route Predicate:请求时间满足在配置时间之间。
  • 请求 Cookie校验条件(Cookie):
  • Cookie Route Predicate:请求指定 Cookie 正则匹配指定值
    • 需要两个参数,一个是 Cookie name,一个是正则表达式。
  • 请求 Header 校验条件(Header):
  • Header Route Predicate:请求指定 Header 正则匹配指定值;
    • 两个参数:一个是属性名称和一个正则表达式,这个属性值和正则表达式匹配执行。
      +
curl http://localhost:9527/payment/lb -H "X-Request-Id:123"
  • CloudFoundryRouteServiceRoutePredicateFactory:请求 Headers 是否包含指定的名称。
  • 请求 Host 校验条件(Host):
  • Host Route Predicate:请求 Host 匹配指定值;
  • 请求 Method 校验条件(Method):
  • Method Route Predicate:请求 Method 匹配配置的 method;
  • 请求 Path 校验条件(Path):
  • Path Route Predicate:请求路径正则匹配指定值;
  • 请求查询参数校验条件(Queryparam):
  • Query Route Predicate:请求查询参数正则匹配指定值;
  • 请求远程地址校验条件(RemoteAddr):
  • RemoteAddrRoutePredicateFactory:请求远程地址匹配配置指定值;

Filter 的使用

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

Filter 的分类

生命周期
  • pre
  • post
种类
  • GatewayFilter
  • GlobalFilter

自定义过滤器

主要实现:全局日志记录、统一网关鉴权等服务;

案例
@Component
@Slf4j
public 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.NOT_ACCEPTABLE);
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 0;
    }
}

Original: https://www.cnblogs.com/lhnstart/p/16158106.html
Author: 李小龙他哥
Title: Gateway

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/588696/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 通俗易懂spring之singleton和prototype

    关于spring bean作用域,基于不同的容器,会有所不同,如BeanFactory和ApplicationContext容器就有所不同,在本篇文章,主要讲解基于Applicat…

    Java 2023年5月30日
    083
  • SpringBoot —— Filter 过滤器

    SpringBoot——实现过滤器Filter 1、Filter过滤器 (1) 主要用来过滤用户请求的,允许我们对用户的请求进行前置处理和后置处理。面向切面编程AOP。 例如:实现…

    Java 2023年6月5日
    064
  • auth授权登录:淘宝客官方接口中用到的sessionkey是如何获取的

    404. 抱歉,您访问的资源不存在。 可能是网址有误,或者对应的内容被删除,或者处于私有状态。 代码改变世界,联系邮箱 contact@cnblogs.com 园子的商业化努力-困…

    Java 2023年5月30日
    067
  • Kubernetes-Service

    1. 简介 kubernets service 是将运行一组pods上的应用程序公开为网络服务的抽象方法。 有了 kubernets service,你就无需修改应用程序即可使用服…

    Java 2023年6月7日
    068
  • 并发编程之:ThreadLocal

    大家好,我是小黑,一个在互联网苟且偷生的农民工。 从前上一期【并发编程之:synchronized】 我们学到要保证在并发情况下对于共享资源的安全访问,就需要用到锁。 但是,加锁通…

    Java 2023年6月7日
    095
  • ysoserial URLDNS利用链分析

    对这个测试类Urldns做序列化后,反序列化的时候执行了重写的readobject方法。 所以只要对readobject方法做重写就可以实现在反序列化该类的时候得到执行。 利用链的…

    Java 2023年6月5日
    066
  • springmvc项目中InitializingBean执行2次

    为了修复生产数据,需要执行一段一次性的代码。 鉴于是spring老项目,就想到了InitializingBean。 代码如下。服务启动后,log里发现出现2条”一次性任…

    Java 2023年5月30日
    095
  • Spring Ioc源码分析系列–@Autowired注解的实现原理

    Spring Ioc源码分析系列–@Autowired注解的实现原理 前言 前面系列文章分析了一把Spring Ioc的源码,是不是云里雾里,感觉并没有跟实际开发搭上半…

    Java 2023年6月8日
    069
  • Spring Cloud认知学习(五):网关Zuul的使用

    💡这一篇介绍一个新的组件Zuul,Zuul是网关组件,对Api请求进行了统一的接收,基于网关,我们可以对所有的请求来进行处理,进行日志记录,请求授权等操作。 zuul可以作为微服务…

    Java 2023年5月30日
    090
  • ab test压力测试

    之前做性能调试的时候一直用的JMeter压测,最近发现一款简单易用的压力测试工具。 ab(Apache benchmark)是一款常用的压力测试工具,是Apache附带的一个小工具…

    Java 2023年6月8日
    0101
  • 聊聊webservice

    webservice这个东西已经是一个比较旧的技术了,可能很多人都没听说过,乍一听是不是跟websocket有关呀,哈哈哈,其实压根就是两个东西; 我对webservice的理解是…

    Java 2023年6月6日
    069
  • PowerJob高级特性-容器部署完整教程

    介绍 powerjob提供了容器功能,用来做一些灵活的任务处理。这里容器为 JVM 级容器,而不是操作系统级容器(Docker)。(至于为什么取”容器”这个…

    Java 2023年6月6日
    093
  • Elasticsearch必知必会的干货知识二:ES索引操作技巧

    一次性创建包含完整的别名(alias)、字段(mappings)、设置(settings)的索引,如: PUT /index_name { "index_name&quo…

    Java 2023年6月9日
    0178
  • TreeMap源码分析

    TreeMap源码分析 数据结构 TreeMap使用红黑树来存储数据,红黑树是一种平衡二叉查找树,它是一种高效的搜索算法,它的算法时间复杂度是O(lgn) 增删改查 增改 publ…

    Java 2023年6月16日
    071
  • poi读excel的空cell时,产生空指针

    背景 昨天,我用poi读取excel时,当读到空的cell时,抛出个空指针异常。但是当我读取别的excel时,即使cell为空,也不抛空指针啊,读出结果为”&#8221…

    Java 2023年6月5日
    058
  • 软件需求分析与系统设计笔记

    简介 软件过程模型 瀑布模型 快速原型模型 增量模型 螺旋模型 喷泉模型 各模型优缺点: 简介 什么是软件? 软件是计算机系统中与硬件(hardware)相互依存的另一 部分,是程…

    Java 2023年6月15日
    087
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球