Spring Cloud融合gateway自带GatewayFilter使用 | Spring Cloud 15

news2024/9/25 1:15:08

一、Spring Cloud Gateway内置GatewayFilter

路由过滤器允许以某种方式修改传入的 HTTP 请求或传出的 HTTP 响应路由过滤器的范围是特定路由Spring Cloud Gateway 包括许多内置的 GatewayFilter 工厂。

官网地址:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#gatewayfilter-factories

过滤器工厂作用参数
AddRequestHeader为原始请求添加HeaderHeader的名称及值
AddRequestParameter为原始请求添加请求参数参数名称及值
AddResponseHeader为原始响应添加HeaderHeader的名称及值
DedupeResponseHeader剔除响应头中重复的值需要去重的Header名称及去重策略
Hystrix为路由引入Hystrix的断路器保护HystrixCommand的名称
FallbackHeaders为fallbackUri的请求头中添加具体的异常信息Header的名称
PrefixPath为原始请求路径添加前缀前缀路径
PreserveHostHeader为请求添加一个preserveHostHeader=true 的属性,路由过滤器会检查该属性以决定是否要发送原始的Host
RequestRateLimiter用于对请求限流,限流算法为令牌桶keyResolver、rateLimiter、statusCode、denyEmptyKey、emptyKeyStatus
RedirectTo将原始请求重定向到指定的URLhttp状态码及重定向的url
RemoveHopByHopHeadersFilter为原始请求删除IETF组织规定的一系列Header默认就会启用,可以通过配置指定仅删除哪些Header
RemoveRequestHeader为原始请求删除某个HeaderHeader名称
RemoveResponseHeader为原始响应删除某个HeaderHeader名称
RewritePath重写原始的请求路径原始路径正则表达式以及重写后路径的正则表达式
RewriteResponseHeader重写原始响应中的某个HeaderHeader名称、值的正则表达式,重写后的值
SaveSession在转发请求之前,强制执行WebSession::save操作
secureHeaders为原始响应添加一系列起安全作用的响应头无,支持修改这些安全响应头的值
SetPath修改原始的请求路径修改后的路径
SetResponseHeader修改原始响应中某个Header的值Header名称,修改后的值
SetStatus修改原始响应的状态码HTTP 状态码,可以是数字,也可以是字符串
StripPrefix用于截断原始请求的路径使用数字表示要截断的路径的数量
Retry针对不同的响应进行重试retries、statuses、methods、series
RequestSize设置允许接收最大请求包的大 小。如果请求包大小超过设置的值,则返回 413 Payload Too Large请求包大小,单位为字节,默认值为5M
ModifyRequestBody在转发请求之前修改原始请求体内容修改后的请求体内容
ModifyResponseBody修改原始响应体的内容修改后的响应体内容

二、DefaultFilter

添加DefaultFilter将其应用于所有路由,您可以使用spring.cloud.gateway.default-filters,此属性配置采用DefaultFilter列表。

spring:
  cloud:
    gateway:
      default-filters:
      - AddResponseHeader=X-Response-Default-Red, Default-Blue
      - StripPrefix=1

三、GlobalFilter

GlobalFilter接口与GatewayFilter接口具有相同特征。GlobalFilter是有条件地应用于所有路由的特殊过滤器。

Spring Cloud Gateway 内置的GatewayFilter
在这里插入图片描述
更多介绍请见官网:https://docs.spring.io/spring-cloud-gateway/docs/current/reference/html/#global-filters

以下为自定义GlobalFilter实现记录请求方状态及耗时:

ApiLoggingFilter.java

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.List;

@Slf4j
public class ApiLoggingFilter implements GlobalFilter, Ordered {

	private static final String START_TIME = "startTime";

	private static final String X_REAL_IP = "X-Real-IP";// nginx需要配置

