gateway基本配置

news2024/11/15 20:04:31

目录

1、gateway简介

2、gateway核心概念

3、路由

4、断言

5、过滤器

5.1、过滤器介绍

5.2、内置局部过滤器与使用

5.3、内置全局过滤器

5.4、自定义全局过滤器

5.4.1、黑名单校验

5.4.2、模拟登录校验

6、一个简单的gateway配置实例


1、gateway简介

        路由转发 + 执行过滤器链。

        网关,旨在为微服务架构提供一种简单有效的统一的API路由管理方式。同时,基于Filter链的方式提供了网关的基本功能,比如:鉴权、流量控制、熔断、路径重写、黑白名单、日志监控等。
基本功能如下:

  • 统一入口:暴露出网关地址,作为请求唯一入口,隔离内部微服务,保障了后台服务的安全性
  • 鉴权校验:识别每个请求的权限,拒绝不符合要求的请求
  • 动态路由:动态的将请求路由到不同的后端集群中

 

2、gateway核心概念

  • 路由(Route):由一个ID,一个目标URI(最终路由到的url地址),一组断言(匹配条件判断)和一组过滤器定义。如果断言为真,则路由匹配。
  • 断言(Predicate):通过断言匹配http请求中的任何内容(请求头、请求参数等),如果匹配成功,则匹配断言所在路由。
  • 过滤器(Filter):在请求前后执行业务逻辑,比如鉴权、日志监控、流量控制、修改请求头、修改响应等。

3、路由

