Spring GateWay

news2024/9/26 1:25:07

概述简介

能干什么

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

Spring Cloud Gateway 与Zuul的区别

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

image.png

上述模式的缺点:
servlet是一个简单的网络IO模型,当请求进入servlet container时,servlet container就会为其绑定一个线程,在并发不高的场景下这种模型是适用的。但是一旦高并发(此比如抽风用jemeter压),线程数量就会上涨,而线程资源代价是昂贵的(上线文切换,内存消耗大)严重影响请求的处理时间。在一些简单业务场景下,不希望为每个request分配一个线程,只需要1个或几个线程就能应对极大并发的请求,这种业务场景下servlet模型没有优势
所以Zul 1.X是基于servlet之上的一个阻塞式处理模型,即spring实现了处理所有request请求的一个servlet (DispatcherServlet)并由该servlet阻塞式处理.所以SpringCloud zuul无法摆脱servlet模型的弊端

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

二,三大核心概念

Router(路由)

路由是构建网关的基本模块,它由id,目标url,一系列断言和过滤器组成,如果断言为TRUE则匹配该路由
image.png

predicate(断言)

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

filter(过滤)

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

总体

image.png

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

三,工作流程

image.png
客户端向Spring Cloud Gateway发出请求。然后在Gateway Handler Mapping 中找到与请求相匹配的路由,将其发送到Gatewa)Web Handler。
Handler再通过指定的过滤器链来将请求发送到我们实际的服务执行业务逻辑,然后返回。
过滤器之间用虚线分开是因为过滤器可能会在发送代理请求之前(“pre”)或之后(“post”)执行业务逻辑。

核心逻辑

路由转发+执行过滤链

四,入门配置

<dependency>  
    <groupId>org.springframework.cloud</groupId>  
    <artifactId>spring-cloud-starter-gateway</artifactId>  
</dependency>
server:  
  port: 9527  
spring:  
  application:  
    name: cloud-gateway  
eureka:  
  instance:  
    hostname: cloud-gateway-service  
  client:  
    service-url:  
      register-with-eureka: true  
      fetch-register: true  
      defaultZone: http://eureka7001.com:7001/eureka
package com.atguigu.springcloud;  
  
import org.springframework.boot.SpringApplication;  
import org.springframework.boot.autoconfigure.SpringBootApplication;  
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;  
  
@SpringBootApplication  
@EnableEurekaClient  
public class GateWayMain9527 {  
    public static void main(String[] args) {  
        SpringApplication.run(GateWayMain9527.class,args);  
    }  
}

9527网关如何做路由映射

image.png

yml新增网关配置

server:
  port: 9527

spring:
  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/

这两个要删掉

<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>

成功
image.png
image.png

网关配置两种方式

image.png

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

  2. 在配置类中配置
    代码中注入RouteLocator的Bean 在这里插入图片描述
    在这里插入图片描述

@Configuration
public 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();
    }

//    @Bean
//    public RouteLocator customRouteLocator2(RouteLocatorBuilder routeLocatorBuilder){
//        RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
//
//        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();
//    }

}

出现的问题

  1. 地址写死
  2. 8001这种服务提供者不可能只有一台机器

五,根据服务名实现负载均衡

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

image.png

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

Spring Cloud Netflix Ribbon会在定义lb前缀的目标URI上实现负载平衡(官方文档翻译)

六, Predicate的使用

image.png

Spring Cloud Gateway将路由匹配作为Spring WebFlux HandlerMapping基础架构的一部分。
Spring Cloud Gateway包括许多内置的Route Predicate工厂。所有这些Predicate都与HTTP请求的不同属性匹配。多个RoutePredicate工厂可以进行组合
Spring Cloud Gateway创建Route对象时,使用RoutePredicateFactory创建Predicate对象
Predicate 对象可以赋值给
Route。Spring Cloud Gateway包含许多内置的Route Predicate Factories。
所有这些谓词都匹配HTTP请求的不同属性。多种谓词工厂可以组合,并通过逻辑and。

image.png

After Route Predicate

  • 获取当前时区的时间
    ZoneDateTime.now()