	@Override
	public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
		if (log.isDebugEnabled()) {
			String info = String.format("Method:{%s} Host:{%s} Path:{%s} Query:{%s}",
					exchange.getRequest().getMethod().name(), exchange.getRequest().getURI().getHost(),
					exchange.getRequest().getURI().getPath(), exchange.getRequest().getQueryParams());
			log.debug(info);
		}
		exchange.getAttributes().put(START_TIME, System.currentTimeMillis());
		return chain.filter(exchange).then(Mono.fromRunnable(() -> {
			Long startTime = exchange.getAttribute(START_TIME);
			if (startTime != null) {
				Long executeTime = (System.currentTimeMillis() - startTime);
				List<String> ips = exchange.getRequest().getHeaders().get(X_REAL_IP);
				String ip = ips != null ? ips.get(0) : exchange.getRequest().getRemoteAddress().getAddress().getHostAddress();
				String api = exchange.getRequest().getURI().getRawPath();

				int code = 500;
				if (exchange.getResponse().getStatusCode() != null) {
					code = exchange.getResponse().getStatusCode().value();
				}
				// 当前仅记录日志,后续可以添加日志队列,来过滤请求慢的接口
				if (log.isDebugEnabled()) {
					log.debug("来自IP地址:{}的请求接口:{},响应状态码:{},请求耗时:{}ms", ip, api, code, executeTime);
				}
			}
		}));
	}

	@Override
	public int getOrder() {
		return Ordered.LOWEST_PRECEDENCE;
	}

}

配置使用ApiLoggingFilter

GatewayConfiguration.java

@Configuration(proxyBeanMethods = false)
public class GatewayConfiguration {

    @Bean
    public ApiLoggingFilter apiLoggingFilter() {
        return new ApiLoggingFilter();
    }
}

四、过滤器的执行顺序

请求进入网关会碰到三类过滤器:当前路由的过滤器DefaultFilterGlobalFilter

请求路由后,会将 当前路由过滤器DefaultFilterGlobalFilter,合并到一个过滤器链(集合)中,按org.springframework.core.Ordered接口排序,排序后依次执行每个过滤器

在这里插入图片描述
排序的规则是什么呢?

  • 每一个过滤器都必须指定一个int类型的order值,order值越小,优先级越高,执行顺序越靠前。
  • GlobalFilter通过实现Ordered接口,或者添加@Order注解来指定order值,由我们自己指定。
  • 路由过滤器defaultFilterorderSpring指定,默认是按照声明顺序从1递增。
  • 当过滤器的order值一样时,会按照 defaultFilter > 路由过滤器 > GlobalFilter的顺序执行。
  • 传入的 HTTP 请求第一个过滤器具有最高优先级。
  • 传出的 HTTP 响应最后一个过滤器具有最高优先级。

详细内容,可以查看源码:

org.springframework.cloud.gateway.route.RouteDefinitionRouteLocator#getFilters()方法是先加载defaultFilters,然后再加载某个routefilters,然后合并。

private List<GatewayFilter> getFilters(RouteDefinition routeDefinition) {
    List<GatewayFilter> filters = new ArrayList();
    if (!this.gatewayProperties.getDefaultFilters().isEmpty()) {
        filters.addAll(this.loadGatewayFilters(routeDefinition.getId(), new ArrayList(this.gatewayProperties.getDefaultFilters())));
    }

    if (!routeDefinition.getFilters().isEmpty()) {
        filters.addAll(this.loadGatewayFilters(routeDefinition.getId(), new ArrayList(routeDefinition.getFilters())));
    }

    AnnotationAwareOrderComparator.sort(filters);
    return filters;
}

org.springframework.cloud.gateway.handler.FilteringWebHandler#handle()方法会加载全局过滤器,与前面的过滤器合并后根据order排序,组织过滤器链。

public Mono<Void> handle(ServerWebExchange exchange) {
    Route route = (Route)exchange.getRequiredAttribute(ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR);
    List<GatewayFilter> gatewayFilters = route.getFilters();
    List<GatewayFilter> combined = new ArrayList(this.globalFilters);
    combined.addAll(gatewayFilters);
    AnnotationAwareOrderComparator.sort(combined);
    if (logger.isDebugEnabled()) {
        logger.debug("Sorted gatewayFilterFactories: " + combined);
    }

    return (new DefaultGatewayFilterChain(combined)).filter(exchange);
}

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

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