spring:
  cloud:
	gateway:
	  routes:
	  - id: manager						# 路由唯一标识
		uri: lb://manager_server		# 路由指向目的地URL或服务名,客户端请求最终被转发到的微服务
		predicates:
		- Path=/manager/** 				# 断言:以manager开头的请求都负载到manager_server服务
		filters:
		- RewritePath=/manager/(?<segment>.*), /$\{segment} # 过滤器:过滤掉url里的manager,例如http://ip:port/manager/test -> http://ip:port/test
		order: 5						# 用于多个Route之间的排序,数值越小越靠前,匹配优先级越高

4、断言

spring:
  cloud:
    gateway:
      routes:
      - id: manager
        uri: https://manager_server
        predicates:
        - After=2017-01-20T17:42:47.789-07:00[America/Denver]	# 时间点后匹配
		- Before=2017-01-20T17:42:47.789-07:00[America/Denver]	# 时间点前匹配
		- Between=2017-01-20T17:42:47.789-07:00[America/Denver],2017-01-21T17:42:47.789-07:00[America/Denver]	# 时间区间匹配
		- Cookie=chocolate, ch.p						# 指定cookie正则匹配
		- Header=X-Request-Id, \d+						# 指定Header正则匹配
		- Host=**.somehost.org,**.anotherhost.org		# 请求Host匹配
		- Method=GET,POST								# 请求Method匹配指定请求方式
		- Path=/red/{segment},/blue/{segment}			# 请求路径正则匹配
		- Query=green									# 请求包含某参数
		- Query=red, gree.								# 请求包含某参数并且参数值匹配正则表达式(匹配red;green,greet,gree...)
		- RemoteAddr=192.168.1.1/24						# 远程地址匹配
		
		# 设置分组和权重,按照路由权重选择同一个分组中的路由
      - id: preManager1
        uri: https://preManager1
        predicates:
		- Weight=group1, 2
      - id: preManager2
        uri: https://preManager2
        predicates:
		- Weight=group1, 8

5、过滤器

5.1、过滤器介绍

按生命周期分类

  • 前置(pre)过滤器:    在请求被路由之前调用:在chain.filter(exchange)前编写过滤器逻辑
  • 后置(post)过滤器:    在路由到微服务之后调用:通过chain.filter(exchange).then(Mono.fromRunnable(() -> {过滤器逻辑})实现

按类型分类

  • 局部(GatewayFilter)过滤器:作用在某一个路由上,使用时需要关联指定的路由
  • 全局(GlobalFilter)过滤器:作用在所有路由上,不需要在配置文件中配置

5.2、内置局部过滤器与使用

spring:
  cloud:
    gateway:
      routes:
      - id: gateway_filter
        uri: https://example.org
		predicates:
        - Path=/red/{segment}
        filters:
		# 1、为原始请求添加Header。headerName:X-Request-red,headerValue:blue。
        - AddRequestHeader=X-Request-red, blue		
		- AddRequestHeadersIfNotPresent=X-Request-Color-1:blue,X-Request-Color-2:green
		# 2、为原始请求添加参数。参数名,参数值
		- AddRequestParameter=red, blue
		# 3、为原始响应添加Header
		- AddResponseHeader=X-Response-Red, Blue
		# 4、剔除响应头中重复的值
		- DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
		# 5、为原始请求路径添加前缀
		- PrefixPath=/mypath
		# 6、配置该过滤器后,会原始请求的host头信息,并原封不动的转发出去,而不是被gateway的http客户端重置。
		- PreserveHostHeader
		# 7、将原始请求重定向到指定的URL,参数为http状态码及重定向的url
		- RedirectTo=302, https://acme.org
		# 8、移除响应Body中的指定key
		- RemoveJsonAttributesResponseBody=id,color
		# 9、移除原始请求中的指定Header
		- RemoveRequestHeader=X-Request-Foo
		# 10、移除原始请求中的指定参数
		- RemoveRequestParameter=red
		# 11、移除响应中的指定Header
		- RemoveResponseHeader=X-Response-Foo
spring:
  cloud:
    gateway:
      routes:
      - id: gateway_filter
        uri: https://example.org
		predicates:
        - Path=/red/{segment}
        filters:
		# 12、请求限流,限流算法为令牌桶,以下示例为根据用户id做限流
		# @Configuration
		# public class RateLimiterConfig {
		#	  @Bean
		#	  public KeyResolver userKeyResolver() {
		#		  return exchange -> Mono.just(Objects.requireNonNull(exchange.getRequest().getQueryParams().getFirst("userId")));
		#     }
		# }
		- name: RequestRateLimiter
          args:
            redis-rate-limiter.replenishRate: 10	# 允许用户每秒处理的请求数
            redis-rate-limiter.burstCapacity: 20	# 令牌桶的容量,即允许在 1 秒内完成的最大请求数。设置为 0 则表示拒绝所有请求。
            key-resolver: "#{@userKeyResolver}"		# 一个引用名为 userKeyResolver 的 bean 的 SpEL 表达式
		# 13、重写原始的请求路径
		- RewritePath=/red/?(?<segment>.*), /$\{segment}
		# 14、重写响应中的某个Header
		- RewriteResponseHeader=X-Response-Red, , password=[^&]+, password=***
		# 15、在转发请求之前,强制执行websession::save操作,保存会话状态
		- SaveSession
		# 16、修改原始的请求路径
		- SetPath=/{segment}
		# 17、修改原始请求中的指定Header值
		- SetRequestHeader=X-Request-Red, Blue
		# 18、修改原始响应中的指定Header值
		- SetResponseHeader=X-Response-Red, Blue
		# 19、修改原始响应的响应码
		- SetStatus=401
		# 20、剥离原始请求路径
		- StripPrefix=2
		# 21、请求重试
		- name: Retry
          args:
            retries: 3						# 重试次数
            statuses: BAD_GATEWAY			# 应被重试的 HTTP Status Codes
            methods: GET,POST				# 应被重试的 HTTP Methods
            backoff:						# 为重试配置指数级的 backoff。重试时间间隔的计算公式为 firstBackoff * (factor ^ n),n 是重试的次数;如果设置了 maxBackoff,最大的 backoff 限制为 maxBackoff. 如果 basedOnPreviousValue 设置为 true, backoff 计算公式为 prevBackoff * factor.
              firstBackoff: 10ms
              maxBackoff: 50ms
              factor: 2
              basedOnPreviousValue: false
		# 22、设置允许接收最大请求包的大小。如果请求包大小超过设置的值,则返413Payload Too Large
		- name: RequestSize
          args:
            maxSize: 5000000

5.3、内置全局过滤器

  • GatewayMetricsFilter(0):统计一些网关的性能指标
  • RouteToRequestUrlFilter(10000):把浏览器的URL请求的Path路径添加到路由的URI之中。
  • NettyRoutingFilter(2147483647):通过HttpClient客户端转发真实的URL,并存储返回的结果。
  • NettyWriteResponseFilter(-1):在所有的其它的过滤器执行完成之后运行,将响应的数据发送给网关的客户端。
  • ForwardRoutingFilter(2147483647):转发路由过滤器,若URI是forward模式,过滤器会将请求转发到DispatcherHandler来处理请求。
  • ForwardPathFilter(0):解析路径,并将路径转发。
  • LoadBalancerClientFilter(10100):负载均衡,解析服务名,获取真实服务地址。
  • RemoveCachedBodyFilter(-2147483648):清除网关上下文中的缓存的请求Body。
  • WebsocketRoutingFilter(2147483646):如果请求中的ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR 属性对应的URL前缀为 ws 或 wss,会使用Spring Web Socket 模块转发WebSocket请求。WebSockets可以使用路由进行负载均衡。
  • AdaptCachedBodyGlobalFilter(-2147482648):从请求中获取body缓存到网关上下文。

5.4、自定义全局过滤器

创建自定义全局过滤器类 ,实现GlobalFilter和Ordered两个接口。

  • GlobalFilter:全局过滤拦截器
  • Ordered:拦截器的顺序,数字越低,优先级越高

5.4.1、黑名单校验

/**
* 定义全局过滤器,会对所有路由生效
*/
@Slf4j
@Component // 让容器扫描到,等同于注册了
public class BlackListFilter implements GlobalFilter, Ordered {
	// 模拟黑名单(实际可以去数据库或者redis中查询)
	private static List<String> blackList = new ArrayList<>();
 
