SpringColoud GateWay 核心组件
优质博文:IT-BLOG-CN
【1】Route
路由: Gateway
的基本构建模块,它由ID
、目标URL
、断言集合和过滤器集合组成。如果聚合断言结果为真,则匹配到该路由。
Route
路由-动态路由实现原理: 配置变化Apollo
+ 服务地址实例变化Nacos
。Spring Cloud Gateway
通过RouteDefinitionLocator
和RouteRefreshListener
等组件实现动态路由。
先看下配置信息,方便后面原理的理解:SpringCloudGateway bootstrap.yml
的配置如下:
spring:application:name: gateway-servicecloud:nacos:discovery:server-addr: ${NACOS_SERVER_ADDR:localhost:8848}apollo:bootstrap:enabled: truemeta: ${APOLLO_META:localhost:8080}
application.yml
的配置如下:
spring:cloud:gateway:discovery:locator:enabled: truelower-case-service-id: true
apollo:bootstrap:namespaces: application # 1、登录 Apollo 控制台。 2、创建一个新的配置,例如 application.yml。 3、内容就是上看配置的SpringCloud Gateway 配置的路由信息
1、RouteDefinitionLocator
:Spring Cloud Gateway
启动时,会通过RouteDefinitionLocator
从Apollo
加载初始的路由定义。
2、DiscoveryClientRouteDefinitionLocator
:使用Nacos
进行服务发现,从Nacos
获取动态路由定义。
3、RouteDefinitionRepository
:加载的路由定义会存储在RouteDefinitionRepository
中,供后续路由匹配使用。
4、RouteRefreshListener
:监听路由定义的变化事件(如配置更新、服务实例变化等)。当监听到路由定义变化事件时,触发路由刷新操作,更新网关的路由规则,重新加载并应用新的路由配置。
GatewayHandlerMapping
根据预先配置的路由信息和请求的属性(如路径、方法、头部信息等)来确定哪个路由与请求匹配。它使用谓词Predicates
来进行匹配判断。
【2】Predicate
断言: 这是一个Java 8 Function Predicate
。输入类型是Spring Framework ServerWebExchange
。允许开发人员匹配来自HTTP
请求的任何内容,例如Header
或参数。Predicate
接受一个输入参数,返回一个布尔值结果。Spring Cloud Gateway
内置了许多Predict
,这些Predict
的源码在org.springframework.cloud.gateway.handler.predicate
包中,如果读者有兴趣可以阅读一下。现在列举各种 Predicate如下图:
在上图中,有很多类型的Predicate
,比如说时间类型的 Predicated
[AfterRoutePredicateFactory BeforeRoutePredicateFactory BetweenRoutePredicateFactory
],当只有满足特定时间要求的请求会进入到此Predicate
中,并交由Router
处理;Cookie
类型的CookieRoutePredicateFactory
,指定的Cookie
满足正则匹配,才会进入此Router
。以及host
、method
、path
、querparam
、remoteaddr
类型的Predicate
,每一种Predicate
都会对当前的客户端请求进行判断,是否满足当前的要求,如果满足则交给当前请求处理。如果有很多个Predicate
,并且一个请求满足多个Predicate
,则按照配置的顺序第一个生效。
Predicate 断言配置:
server:port: 8080
spring:application:name: api-gatewaycloud:gateway:routes:- id: gateway-serviceuri: https://www.baidu.comorder: 0predicates:- After=2017-01-20T17:42:47.789-07:00[America/Denver]- Host=**.foo.org- Path=/headers- Method=GET- Header=X-Request-Id, \d+- Query=foo, ba.- Query=baz- Cookie=chocolate, ch.p
在上面的配置文件中,配置了服务的端口为8080
,配置spring cloud gateway
相关的配置,id
标签配置的是router
的id
,每个router
都需要一个唯一的id
,uri
配置的是将请求路由到哪里,本案例全部路由到https://www.baidu.com
。
Predicates
: After=2017-01-20T17:42:47.789-07:00[America/Denver]
会被解析成PredicateDefinition
对象name =After ,args= 2017-01-20T17:42:47.789-07:00[America/Denver]
。需要注意的是Predicates
的After
这个配置,遵循契约大于配置的思想,它实际被 AfterRoutePredicateFactory
这个类所处理,这个After
就是指定了它的Gateway web handler
类为AfterRoutePredicateFactory
,同理,其他类型的Predicate
也遵循这个规则。当请求的时间在这个配置的时间之后,请求会被路由到指定的URL
。跟时间相关的Predicates
还有 Before Route Predicate Factory
、Between Route Predicate Factory
,读者可以自行查阅官方文档,再次不再演示。
Query=baz
: Query
的值以键值对的方式进行配置,这样在请求过来时会对属性值和正则进行匹配,匹配上才会走路由。经过测试发现只要请求汇总带有baz
参数即会匹配路由[localhost:8080?baz=x&id=2
],不带baz
参数则不会匹配。
Query=foo, ba.
:这样只要当请求中包含foo
属性并且参数值是以 ba
开头的长度为三位的字符串才会进行匹配和路由。使用curl
测试,命令行输入:curl localhost:8080?foo=bab
测试可以返回页面代码,将foo
的属性值改为babx
再次访问就会报404
,证明路由需要匹配正则表达式才会进行路由。
Header=X-Request-Id
, \d+
:使用curl
测试,命令行输入:curl http://localhost:8080 -H "X-Request-Id:88"
则返回页面代码证明匹配成功。将参数-H "X-Request-Id:88"改为-H "X-Request-Id:spring"
再次执行时返回404
证明没有匹配。
【3】Filter
过滤器:方案一:写死在代码中
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {return builder.routes()//openapi路由转发.route("openapi_route", p -> p.path( "/openapi/**").filters(f->f.removeRequestHeader("Expect")).uri("lb://order-openapi-service")).build();
}
方案二:配置文件yml
# gateway 的配置形式routes:- id: order-service #路由ID,没有规定规则但要求唯一,建议配合服务名。uri: lb://order-servicepredicates:- Path=/order/**filters:- ValidateCodeGatewayFilter
Filter
过滤器:Filter
按处理顺序Pre Filter / Post Filter
Filter
按作用范围分为: GlobalFilter
全局过滤器。GatewayFilter
指定路由的过滤器。
Filter
过滤器-扩展自定义Filter
: Filter
支持通过spi
扩展。实现GatewayFilter
,Ordered
接口。
Filter
方法: 过滤器处理逻辑。getOrder
:定义优先级,值越大优先级越低。
过滤器的名称只需要写前缀,过滤器命名必须是
xxxGatewayFilterFactory
(包括自定义)。
全局过滤器示例: 创建一个全局过滤器类,这也是一个前置过滤器,实现GlobalFilter
接口:
public class TokenFilter implements GlobalFilter, Ordered {Logger logger=LoggerFactory.getLogger( TokenFilter.class );@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {String token = exchange.getRequest().getQueryParams().getFirst("token");if (token == null || token.isEmpty()) {logger.info( "token is empty..." );exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);return exchange.getResponse().setComplete();}return chain.filter(exchange); // 先执行业务逻辑,在执行exchange,是前置过滤器}@Overridepublic int getOrder() {// // 过滤器的执行顺序,值越小优先级越高return -100;}
}
自定义路由过滤器示例: 创建自定义的路由过滤器,可以实现GatewayFilter
接口:
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;@Component
public class MyCustomFilter extends AbstractGatewayFilterFactory<MyCustomFilter.Config> {public MyCustomFilter() {super(Config.class);}@Overridepublic GatewayFilter apply(Config config) {return (exchange, chain) -> {// 前置过滤逻辑System.out.println("Custom Pre Filter executed");return chain.filter(exchange).then(Mono.fromRunnable(() -> { // 限制性exchange再执行过滤器业务逻辑,是后期处理器。// 后置过滤逻辑System.out.println("Custom Post Filter executed");}));};}public static class Config {// 配置属性}
}
在配置文件中使用自定义过滤器:
spring:cloud:gateway:routes:- id: my_routeuri: http://httpbin.org:80predicates:- Path=/getfilters:- name: MyCustomFilter
相关文章:

SpringColoud GateWay 核心组件
优质博文:IT-BLOG-CN 【1】Route路由: Gateway的基本构建模块,它由ID、目标URL、断言集合和过滤器集合组成。如果聚合断言结果为真,则匹配到该路由。 Route路由-动态路由实现原理: 配置变化Apollo 服务地址实例变化…...

5.计算机网络_抓包工具wireshark
安装 Linux中安装wireshark: sudo apt-get install wireshark Linux中执行wireshark: sudo wireshark 使用 注意:只有与外网交互的数据才可以被wireshark抓到,本机回环的数据不会被抓到 实验内容: 使用nc命令…...

基于Java的车辆管理系统的设计与实现-计算机毕业设计源码41727
摘要 信息化社会内需要与之针对性的信息获取途径,但是途径的扩展基本上为人们所努力的方向,由于站在的角度存在偏差,人们经常能够获得不同类型信息,这也是技术最为难以攻克的课题。针对车辆管理系统等问题,对车辆管理…...

在软件开发中低耦合和高内聚是什么,如何实现,请看文章
软件开发中,“低耦合”和“高内聚”是设计原则,用于提高系统的可维护性、可扩展性和可重用性。下面我会详细解释这两个概念及其带来的好处和规避的坏处。 低耦合(Low Coupling) 定义: 低耦合指的是模块之间的依赖关系…...

关于MyBatis-Plus 提供Wrappers.lambdaQuery()的方法
实例: private LambdaQueryWrapper<XXX> buildQueryWrapper(XXXBo bo) { Map<String, Object> params bo.getParams(); LambdaQueryWrapper<XXX> lqw Wrappers.lambdaQuery(); lqw.eq(bo.getOrgId() ! null, XXX::getOrgId, bo.getOrgId()); lq…...

C++——vector的了解与使用
目录 引言 vector容器的基本概念 1.功能 2.动态大小 3.动态扩展 vector的接口 1.vector的迭代器 2.vector的初始化与销毁 3.vector的容量操作 3.1 有效长度和容量大小 (1)使用示例 (2)扩容机制 3.2 有效长度和容量操作 (1)reserve (2)resize 4.vector的访问操作…...

Ubuntu设置静态IP地址
Ubuntu如果是最小安装,没有图形界面,需要配置静态IP,该怎么操作呢? Netplan 是最新版 Ubuntu 的默认网络管理工具。Netplan 的配置文件使用 YAML 编写,扩展名为 .yaml。 注意:配置文件中的空格是语法的一部…...

力扣349.两个数组的交集
题目链接:349. 两个数组的交集 - 力扣(LeetCode) 给定两个数组 nums1 和 nums2 ,返回 它们的 交集。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。 示例 1: 输入:nums1 [1,2,…...

FreeRTOS - 软件定时器
在学习FreeRTOS过程中,结合韦东山-FreeRTOS手册和视频、野火-FreeRTOS内核实现与应用开发、及网上查找的其他资源,整理了该篇文章。如有内容理解不正确之处,欢迎大家指出,共同进步。 1. 软件定时器 软件定时器也可以完成两类事情…...

Python的Atlassian第三方库的详细介绍
atlassian-python-api 是一个用于与 Atlassian 生态系统进行交互的 Python 库,支持与多种 Atlassian 工具(如 Jira、Confluence、Bitbucket 等)进行 API 调用。它简化了 REST API 的调用,提供了高层次的抽象,方便开发者…...

Java中的基本循环结构详解
在Java编程中,循环是控制流的重要组成部分,用于重复执行一段代码。Java提供了三种基本的循环结构:for循环、while循环和do-while循环。本文将详细介绍这三种循环的语法和使用场景,并通过示例代码展示其应用。 一,for …...

关于Git Bash中如何定义alias
一、在一次临时Bash会话中使用alias 在Bash中直接输入alias xxdddd,xx为对应要执行的命令的缩写,dddd为要执行的命令,如alias ddcd /d,输入完成后,在Bash中输入dd,即可切换至D盘。 此种设置方式ÿ…...

luckfox1106初次使用
luckfox1106初次使用 下载rk驱动 https://files.luckfox.com/wiki/Luckfox-Pico/Software/DriverAssitant_v5.12.zip 安装驱动 SD 卡烧录工具 https://files.luckfox.com/wiki/Luckfox-Pico/Software/SocToolKit_v1.98_20240705_01_win.zip 右键以管理员方式运行...

ab命令深入解析:ApacheBench性能测试工具
软考鸭微信小程序 学软考,来软考鸭! 提供软考免费软考讲解视频、题库、软考试题、软考模考、软考查分、软考咨询等服务 引言 在Web开发和运维领域,性能测试是评估服务器和应用性能的重要手段。ApacheBench(简称ab)是Apache HTTP服务器自带的…...

VSCode创建VUE项目(二)前端登录页面
一.创建登录页面 代码: <template><div class"login-container dis-h"><div class"login-form dis-h"><div class"dis-v left"><span> 欢迎~ </span><span> VUE 新世界 </span>&l…...

centos 8.4学习小结
1.权限委派 2.vim快捷方式 2.1非正常关闭文本处理方式 2.2快捷方式 2.3TAB键补齐安装包 [ rootcloud Packages]# rpm -ivh bash-completion-2.7-5.el8.noarch.rpm 2.4#history 查询历史记录 [rootcloud ~]# vim /etc/profile HISTSIZE1000(默认保存1000条历史记…...

AI 设计工具合集
🐣个人主页 可惜已不在 🐤这篇在这个专栏AI_可惜已不在的博客-CSDN博客 🐥有用的话就留下一个三连吧😼 前言: AI 视频,科技与艺术的精彩融合。它借助先进的人工智能技术,为影像创作带来全新可能。本书…...

mac 源代码安装openresty
1. clone源代码 git clone https://github.com/openresty/openresty.git 2. 安装依赖包 brew install hg unix2dos brew install pcre openssl 3. 编译 make 4. 安装openresty cd openresty-1.27.1.1 ./configure --prefix/opt/openresty --with-http_ssl_module --with-…...

人工智能和机器学习之线性代数(二)
人工智能和机器学习之线性代数(二) 本文Linear Algebra 101 for AI/ML – Part 2将通过介绍向量的点积(dot Product)、Embedding及其在相似性搜索中的应用来建立这些基础知识。 将学习Embedding,Embedding是表示概念、对象和想法的特殊类型的向量。Embedding在整个…...

Postman中的form-data 和 JSON 的区别
在使用 Postman 进行 API 测试时,form-data 和 JSON 是两种常用的请求体格式,它们有以下几个主要区别: 1. 数据格式 form-data: 主要用于表单数据的提交,适合文件上传和键值对的数据传递。数据以键值对的形式编码,类似…...

网络安全基础知识点_网络安全知识基础知识篇
文章目录 一、网络安全概述1.1 定义1.2 信息安全特性1.3 网络安全的威胁1.4 网络安全的特征 二、入侵方式2.1 黑客2.1.1 入侵方法2.1.2 系统的威胁2.2 IP欺骗与防范2.2.1 TCP等IP欺骗基础知识2.2.2 IP欺骗可行的原因2.2.3 IP欺骗过程2.2.4 IP欺骗原理2.2.5 IP欺骗防范2.3 Sniff…...

Vue.js 从入门到精通:全面解析组件化、路由与状态管理(附 Todo 案例)
在当今的前端开发领域,Vue.js 以其简洁、高效和灵活的特点受到了广泛的关注和应用。本文将带你从 Vue 的基础知识入手,逐步深入到高级特性,让你对 Vue 有一个全面的了解,并通过实际案例帮助你更好地掌握 Vue 的开发。 一、Vue 简…...

AI Weekly#1:过去一周重要的AI资讯汇总
🚀热点头条 诺贝尔奖青睐AI领域:2024年诺贝尔物理学奖和化学奖均授予了与人工智能相关的研究。物理学奖颁发给了约翰霍普菲尔德和杰弗里辛顿,表彰他们在机器学习领域的开创性工作。化学奖则授予了大卫贝克、德米斯哈萨比斯和约翰江珀…...

图论刷题
卡码网 98. 所有可达路径 使用邻接矩阵存储: #include<iostream> #include<vector> using namespace std;vector<vector<int>>res;//收集符合条件的路径vector<int>path;//0节点到终点的路径//确定递归函数 参数和返回值void dfs(c…...

ICM20948 DMP代码详解(85)
接前一篇文章:ICM20948 DMP代码详解(84) 上一回解析了inv_icm20948_ctrl_enable_sensor函数的大部分代码,只剩下一行代码没有解析。为了便于理解和回顾,再次贴出inv_icm20948_ctrl_enable_sensor函数源码,在EMD-Core\sources\Invn\Devices\Drivers\ICM20948\Icm20948Data…...

深入解析:Linux tcpdump命令在网络流量分析中的实战应用
tcpdump是一个强大的命令行工具,用于捕获和分析TCP、UDP、ICMP等协议的网络流量。 功能与用途 捕获网络流量:tcpdump可以捕获和显示来自本地计算机或通过网络传输的数据包,提供有关数据包的详细信息,如源和目的IP地址、端口号、…...

Java集合常见知识总结(上)
Java 集合概览 Java 集合,也叫作容器,主要是由两大接口派生而来:一个是 Collection接口,主要用于存放单一元素;另一个是 Map 接口,主要用于存放键值对。对于Collection 接口,下面又有三个主要的…...

【算法】力扣:K个一组反转链表
前置知识 数据结构-链表反转部分链表算法题的手写栈使用 难度: 初阶:使用容器, 难度中等。进阶:纯coding修改指针 ,难度中等,虽然leetcode是困难题。不过更加注重细节。 题目:反转 k 组中的…...

Matlab报错——错误使用 vertcat
错误提示: 原因: 这个错误表明 segment_lengths 的维度和 0 不一致。在 MATLAB 中,有时,diff 函数的输出可能是行向量,而segment_lengths 应该是一个列向量才能与 0 正确连接。 解决方法: 使用转置操作 …...

【如何获取股票数据10】Python、Java等多种主流语言实例演示获取股票行情api接口之沪深A股历史分时KDJ数据获取实例演示及接口API说明文档
最近一两年内,股票量化分析逐渐成为热门话题。而从事这一领域工作的第一步,就是获取全面且准确的股票数据。因为无论是实时交易数据、历史交易记录、财务数据还是基本面信息,这些数据都是我们进行量化分析时不可或缺的宝贵资源。我们的主要任…...