相关文章

MATLAB与图像处理的那点小事儿~

目录 一、学习内容 二、matlab基本知识 三、线性点运算 四、非线性点运算&#xff0c;伽马矫正 五、直方图 1、直方图均衡化 &#xff08;1&#xff09;使用histep函数实现图像均衡化 &#xff08;2&#xff09;使用自行编写的均衡化函数实现图像均衡化 2、直方图规定…

Ansys Zemax | 如何使用 OpticStudio 非序列优化向导

本文描述了如何使用 OpticStudio 非序列优化向导创建常见的评价函数类型&#xff0c;以及创建用于匹配导入图像文件的目标能量分布评价函数。&#xff08;联系我们获取文章附件&#xff09; 简介 在非序列模式下优化光学系统通常比在序列模式下的优化更复杂、更耗时。下期我们…

TencentOS tiny 移植到STM32F103教程

一、移植前的准备工作1. STM32的裸机工程模板这个可以自己创建&#xff08;创建过程参考之前的STM32裸机工程也有工程网盘在上面&#xff09;2.下载TencentOS tiny 源码TencentOS tiny的源码可从TencentOS tiny GitHub仓库地址https://github.com/Tencent/TencentOS-tiny下载&a…

无人机动力测试台:150kg级-Flight Stand 150

“飞行汽车”被人们广泛视为下一代交通工具。从2022年初至今&#xff0c;eVTOL&#xff08;电动垂直起降飞行器&#xff09;产业乃至整个UAM&#xff08;城市间空中交通&#xff09;市场呈现爆发式增长——各国航空制造企业纷纷入局&#xff0c;不断有新产品问世、试飞或试运行…

吐血整理,web自动化测试,POM模式搭建自动化测试框架(超级详细)

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 POM设计模式 主要是…

IO多路复用(select、poll、epoll网络编程)

目录一、高级IO相关1.1 同步通信和异步通信1.2 阻塞与非阻塞1.3 fcntl 函数二、五种IO模型2.1 阻塞式IO模型2.2 非阻塞式IO模型2.3 多路复用IO模型2.4 信号驱动式IO模型2.5 异步IO模型三、认识IO多路复用四、select4.1 认识select函数4.2 select函数原型4.3 select网络编程4.4 …

脂肪毒性的新兴调节剂——肠道微生物组

谷禾健康 肠道微生物组与脂质代谢&#xff1a;超越关联 脂质在细胞信号转导中起着至关重要的作用&#xff0c;有助于细胞膜的结构完整性&#xff0c;并调节能量代谢。 肠道微生物组通过从头生物合成和对宿主和膳食底物的修饰产生了大量的小分子。 最近的研究表明&#xff0c;由…

[计算机操作系统(第四版 汤小丹 汤子瀛)]第一章 操作系统引论(学习复习笔记)

操作系统&#xff08;Operating System&#xff0c;OS&#xff09;是配置在计算机硬件上的第一层软件&#xff0c;是对硬件系统的首次扩充。操作系统的主要作用&#xff1a; 管理硬件设备&#xff0c;提高他们的利用率和系统吞吐量 利用率&#xff1a;使硬件充分忙碌系统吞吐量…

MQTT协议-心跳请求和心跳响应

MQTT协议-心跳请求和心跳响应 心跳请求是客户端发送给服务器的&#xff0c;心跳响应是服务器回应给客户端的 作用是保持客户端与服务器之间的连接 CONNECT报文的可变报头是由协议名&#xff08;Procotol Name&#xff09;协议级别&#xff08;Procotol Level&#xff09;连接…

冰刃杀毒工具使用实验(29)

实验目的 &#xff08;1&#xff09;学习冰刃的基本功能&#xff1b; &#xff08;2&#xff09;掌握冰刃的基本使用方法&#xff1b;预备知识 windows操作系统的基本知识&#xff0c;例如&#xff1a;进程、网络、服务和文件等的了解。 冰刃是一款广受好评的ARK工…