	static {
		blackList.add("0:0:0:0:0:0:0:1"); // 模拟本机地址
	}
	
	/**
	* 过滤器核心方法
	* @param exchange 封装了request和response对象的上下文
	* @param chain 网关过滤器链(包含全局过滤器和单路由过滤器)
	* @return
	*/
	@Override
	public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
		// 思路:获取客户端ip,判断是否在黑名单中,在的话就拒绝访问,不在的话就放行
		ServerHttpRequest request = exchange.getRequest();
		ServerHttpResponse response = exchange.getResponse();
		
		// 从request对象中获取客户端ip
		String clientIp = request.getRemoteAddress().getHostString();
		
		// 拿着clientIp去黑名单中查询,存在的话就决绝访问
		if(blackList.contains(clientIp)) {
			// 拒绝访问,返回
			response.setStatusCode(HttpStatus.UNAUTHORIZED); // 状态码
			log.debug("=====>IP:" + clientIp + " 在⿊名单中,将被拒绝访问!");
			String data = "Request be denied!";
			DataBuffer wrap = response.bufferFactory().wrap(data.getBytes());
			return response.writeWith(Mono.just(wrap));
		}
		
		// 合法请求,放行,执行后续的过滤器
		return chain.filter(exchange);
	}
	
	/**
	* @return 过滤器的顺序(优先级),数值越小,优先级越高
	*/
	@Override
	public int getOrder() {
		return 0;
	}
}

5.4.2、模拟登录校验

        在过滤器中检查请求中是否携带token请求头。如果token请求头存在则放行;如果token为空或者不存在则返回认证失败状态码。

@Component
public class MyGlobalFilter implements GlobalFilter,Ordered {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        boolean token = exchange.getRequest().getHeaders().containsKey("token");
        System.out.println("----全局过滤器token----"+token);
        if (!token){
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            ServerHttpResponse response = exchange.getResponse();
            return response.setComplete();
        }
        return chain.filter(exchange);
    }

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


6、一个简单的gateway配置实例

