spring cloud gateway 官方文档 Spring Cloud Gateway 中文文档

什么是api网关

对于微服务的每个接口,我们都需要校验请求的权限是否足够,而微服务把项目细化除了许多个接口,若这些接口都要对服务进行权限校验的话,那么无疑加重的代码负担和运行熟读,而如果我使用一个统一的服务来对所有的请求进行权限校验并将请求转发到对应的服务,而服务的接口不对外暴露,那么就可以确保服务收到的请求是服务之间调用的,而不是用户发起的请求调用的,而这个服务就是我们的网关,他是服务的守门神

api网关的结构如图

他通常是后端服务的唯一入口,类似于门面模式,所有的请求都经过他手并受他掉调度,协调,过滤,如果有有多个相同的服务启动了还可以使用负载均衡来平衡压力

常见的开源的api网关的实现有zuul,gateway,nginx,kong

部署Gateway服务

引入依赖

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId><version>4.0.6</version>
</dependency>
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

gateway服务也需要注册再注册中心nacos中,这个spring-cloud-xxx(loadbalancer)和spring-cloud-starter-xxx(loadbalancer)依赖的区别是前者提供了负载均衡的核心api,但是没有负载均衡的依赖的依赖,如果需要使用某些功能需要自己导入对应的依赖,而后者stater他提供开箱即用的体验,他是一个空的jar包,但是会有一些元数据来告诉他需要导入哪些依赖来确保依赖运行

对项目写一

个启动类之后就可以路由配置了

gateway路由规则

可以写在代码中 不过很麻烦

写在配置文件中要简便许多 

uri也可以使用ws://或wss://来进行websocket请求的转发可以直接转发到固定的url或者通过服务发现,ws和wss的区别是前者是未加密的websocket连接后者是加密的websocket连接

http://和https:// 转发到固定的http和https地址

Route Predicate Factories 路由断言工厂

gateway提供了多种路由适配规则来适配多种情况

After需要指定一个ZonedDateTime类型的时间,他会匹配这个时间之后的请求,判断依据是当前收到请求的时间
predicates: # 路由条件- After=2025-09-02T13:38:51.323390200+08:00[Asia/Shanghai]
Before在这个时间之前的请求
predicates: # 路由条件- Before=2025-09-02T13:38:51.323390200+08:00[Asia/Shanghai]
Between匹配俩个时间之间的请求
predicates: # 路由条件- Between=2025-09-02T13:45:35.359524+08:00[Asia/Shanghai], 2025-09-02T13:38:51.323390200+08:00[Asia/Shanghai]
Cookie包含指定的cookie,这个cookie的key是cool v是 这个hh可以是正则表达式
predicates:- Cookie=cool, hh
Header

该请求包含指定的Header字段

且key为haha v满足\d+的正则表达式

