gateway基本配置

news/2024/11/20 4:50:44/

目录

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/testorder: 5						# 用于多个Route之间的排序,数值越小越靠前,匹配优先级越高

4、断言

spring:cloud:gateway:routes:- id: manageruri: https://manager_serverpredicates:- 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: preManager1uri: https://preManager1predicates:- Weight=group1, 2- id: preManager2uri: https://preManager2predicates:- 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_filteruri: https://example.orgpredicates:- 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_filteruri: https://example.orgpredicates:- 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: RequestRateLimiterargs: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: Retryargs:retries: 3						# 重试次数statuses: BAD_GATEWAY			# 应被重试的 HTTP Status Codesmethods: GET,POST				# 应被重试的 HTTP Methodsbackoff:						# 为重试配置指数级的 backoff。重试时间间隔的计算公式为 firstBackoff * (factor ^ n),n 是重试的次数;如果设置了 maxBackoff,最大的 backoff 限制为 maxBackoff. 如果 basedOnPreviousValue 设置为 true, backoff 计算公式为 prevBackoff * factor.firstBackoff: 10msmaxBackoff: 50msfactor: 2basedOnPreviousValue: false# 22、设置允许接收最大请求包的大小。如果请求包大小超过设置的值,则返413Payload Too Large- name: RequestSizeargs: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*/@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {// 思路:获取客户端ip,判断是否在黑名单中,在的话就拒绝访问,不在的话就放行ServerHttpRequest request = exchange.getRequest();ServerHttpResponse response = exchange.getResponse();// 从request对象中获取客户端ipString 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 过滤器的顺序(优先级),数值越小,优先级越高*/@Overridepublic int getOrder() {return 0;}
}

5.4.2、模拟登录校验

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

@Component
public class MyGlobalFilter implements GlobalFilter,Ordered {@Overridepublic 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);}@Overridepublic int getOrder() {return 1;}
}

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

spring:cloud:gateway:discovery:locator:# 表明Gateway开启服务注册和发现的功能,并且Spring Cloud Gateway自动根据服务发现为每一个服务创建了一个router,这个router将以服务名开头的请求路径转发到对应的服务enabled: true# 将请求路径上的服务名配置为小写(因为服务注册的时候,向注册中心注册时将服务名转成大写的了)lower-case-service-id: trueroutes:# 系统管理- id: sys-mgturi: lb://sysmgtpredicates:- 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.ppmy.cn/news/8708.html

相关文章

【android Framework 探究】android 13 aosp 全记录 - 烧录

相关文章&#xff1a;【android Framework 探究】android 13 aosp编译全记录 写在开始 书接上文&#xff0c;编译完后&#xff0c;在二手平台挑挑拣拣最终下手piexl 5&#xff0c;这就开始迫不及待的烧录。 一&#xff0c;解锁bootloader 如果之前已经解锁可以跳过这步 adb r…

SpringBoot整合ShardingJdbc实现数据库水平分表实战

(1)添加Maven依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0"xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/P…

表白墙 -- 前后端代码详解

表白墙 -- 前后端代码详解一、前端二、后端实现2.1 需求2.2 创建项目及初始化2.3 实现提交数据 (存档)2.3.1 实现 doPost2.3.2 构造请求 (修改 html 文件)2.3.3 验证2.4 实现获取数据 (读档)2.4.1 实现 doGet2.4.2 构造请求 (修改 html 文件)2.4.3 验证三、JDBC 版本 (MySQL)3.…

Java个人家乡博客源码

概述 个人博客相册家乡主题&#xff0c;用户注册后可以发布关于家乡的特色文章介绍&#xff0c;可以发布照片&#xff0c;相册管理&#xff0c;留言&#xff0c;评论&#xff0c;回复&#xff0c;收藏&#xff0c;关注 演示视频 https://www.bilibili.com/video/BV1iy4y1x7w6…

Python数据分析案例16——水质检测(支持向量机)

本次带来图片分类的案例&#xff0c;水质检测。 数据展示 五种类别的水质&#xff0c;图片形式储存的&#xff1a; 前面1是代表水质的类别标签&#xff0c;后面是样本个数。 图片特征构建 import numpy as np import pandas as pd import matplotlib.pyplot as plt import o…

Python代码实现学生管理系统

Python代码实现学生管理系统 需求说明 实现一个命令行版本的学生管理系统 功能: 新增学生 显示学生 查找学生 删除学生 存档到文件 创建入口函数 使用一个全局列表 students 表示所有学生信息. 使用 menu 函数和用户交互. 这是一个自定义函数. 使用 insert , show ,…

56. 数据增广 / 图像增广

1. CES上的真实故事 2. 数据增强 增加一个已有数据集&#xff0c;使得有更多的多样性 在语言里加入各种不同的背景噪音改变图片的颜色和形状 例如&#xff0c;我们可以以不同的方式裁剪图像&#xff0c;使感兴趣的对象出现在不同的位置&#xff0c;减少模型对于对象出现位置…

Python全栈开发(一)——环境搭建和入门

今天是2023年的第一天&#xff0c;接下来的一个月里&#xff0c;我将持续更新关于python全栈开发的相关知识&#xff0c;前面一段时间都是基础语法。主要分成四大块&#xff1a;基础、面向对象、MYSQL数据库、Django框架。话不多说&#xff0c;进入到今天的主题。 1.文档和工具…