spring:
  cloud:
    gateway:
      discovery:
        locator:
          # 表明Gateway开启服务注册和发现的功能,并且Spring Cloud Gateway自动根据服务发现为每一个服务创建了一个router,这个router将以服务名开头的请求路径转发到对应的服务
          enabled: true
          # 将请求路径上的服务名配置为小写(因为服务注册的时候,向注册中心注册时将服务名转成大写的了)
          lower-case-service-id: true
      routes:
	  # 系统管理
      - id: sys-mgt
        uri: lb://sysmgt
        predicates:
        - Path=/sys-mgt/** 	#以sys-mgt开头的请求都负载到sysmgt服务
		- Method=GET		#只匹配GET请求
        filters:
        - RewritePath=/sys-mgt/(?<segment>.*), /$\{segment} #过滤掉url里的sys-mgt,例如http://ip:port/sys-mgt/test -> http://ip:port/test
		- PrefixPath=/mgt									#为请求添加/mgt前缀,再结合RewritePath过滤器,http://ip:port/sys-mgt/test -> http://ip:port/mgt/test

以上内容为个人学习理解,如有问题,欢迎在评论区指出。

部分内容截取自网络,如有侵权,联系作者删除。

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

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

相关文章

Linear Regression with PyTorch 用PyTorch实现线性回归

文章目录4、Linear Regression with PyTorch 用PyTorch实现线性回归4.1 Prepare dataset 准备数据集4.2 Design Model 设计模型4.2.1 __call__() 作用4.3 Construct Loss and Optimizer 构造损失和优化器4.4 Training Cycle 训练周期4.5 Test Model 测试模型4.6 Different Opti…

redis缓存淘汰策略

定时删除 Redis不可能时时刻刻遍历所有被设置了生存时间的key&#xff0c;来检测数据是否已经到达过期时间&#xff0c;然后对它进行删除。 立即删除能保证内存中数据的最大新鲜度&#xff0c;因为它保证过期键值会在过期后马上被删除&#xff0c;其所占用的内存也会随之释放。…

zookeeper学习笔记2(小D课堂)

zookeeper数据模型&#xff1a; 我们的zookeeper是以节点的形式存在的&#xff0c;这样的形式和数据结构中的树的形式很像。同时也很像我们的linux的结构&#xff0c;例如linux的/user/local目录下可以有我们的/usr/local/tomcat目录。这样的节点形式。 我们的zookeeper中的每…

算法练习-常用查找算法复现

一个不知名大学生&#xff0c;江湖人称菜狗 original author: jacky Li Email : 3435673055qq.com Time of completion&#xff1a;2023.1.1 Last edited: 2023.1.1 目录 算法练习-常用查找算法复现&#xff08;PS&#xff1a;1 -- 3自己写的&#xff0c;4、5懒得写了&#xf…

PHP开发者之路

我们经常会发现&#xff0c;历时四年软件专业的大学生毕业居然找不到工作&#xff0c;即便找到了工作也只能是做一些简单的辅助性工作。 那么我们不禁要问&#xff0c;究竟是什么原因让我们可爱的大学生们学而无用&#xff0c;或者用而不学呢&#xff1f; 我认为主要是因为现…

三角形年份aabb3n+1近似计算阶乘之和数据统计水仙花数韩信点兵倒三角形子序列的和分数化小数排列蛇形填数sprintf竖式问题

目录 P16_习题1-6_三角形 P16_习题1-7_年份 P20_eg2-1_aabb 为什么是int n a*1100 b*11 为什么要将向下取整&#xff1f; P22_eg2-2_3n1问题 P24_eg2-3_近似计算 P25_eg2-4_阶乘之和 P27_eg2-5_数据统计 P34_习题2-1_水仙花数 P34_习题2-2_韩信点兵 P34_习题2-3_倒…

Fragment全文详解(由浅入深_源码分析)

相信android开发者们一定或多或少的用过Fragment&#xff0c;但是对于其更深层次的原理我猜可能大部分应该都没有了解过&#xff0c;今天这里就由浅入深&#xff0c;整体对Fragment做一个全面解析。 基础介绍 Fragment是什么以及为什么要有Fragment呢&#xff1f; Fragment直…

长沙烟火气回来了,颐而康客流回暖为什么这么快?

随着一大批阳康的人们走出家门&#xff0c;长沙这座消费之城也逐步恢复了往日的活力。车多起来了、路堵起来了、线下店铺恢复营业了、长沙的烟火气息又回来了。 在颐而康万家丽西子店的大厅里&#xff0c;等候休息区已经坐满了顾客&#xff0c;他们有的在等待&#xff0c;有的…

Centos6从零开始安装mysql和tomcat后台环境,并成功部署Tomcat项目

最近因为搞定了一些环境的搭建因为项目过于老旧的缘故我从centosstream9一直改换7一直到6都没有成功一直到改成6.5的32位版本才算是成功搭建完成所以特地来写一篇文章记录一下。 首先我的liunx使用版本是 centos6.5 32位 java版本&#xff1a;jdkCentos6从零开始安装mysql和tom…

7-6 整除光棍

这里所谓的“光棍”&#xff0c;并不是指单身汪啦~ 说的是全部由1组成的数字&#xff0c;比如1、11、111、1111等。传说任何一个光棍都能被一个不以5结尾的奇数整除。比如&#xff0c;111111就可以被13整除。 现在&#xff0c;你的程序要读入一个整数x&#xff0c;这个整数一定…

【Kuangbin数论】阿拉丁和飞毯

4577. 阿拉丁和飞毯 - AcWing题库 题意&#xff1a; 思路&#xff1a; 就是去求x和y 使得 1.x!y 2.x*ya 3.min(x,y)b 一开始想的是去根号n地枚举a的约数 &#xff0c;然后直接统计 但是这样肯定T&#xff0c;所以换成dfs枚举约数去了 但是也T了 首先a*a<b的话直接特…

前端 | 手把手教你装饰你的github profile(github 首页)

1.创建存储库 您可以创建一个与您的 github 帐户名同名的存储库 添加README文件 2.编辑README.md 现在&#xff0c;可以根据自己的喜好修改 repo 中的自述文件&#xff0c;但我在考虑包含哪些信息时查看了其他开发人员的资料。通常包括简短的介绍、使用的技术堆栈和联系方式…

Buildroot编译hisi平台根文件系统

Buildroot编译hisi平台根文件系统 文章目录1. 下载Buildroot源码2. Menuconfig配置3. 编译Buildroot3.1 手动下载软件包3.2 kernel header 报错3.3 arm-hisiv300-linux-gcc-ar&#xff1a;cannot find plugin liblto_plugin.so3.4 /media/data/hisi/buildroot-2022.02.8/output…

C++类的多种构造函数

目录默认构造函数普通构造函数拷贝构造函数转换构造函数移动构造函数举例两个场景下面以Complex 复数类来学习C类中的各种构造函数; #include <iostream> using namespace std;//复数类 class Complex{friend ostream & operator<<(ostream &out, Complex…

2022年终结——人生中最美好的一站

文章目录前言回顾2022工作上学习上投资上生活上展望2023工作学习投资生活总结有一种责任与压力&#xff0c;叫做上有老下有小&#xff0c;但有一种幸福也叫做上有老下有小&#xff0c;当你遭遇挫折与困难时&#xff0c;这些“老小”以及那个同龄的“她”是你坚实的后盾&#xf…

Redisson中的“琐事”

文章目录前言锁分类Redisson可重入锁&#xff08;Reentrant Lock&#xff09;公平锁&#xff08;Fair Lock&#xff09;联锁&#xff08;MultiLock&#xff09;红锁&#xff08;RedLock&#xff09;读写锁&#xff08;ReadWriteLock&#xff09;信号量&#xff08;Semaphore&am…

【C++】左值、右值、语义移动和完美转发

右值引入的目的是为了对象移动&#xff1a; 因为在很多情况下&#xff0c;对象拷贝会经常发生&#xff0c;但是很多对象在拷贝后就直接被销毁了。这对性能是一个很大损耗。在重新分配内存的时候&#xff0c;从旧的内存将元素拷贝到新的内存中是不必要的。更好的方法是移动元素。…

论文投稿指南——中文核心期刊推荐(天文、测绘学)

【前言】 &#x1f680; 想发论文怎么办&#xff1f;手把手教你论文如何投稿&#xff01;那么&#xff0c;首先要搞懂投稿目标——论文期刊 &#x1f384; 在期刊论文的分布中&#xff0c;存在一种普遍现象&#xff1a;即对于某一特定的学科或专业来说&#xff0c;少数期刊所含…

使用Kalibr问题汇总:ModuleNotFoundError: No module named ‘wx‘

问题1&#xff1a; 报错&#xff1a;/kalibr_ws/src/Kalibr/Schweizer-Messer/sm_python/python/sm/PlotCollection.py", line 4, in import wx ModuleNotFoundError: No module named ‘wx’ 解决&#xff1a; sudo apt-get install python3-wxgtk4.0问题2&#xff1…

MySQL补齐函数LPAD和RPAD之SQLite解决方案

工作中经常需要对数据进行清洗&#xff0c;并对个别字段进行格式化处理&#xff0c;像 字符串左右补齐。MySQL数据库自带有LPAD()、RPAD()&#xff0c;而SQLite数据库没有的相应函数&#xff0c;需要自己转换。 目录 1、MySQL数据库 1.1、MySQL左右补全函数 1.2、实践验证 …