predicates:- Header=haha, \d+
Host对请求头中的Host进行匹配
predicates:- Host=**.some.com, nlog.daxuesoutijiang.com
Method匹配请求的获取方法 Get Post  
predicates:- Method=Get,Post
Path匹配url的路径
predicates:- Path=/getServer/**
Query匹配url的查询参数? 后面的参数,需要一个param,和可选的正则表达式regexp 
?hhh=ww
predicates:- Query=hhh, ww
RemoteAddr

匹配的是请求的远程地址

192.168.0.1是ip地址,/16是子网掩码,表示

匹配的是192.168.0.1 - 192.168.255.255

predicates:- RemoteAddr=192.168.0.1/16
Weight将请求分流,如果有请求满足了weight_high和weight_low的规则,那么就会根据weight的权重来进行分配到那个服务中进行,这里是通过相同的权重key(group1)来进*行权重的划分的 
- id: weight_highuri: https://weighthigh.orgpredicates:- Weight=group1, 8
- id: weight_lowuri: https://weightlow.orgpredicates:- Weight=group1, 2

192.168.0.1这后面的.0.1拆开其实是 00000000.00000001 8为二进制,16表示从有往左的16为是网络为那么就对应的这一段地址 192.168.0.1 - 192.168.255.255

Gateway Filter Factory 网关过滤器工厂

predicate决定了请求要经过那个路由处理,如果要对请求进行加工的话就要是使用Filter了

AddRequestParameter

再url中添加字段,最终到url上是

127.0.0.1:8080/hh?hh=ww&www=hhh

这时多个参数的写法

filters:- AddRequestParameter=hh,wwAddRequestParameter=www,hhh
AddRequestHeader再请求头中添加字段h=h1
filters:- AddRequestHeader=h,h1
AddResponseHeader再响应头中添加字段
filters:- AddResponseHeader=r1,h1
RemoveRequestHeader删除请求头的某个字段
filters:- RemoveRequestHeader=del
RemoveResponseHeader删除响应头的某个字段
filters:- emoveResponseHeader=del
RequestSize限制请求的最大大小单位字节,默认5M
filters:- name: RequestSizeargs:maxSize: 50000000

Retry

若后端响应失败会重试3次,Retry还支持很多其他的参数, 比如

methord:应该初始的http方法,用org.springframework.http.HttpMethod表示

status:要重试的状态代码,org.springframework.http.HttpStatus这个类来表示的

series:要重试的状态代码系列,用 org.springframework.http.HttpStatus.Series表示

exceptions:后端抛出异常的类型要重试

还有个backoff可以去原文档看

如果使用了Retry,他的默认配置是

  • retries: 三次

  • series: 5XX系列

  • methods: GET 请求

  • exceptionsIOException 和 TimeoutException

  • backoff: disabled

filters:- name: Retryargs:retries: 3statuses: BAD_GATEWAY

RequestRateLimiter

对请求的流量进行限制,若请求被限流则会返回

HTTP 429 - Too Many Requests

使用的是令牌桶算法来限流,需要配置一个KeyResolver类型的bean,他会根据请求的类型来算出一个key,然后通过这个key来获取到一个令牌桶,所以RequestRateLimiter是通过某种规则来对同种类型(相同key)的请求进行限流,而不是全局限流

使用的时候需要加入依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency> 实现KeyResolver方法@Bean
KeyResolver ipKeyResolver() {return exchange -> {return Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());};
}

这个方法会将请求的ip当作key

filters:- name: RequestRateLimiterargs:redis-rate-limiter.burstCapacity: 20redis-rate-limiter.replenishRate: 12redis-rate-limiter.requestedTokens: 1key-resolver: "#{@ipKeyResolver}" # 这个就对应了实现的KeyResolver bean

redis-rate-limiter.replenishRate 这个代表的是每秒钟允许多少个请求,每秒钟往令牌桶中添加的令牌数

redis-rate-limiter.burstCapacity 每秒钟能允许的最大的令牌数,令牌桶的最大容量

redis-rate-limiter.requestedTokens 每次请求消耗的令牌数

这里的name表示的是要加入哪个过滤器,args中的是参数

Defualt Filters

之前设置的filter只对当前路由生效,而如果想要使Filter对所有的路由生效就可以添加

spring.cloud.gateway.default-filters属性

spring:cloud:gateway:      default-filters:- AddRequestParameter=p1,p1

GlobalFilter 全局过滤

GlobalFilter是gateway的全局过滤器,他和GatewayFilter的作用是相同的,他会应用到全局路由中,通常用于实现与安全性,性能检测,日志打印相关联的全局功能

查看GlobalFilter的监控信息

引入依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

添加一些配置文件

spring:cloud:gateway:# 开启了一些指标信息的搜集 请求计数 耗时什么的metrics:enabled: true
management:#  暴露所有 Actuator 端点 这样就鞥看到更详细的监控端口endpoints:web:exposure:include: "*"endpoint:# 更详细的健康信息health:show-details: always# 允许远程关闭服务 调用actuator/shutdown发起post请求shutdown:enabled: true

访问127.0.0.1:8080/actuator 就可以看到详细的监控信息了

当然不添加刚刚哪些配置文件也能访问

过滤器的执行顺序

当配置了global filter和gateway filter之后,网关会把他们合并到一个集合链中来以此执行,每一个过滤器都必须指定一个int值,值越小的优先级越高越先执行,filter通过实现order接口或者添加@order注解来决定int值

对于spring cloud filter的过滤器由spring来决定

用户自定义的过滤器由用户自己决定

当order的值相同时,会按照default filter -> gateway filter  -> global filter顺序执行

自定义gateway filter

要自定义filter,那么就需要实现GatewayFilterFactory接口,spring提供了一个实现了GatewayFilterFactory的抽象类,我们只需要实现过滤逻辑和优先级就好

@Service
public class CustomizeGatewayFilterFactory extends AbstractGatewayFilterFactory<CustomizeConfig> implements Ordered {public CustomizeGatewayFilterFactory() {super(CustomizeConfig.class);}@Overridepublic GatewayFilter apply(CustomizeConfig config) {return  ((exchange, chain) -> {log.info("request url" + exchange.getRequest().getURI() + "  " + config.toString());return chain.filter(exchange);}));});}@Overridepublic int getOrder() {return HIGHEST_PRECEDENCE;}
}

这个过滤器会把请求的url打印出来

如果请求通过的话,就把请求传递到下一个断言 return chain.filter(exchange)

如果不通过那么可以这样直接拒绝 return exchange.getResponse().setComplete()

也可以把通过过滤器的url打印出来

            return chain.filter(exchange).then(Mono.defer(() -> {//这样获取到的是原来的url,因为这个ServerHttpRequest是不可以修改的,要获取到最后的url需要重新获取到ServerHttpRequest对象log.info("end origin: {}", exchange.getRequest().getURI());URI routedUri = exchange.getAttribute(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR);log.info("end routed: {}", routedUri);return Mono.empty();}));

自定义 全局过滤器 glocal filter

只需要实现GlobalFilter接口就号

@Service
@Slf4j
public class CustomizeGlobalFiler implements GlobalFilter, Ordered {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {log.info(exchange.getRequest().getURI().toString());  return chain.filter(exchange);}@Overridepublic int getOrder() {return Ordered.LOWEST_PRECEDENCE;}
}

和gateway 实现很相似

end ~~

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

返利app的消息队列架构:基于RabbitMQ的异步通信与解耦实践

返利app的消息队列架构&#xff1a;基于RabbitMQ的异步通信与解耦实践 大家好&#xff0c;我是阿可&#xff0c;微赚淘客系统及省赚客APP创始人&#xff0c;是个冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 在返利app的业务流程中&#xff0c;用户下单、返利计算…

Vue3 响应式失效 debug:Proxy 陷阱导致数据更新异常的深度排查

人们眼中的天才之所以卓越非凡&#xff0c;并非天资超人一等而是付出了持续不断的努力。1万小时的锤炼是任何人从平凡变成超凡的必要条件。———— 马尔科姆格拉德威尔 &#x1f31f; Hello&#xff0c;我是Xxtaoaooo&#xff01; &#x1f308; “代码是逻辑的诗篇&#xff0…

【贪心算法】day10

&#x1f4dd;前言说明&#xff1a; 本专栏主要记录本人的贪心算法学习以及LeetCode刷题记录&#xff0c;按专题划分每题主要记录&#xff1a;&#xff08;1&#xff09;本人解法 本人屎山代码&#xff1b;&#xff08;2&#xff09;优质解法 优质代码&#xff1b;&#xff…

LeetCode算法日记 - Day 42: 岛屿数量、岛屿的最大面积

目录 1. 岛屿数量 1.1 题目解析 1.2 解法 1.3 代码实现 2. 岛屿的最大面积 2.1 题目解析 2.2 解法 2.3 代码实现 1. 岛屿数量 https://leetcode.cn/problems/number-of-islands/ 给你一个由 1&#xff08;陆地&#xff09;和 0&#xff08;水&#xff09;组成的的二维…

短波红外相机在机器视觉检测方向的应用

短波红外相机在机器视觉检测方向的应用短波红外相机&#xff1a;机器视觉的“低成本突破者”一、打破成本困局&#xff1a;短波红外的“平民化”革新二、核心技术&#xff1a;有机材料的“硬核创新”1. 材料革命&#xff1a;有机感光层的优势2. 工艺兼容&#xff1a;嫁接成熟CM…

【数据结构与算法】图 Floyd算法

相关题目&#xff1a; 1334. 阈值距离内邻居最少的城市 - 力扣&#xff08;LeetCode&#xff09; 资料 &#xff1a; Floyd算法原理及公式推导 - 知乎 Floyd 算法是一种经典的动态规划算法&#xff0c;用与求解图中所有顶点之间的最短短路路径。它由Robert Floyd 于1962…

卫星通信天线的指向精度,含义、测量和计算

卫星通信天线的指向精度&#xff0c;含义、测量和计算我们在卫星通信天线的技术规格书中&#xff0c;都会看到天线指向精度这个指标。一般来说&#xff0c;技术规格书上的天线指向精度的参数是这么写的&#xff1a;“天线指向精度≤1/10半功率波束带宽”今天这个文章&#xff0…

基于LSTM与3秒级Tick数据的金融时间序列预测实现

数据加载模块解析 def load_data(filepath):df pd.read_csv(filepath)return df该函数承担基础数据采集职责&#xff0c;通过Pandas库读取CSV格式的高频交易数据&#xff08;典型如股票分笔成交明细&#xff09;。输入参数为文件路径字符串&#xff0c;输出结构化DataFrame对象…

C# --- Field and Property

C# --- Field and Property字段 (Field) vs. 属性 (Property)Property的声明初始化方法单例类property错误初始化导致线程泄漏字段 (Field) vs. 属性 (Property) 字段 (Field) - 数据的存储容器 字段是直接在类或结构中声明的变量。它是存储数据的地方&#xff0c;是对象状态的…

【Python】实现一个文件夹快照与比较工具

1. 工具简介 在日常开发、项目管理或备份场景中&#xff0c;我们经常需要知道某个文件夹中的文件是否发生变化&#xff0c;例如&#xff1a; 项目源码是否新增或修改文件&#xff1f;数据集是否被不小心删除或篡改&#xff1f;备份文件夹是否和上次一致&#xff1f; 本教程将教…

LINUX913 shell:set ip [lindex $argv 0],\r,send_user,spawn ssh root@ip “cat “

问题 获取公钥 [codesamba ~]$ cat pub.sh #!/bin/usr/expect set ip "$1" set password 123456 set timeout 20 spawn ssh root192.168.235.100:cat ~/.ssh/id_rsa.pub expect { "yes/no" {send "yes/r";exp_continue} "password:" {…

Acwing算法基础课--链表

一、单链表 AcWing 826. 单链表 代码 N 100010 idx 0 e [0] * N ne [0] * N head -1def init():global idx,headidx 0head -1def add_head(x):global idx,heade[idx] xne[idx] headhead idxidx 1def delete(k):ne[k] ne[ne[k]]def add_k(k,x):global idxe[idx] …

AI表征了西方的有界,AI+体现了东方的无界

AI表征了西方的有界&#xff0c;AI体现了东方的无界&#xff0c;试图通过文化差异的视角来对比传统AI&#xff08;AI&#xff09;与增强型或融合型AI&#xff08;AI&#xff09;的特征。一、“AI表征了西方的有界”西方的“有界”可以理解为&#xff1a;1、逻辑清晰、结构严谨&…

LabVIEW泵轮检测

​在现代制造业蓬勃发展的浪潮下&#xff0c;汽车行业也迎来了高速发展期。液力变矩器作为实现车辆自动变速的关键零件产品&#xff0c;在汽车动力系统中扮演着不可或缺的角色。泵轮作为液力变矩器的核心组成部分&#xff0c;其生产质量直接影响着液力变矩器的性能。因此&#…

RT-DETRv2 中的坐标回归机制深度解析:为什么用 `sigmoid(inv_sigmoid(ref) + delta)` 而不是除以图像尺寸?

引言&#xff1a;一个看似简单的公式&#xff0c;背后藏着工业级设计智慧 在阅读 RT-DETRv2&#xff08;Real-Time DETR v2&#xff09;源码时&#xff0c;我曾被一行代码深深震撼&#xff1a; inter_ref_bbox F.sigmoid(bbox_head[i](output) inverse_sigmoid(ref_points_de…

简单了解一下GraphRAG

传统RAG的缺点 当我们将一段文本信息以句子分割后&#xff0c;存入到向量数据库中。用户提问“老王喜欢吃什么”&#xff0c;这个问题会与向量数据库中的许多句子关联性比较强&#xff0c;能返回准确且具体的信息。 但是&#xff0c;若是问题换成“出现了几次西瓜”&#xff0c…

HTTP 状态码背后的逻辑:从请求到响应的完整流程解析(含完整流程图)

在日常的 Web 开发与 API 调试中&#xff0c;我们经常会遇到各种 HTTP 状态码 ——404 Not Found、401 Unauthorized、500 Internal Server Error... 这些数字背后并非随机出现&#xff0c;而是服务器处理请求过程中不同阶段的 "反馈信号"。理解这些状态码的触发逻辑…

Vue:下拉框多选影响行高

目录 一、 出现场景二、 解决方案 一、 出现场景 在使用el-select增加multiple属性进行多选时&#xff0c;会出现高度塌陷的情况 二、 解决方案 首先需要在el-select中增加collapse-tags属性&#xff0c;并在style中增加如下样式 方案一 <style scoped> ::v-deep .e…

如何在高通跃龙QCS6490 Arm架构上使用Windows 11 IoT企业版?

1.简介研华已将高通跃龙QCS6490 技术应用于嵌入式模块、单板电脑和AI摄像头等各种规格的嵌入式硬件中。QCS6490平台支持全面的操作系统生态系统&#xff0c;包括Windows、Ubuntu、Yocto和 Android。Windows 11 IoT企业版是微软新一代的物联网操作系统&#xff0c;具有更强的安全…

阿里云国际代理:如何利用RDS构建高可用、可扩展的数据库架构

讲下云数据库RDS案例解析&#xff0c;若在上云或用云过程中有不懂的&#xff0c;可寻云枢国际yunshuguoji助力免卡上云用云。1、RDS MySQL数据库代理支持读写分离、连接保持、就近访问、事务拆分、连接池、SSL加密等功能&#xff0c;能够降低主实例负载&#xff0c;提高实例可用…