predicates:
- Path=/payment/1b/**
#断言,路径相匹配的进行路由
- After=2020-02-21T15:51:37.485+08:0o[Asia/shanghai]

Cookie Route Predicate

  • 不带cookie访问
  • 带cookie访问
    image.png

image.png

Cookie Route Predicate需要两个参数,一个是Cookie name ,一个是正则表达式。
路由规则会通过获取对应的Cookie name值和正则表达式去匹配,如果匹配上就会执行路由,如果没有匹配上则不执行

Header Route Predicate Factory


spring:
	cloud :
		gateway :
			routes:
			- id: header_route
				uri: https : //example.org
				predicates:
				- HeaderX-Request-Id,ld+

两个参数:一个是属性名称和一个正则表达式,这个属性值和正则表达式匹配则执行。
image.png

路径匹配

例如
Path=/*/product/**断言

  • 作用: 这个断言基于请求的路径来决定是否将请求路由到对应的服务。只有当请求的路径匹配指定的模式(在这个例子中是/*/product/**),请求才会被路由到配置中指定的服务。这种模式允许在请求的路径中有很大的灵活性,能够匹配包含/product/的任何路径。
  • 适用场景: 当你想要根据请求的URL路径将不同的请求分发到不同的后端服务时,这种方式非常有用。比如,所有关于产品信息的请求都可以路由到处理产品信息的微服务。

host匹配

Host=item.gmall.com断言

  • 作用: 这个断言基于请求的主机名(即域名)来决定是否将请求路由到对应的服务。只有当请求的主机名完全匹配item.gmall.com时,请求才会被路由到配置中指定的服务。这种方式侧重于基于请求的“来源”或者说是“访问的域名”来进行路由。
  • 适用场景: 当你的网关服务多个域名,并且你希望根据不同的域名将请求分发到不同的服务时,这种方式非常有用。比如,所有来自item.gmall.com的请求都被路由到处理特定商品信息的服务。

七,filter

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

概述

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

image.png

  • 生命周期,only Two
    • pre
    • post
  • 种类,Only Two
    • GateWayFilter
    • GlobalFilter

常用的GateWayFilter

GatewayFilter(31种)
Global Filter(10种)

这里以AddRequestParameter为代表。
image.png

自定义过滤器

两个主要接口介绍

implements GlobalFilter,Ordered

能干啥

  • 全局日志记录
  • 统一网关鉴权

配置

@Slf4j
public class MyLogGateWayFilter implements GlobalFilter, Ordered {


    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        log.info("**************come in MyLogGateWayFilter:" + new Date());
        //获取request中的uname参数
        String uname = exchange.getRequest().getQueryParams().getFirst("uname");

        if(uname == null){
            log.info("*******用户名为null,非法用户!!");
            //设置响应,不被接受
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);

            return exchange.getResponse().setComplete();
        }

        //返回chain.filter(exchange),放行
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        //返回值是过滤器的优先级,越小优先级越高(最小-2147483648,最大2147483648)
        return 0;
    }
}

启动7001,8001,8002,9527
http://localhost:9527/payment/lb?uname=111
在这里插入图片描述
http://localhost:9527/payment/lb?xxx=111
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1438816.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

双非本科准备秋招(19.1)—— Synchronized优化

轻量级锁 流程 一个对象虽然有多线程加锁&#xff0c;但是加锁时间是错开的&#xff0c;那么可以用轻量级锁优化。 语法还是synchronized&#xff0c;只是对使用者是透明的。 static final Object obj new Object(); public static void method1() {synchronized( obj ) {//…

Unity AnimationRigging无法修改权重?

个人理解&#xff0c;已解决无法修改权重的问题: unity自带的动画系统是在FixUpdate和Update之后LateUpdate之前执行&#xff0c;如果在这FixedUpdate或Update函数内更新AnimationRigging内的权重后&#xff0c;内部动画系统会覆盖权重的修改&#xff0c;导致无法正确更新&…

C语言:函数递归

创作不易&#xff0c;给个三连吧&#xff01;&#xff01; 一、什么是递归 递归式一种解决问题的方法&#xff0c;在C语言中&#xff0c;递归就是自己调用自己。 递归的思想&#xff1a; 把⼀个⼤型复杂问题层层转化为⼀个与原问题相似&#xff0c;但规模较小的⼦问题来求解…

FPC概述及仿真

柔性印刷电路(FPC)是由聚酰亚胺或聚酯薄膜制成的高可靠性和优异的柔性印刷电路板。它具有布线密度高、重量轻、厚度薄、可弯曲性好等特点。 概述 FPC&#xff0c;也被称为柔性印刷电路&#xff0c;因其重量轻&#xff0c;厚度薄&#xff0c;自由弯曲和折叠等优异特性而受到青睐…

Nicn的刷题日常之操作一维数组

1.题目描述 创建一个整形数组&#xff0c;完成对数组的操作 实现函数init() 初始化数组为全0实现print() 打印数组的每个元素实现reverse() 函数完成数组元素的逆置。 要求&#xff1a;自己设计以上函数的参数&#xff0c;返回值。 2.解题 void Init(int arr[], int sz, …

网站被攻击有什么办法呢?

最近&#xff0c;德迅云安全遇到不少网站用户遇到攻击问题&#xff0c;来咨询安全解决方案。目前在所有的网络攻击方式中&#xff0c;DDoS是最常见&#xff0c;也是最高频的攻击方式之一。不少用户网站上线后&#xff0c;经常会遭受到攻击的困扰。有些攻击持续时间比较短影响较…

TI毫米波雷达开发——High Accuracy Demo 串口数据接收及TLV协议解析 matlab 源码

TI毫米波雷达开发——串口数据接收及TLV协议解析 matlab 源码 前置基础源代码功能说明功能演示视频文件结构01.bin / 02.binParseData.mread_file_and_plot_object_location.mread_serial_port_and_plot_object_location.m函数解析configureSport(comportSnum)readUartCallback…

Appium报错:无法打开appPackage

能打开微信、微博&#xff0c;但是要打开另一个app的时候&#xff0c;就出现上面的报错信息。 报错信息说参考&#xff1a;https://github.com/appium/appium/blob/master/docs/en/writing-running-appium/android/activity-startup.md &#xff0c;链接地址变了&#xff0c;找…

数据结构——单链表详解

目录 前言 一.什么是链表 1.概念 ​编辑 2.分类 二.单链表的实现(不带头单向不循环链表) 2.1初始化 2.2打印 2.3创建新节点 2.4头插、尾插 2.5头删、尾删 2.6查找 2.7在指定位置之前插入 2.8在指定位置之后插入 2.9删除pos位置 2.10删除pos之后的 2.11销毁链表…

JavaScript 入门

目录 第一个知识点&#xff1a;引入js文件 内部引用: 外部引用: 第二个知识点&#xff1a;javascript的基本语法 定义变量&#xff1a; 条件控制(if - else if - else) 第三个知识点&#xff1a;javascript里的数据类型、运算符&#xff1a; 数字类型 字符串类型 布尔…

B站UP主实时信息获取展示php源码

B站UP主实时数据展示系统 - PHP源码分享 想要实时追踪你心仪的B站UP主的最新动态吗&#xff1f;现在&#xff0c;你可以轻松获取并展示B站UP主的实时数据&#xff0c;包括粉丝数、作品数、头像、播放量等关键信息。 功能亮点&#xff1a; 实时更新&#xff1a;系统通过B站AP…

高中学校档案室主要做什么

高中学校档案室主要负责管理、保存和维护学校的各类档案文件。具体工作内容包括&#xff1a; 1. 档案收集&#xff1a;负责收集学校各个部门的档案文件&#xff0c;包括学生档案、教职工档案、教学档案、行政档案等。 2. 档案分类和整理&#xff1a;对收集到的档案文件进行分类…

LeetCode Python - 1.两数之和

文章目录 题目答案运行结果 题目 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出 和为目标值 target 的那 两个 整数&#xff0c;并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是&#xff0c;数组中同一个元素在答案里不能…

(2024,弱到强蒸馏,开源 CLIP,模型扩展)EVA-CLIP-18B:将 CLIP 扩展到 18B 参数

EVA-CLIP-18B: Scaling CLIP to 18 Billion Parameters 公和众和号&#xff1a;EDPJ&#xff08;进 Q 交流群&#xff1a;922230617 或加 VX&#xff1a;CV_EDPJ 进 V 交流群&#xff09; 目录 0. 摘要 1. 简介 2. 弱到强视觉扩展 3. 实验 0. 摘要 扩展对比语言-图像预训…

Flink实战六_直播礼物统计

接上文&#xff1a;Flink实战五_状态机制 1、需求背景 现在网络直播平台非常火爆&#xff0c;在斗鱼这样的网络直播间&#xff0c;经常可以看到这样的总榜排名&#xff0c;体现了主播的人气值。 人气值计算规则&#xff1a;用户发送1条弹幕互动&#xff0c;赠送1个荧光棒免费…

【JS逆向八】逆向某企查网站的headers参数,并模拟生成 仅供学习

逆向日期&#xff1a;2024.02.07 使用工具&#xff1a;Node.js 加密方法&#xff1a;未知 / 标准库Hmac-SHA512 文章全程已做去敏处理&#xff01;&#xff01;&#xff01; 【需要做的可联系我】 可使用AES进行解密处理&#xff08;直接解密即可&#xff09;&#xff1a;AES加…

2月7日作业

分别通过select、多进程、多线程实现一个并发服务器 #include <myhd.h> #define IP "192.168.250.100" #define PORT 8888 int deal_cli_msg(int newfd,struct sockaddr_in cin) {char buf[128] "";while(1){bzero(buf,sizeof(buf));int res recv…

【已解决】onnx转换为rknn置信度大于1,图像出现乱框问题解决

前言 环境介绍&#xff1a; 1.编译环境 Ubuntu 18.04.5 LTS 2.RKNN版本 py3.8-rknn2-1.4.0 3.单板 迅为itop-3568开发板 一、现象 采用yolov5训练并将pt转换为onnx&#xff0c;再将onnx采用py3.8-rknn2-1.4.0推理转换为rknn出现置信度大于1&#xff0c;并且图像乱框问题…

(力扣)1314.矩阵区域和

给你一个 m x n 的矩阵 mat 和一个整数 k &#xff0c;请你返回一个矩阵 answer &#xff0c;其中每个 answer[i][j] 是所有满足下述条件的元素 mat[r][c] 的和&#xff1a; i - k < r < i k, j - k < c < j k 且(r, c) 在矩阵内。 示例 1&#xff1a; 输入&a…

春节假期如何高效管理Shopee虾皮本土店?技巧都给你整理好了!

EasyBoss ERP 对于中国人最重要的春节即将来临&#xff0c;但对于运营Shopee、TikTok Shop等平台的卖家而言&#xff0c;他们的客户可不会过春节。为了不影响店铺的业绩&#xff0c;很多卖家在春节期间都还是照常运营店铺&#xff0c;但又不想错过和家人团圆的机会怎么办&…