MYSQL 中 ROW_NUMBER 的实现

由于mysql没有 row_number函数实现&#xff0c;然后我们后台表里没给可以排序的字段&#xff0c;考虑用mysql实现一个row_number, 由于想使用视图进行实时展示&#xff0c;但是row_number在视图中不生效&#xff0c;所有我们最后还是找了后台程序伙伴沟通加了排序字段。 row_nu…

MySQL的图形化界面开发工具DataGrip的下载安装

在日常的开发中&#xff0c;会借助于MySQL的图形化界面&#xff0c;来简化开发&#xff0c;提高开发效率。目前mysql主流的图形化界面工具&#xff0c;有Navicat、SQLyog、DataGrip等&#xff0c;最后一种DataGrip&#xff0c;这种图形化界面工具&#xff0c;功能更加强大&…

Android Framework-管理Activity和组件运行状态的系统进程—— ActivityManagerService(AMS)

ActivityManagerService&#xff08;AMS&#xff09;是Android提供的一个用于管理Activity&#xff08;和其他组件&#xff09;运行状态的系统进程 AMS功能概述 和WMS一样&#xff0c;AMS也是寄存于systemServer中的。它会在系统启动时&#xff0c;创建一个线程来循环处理客户…

uni-app中使用vue3语法详解

全局创建 app.use(createPina()).mount 全局方法 通过app.config.globalProperties.xxx可以创建 这里我们写了一个字符串翻转的全局方法 main.js里面添加一个全局方法 不要忘了加$ 否则会报错 // #ifdef VUE3 //导入创建app import { createSSRApp } from vue //导入创建ap…

数据结构刷题(二十一):131分割回文串、78子集

1.分割回文串题目链接思路&#xff1a;回溯算法的组合方法&#xff08;分割问题类似组合问题&#xff09;。流程图&#xff1a;红色竖杠就是startIndex。 for循环是横向走&#xff0c;递归是纵向走。回溯三部曲&#xff1a;递归函数参数&#xff1a;字符串s和startIndex&#…

Vue(10-20)

1Vue赋值方式 Object.defineProperty <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" conten…

如何从Outlook向Teams共享电子邮件

从 Outlook 或 web 上的 Outlook,你可以将电子邮件共享到Teams中的聊天和频道。 注意: 你必须具有“共享到Teams”的Outlook”加载项。它为Teams用户自动安装。此外,移动设备当前不支持该功能。外接程序当前不支持共享邮箱。如果你安装了Teams桌面客户端,并且使用的是Outl…

精、稳、敏、融,步入人民金融时代 | 易观银行业数字化转型年度趋势报告

易观分析&#xff1a;2022年&#xff0c;在深化金融供给侧结构性改革和高质量增长要求的指引下&#xff0c;赋能实体、公平普惠、审慎经营成为银行业转型发展的关键词。一方面面临内外部复杂的经济环境和不确定性风险&#xff0c;银行主打稳健策略&#xff0c;数字化转型仍在持…

软件测试用例篇(5)

测试是否运行代码去划分&#xff1f; 1)静态测试: 不运行代码&#xff0c;检查代码的风格&#xff0c;格式是否符合公司的标准规范&#xff0c;检查代码的逻辑结构是否满足需求要实现的功能 看代码&#xff0c;不运行代码&#xff0c;通过静态分析代码的语法&#xff0c;编写规…

谷歌Google Pixel6Pro/7pro手机刷入ROOT权限-开通Volte+破解5G网络高速刷机教程

谷歌pixel6和pixel7系列&#xff0c;出厂并不带volte功能&#xff0c;也不支持完美的5G效果&#xff0c;对于我们这种身处大陆&#xff0c;又想体验高清通话的小伙伴来说&#xff0c;并不友好&#xff0c;所以第三方破解实现就显得非常重要了。通过实际测试&#xff0c;两款机型…