SpringCloudAlibaba之Gateway

1、简介

        网关是系统唯一对外的入口,介于客户端与服务器端之间,用于对请求进行鉴权、限流、路由、监控等功能。

2、Gateway主要功能
2.1、route 路由

路由是网关的最基本组成,由一个路由 id、一个目标地址 url,一组断言工厂及一组 filter 组成。若断言为 true,则请求将经由 filter 被路由到目标 url。

2.2、predicate 断言

断言即一个条件判断,根据当前的 http 请求进行指定规则的匹配,比如说 http 请求头,请求时间等。只有当匹配上规则时,断言才为 true,此时请求才会被直接路由到目标地址(目标服务器),或先路由到某过滤器链,经过过滤器链的层层处理后,再路由到相应的目标地址(目标服务器)。

2.3、filter 过滤器

对请求进行处理的逻辑部分。当请求的断言为 true 时,会被路由到设置好的过滤器,以对请求或响应进行处理。例如,可以为请求添加一个请求参数,或对请求 URI 进行修改,或为响应添加 header 等。总之,就是对请求或响应进行处理。

3、route路由使用配置示例
3.1、引入依赖
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
3.2、修改配置文件(application.yml)
spring:application:name: gateway_8085cloud:nacos:discovery:server-addr: localhost:8848gateway:  # 使用gateway调用服务,服务不正常时,将状态码从503改成404loadbalancer:use404: true# 配置注册中心可以发现discovery:locator:enabled: trueglobalcors:  # 全局跨域设置cors-configurations:'[/**]':allowedOrigins: "*"allowedMethods:- GET- POSTroutes:- id: my_routeuri: https://www.cnblogs.com/predicates:- Path=/1114zwlmetadata:  # 针对单个路由跨域配置 cors:allowedOrigins: "*"allowedMethods:- GET- POST- id: my_route1   # 可配置多个路由规则uri: https://www.cnblogs.com/predicates:- Path=/1114zwlmetadata:  # 针对单个路由跨域配置 # 设置单个路由http请求超时时间response-timeout: 200connect-timeout: 200cors:allowedOrigins: "*"allowedMethods:- GET- POST
2.3、使用api方式配置路由(与配置文件同在时,api优先)
@SpringBootConfiguration
public class GatewayConfig {@Beanpublic RouteLocator routeLocator(RouteLocatorBuilder builder){return builder.routes().route("my_route", ps -> ps.path("/**").uri("https://baidu.com")).route("my_route1", ps -> ps.path("/**").uri("https://taoao.com")).build();}
}
3、predicate 断言
3.1、After/Before/Between路由断言工厂

        这些断言工厂的参数是一个 UTC 格式的时间。其会将请求访问到 Gateway 的时间与该参数时间相比,若请求时间在参数时间之后/之前/之中,则匹配成功,断言为 true。

具体配置:

spring:application:name: gateway_8085cloud:nacos:discovery:server-addr: localhost:8848gateway:  routes:- id: my_routeuri: https://www.cnblogs.com/predicates:- Path=/1114zwl- After=2023-01-21T17:42:47.789-07:00- Before=2023-12-21T17:42:47.789-07:00- Between=2023-01-21T17:42:47.789-07:00,2023-12-21T17:42:47.789-07:00
3.2、Cookie/Header/host路由断言工厂

该断言工厂中包含两个参数,分别是 cookie/header 的 key 与 value。当请求中携带了指定 key 与 value的 cookie/header 时,匹配成功,断言为 true。

spring:application:name: gateway_8085cloud:nacos:discovery:server-addr: localhost:8848gateway: httpclient: # 设置全局http请求超时时间connect-timeout: 1000response-timeout: 5sroutes:- id: my_routeuri: https://www.cnblogs.com/predicates:- Path=/1114zwl- After=2023-01-21T17:42:47.789-07:00- Before=2023-12-21T17:42:47.789-07:00- Between=2023-01-21T17:42:47.789-07:00,2023-12-21T17:42:47.789-07:00- Cookie=city,beijing   # 示例:Cookie: city=beijing- Header=X-Request-Id, \d+ # 示例:X-Request-Id=123- Host=myhost:9000, ...        # host: myhost:9000- Method=GET, POST  # 请求方式
3.3、path路由断言工厂

该断言工厂用于判断请求路径中是否包含指定的 uri。若包含,则匹配成功,断言为 true,此时会将该匹配上的 uri 拼接到要转向的目标 uri 的后面,形成一个统一的 uri

注:更多断言相关配置见官网:Spring Cloud Gateway

4、自定义异常处理类
@Component
@Order(-1)
public class CustomerErrorWebExceptionHandler extends AbstractErrorWebExceptionHandler {public CustomerErrorWebExceptionHandler(ErrorAttributes errorAttributes, ApplicationContext applicationContext, ServerCodecConfigurer serverCodecConfigurer){super(errorAttributes, new WebProperties.Resources(), applicationContext);super.setMessageReaders(serverCodecConfigurer.getReaders());super.setMessageWriters(serverCodecConfigurer.getWriters());}@Overrideprotected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {return RouterFunctions.route(RequestPredicates.all(), this::renderErrorResponse);}private Mono<ServerResponse> renderErrorResponse(final ServerRequest request){Map<String, Object> map = getErrorAttributes(request, ErrorAttributeOptions.defaults());return ServerResponse.status(HttpStatus.NOT_FOUND).contentType(MediaType.APPLICATION_JSON).body(BodyInserters.fromValue(map));}
}//如果想要自定义map内容需要重写getErrorAttributes方法
import org.springframework.boot.web.reactive.error.DefaultErrorAttributes;
@Component
public class CustomErrorAttributes extends DefaultErrorAttributes {@Overridepublic Map<String, Object> getErrorAttributes(ServerRequest request, ErrorAttributeOptions options) {Map<String, Object>  map = new HashMap<>(16);map.put("status", HttpStatus.NOT_FOUND.value());map.put("msg", "对不起找不到资源");return map;}
}
5、自定义路由断言工厂

命名规则:该类类名由两部分构成:后面必须是 RoutePredicateFactory,前面为功能前缀,该前缀将来要用在配置文件中

5.1、自定义代码
import lombok.Data;
import org.springframework.cloud.gateway.handler.predicate.AbstractRoutePredicateFactory;
import org.springframework.http.HttpHeaders;
import org.springframework.web.server.ServerWebExchange;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;public class AuthRouterPredicateFactory extends AbstractRoutePredicateFactory<AuthRouterPredicateFactory.Config> {public AuthRouterPredicateFactory(){super(Config.class);}@Datapublic static class Config {private String name;private String password;}@Overridepublic List<String> shortcutFieldOrder() {return Arrays.asList("name", "password");}@Overridepublic Predicate<ServerWebExchange> apply(Config config) {return serverWebExchange -> {HttpHeaders headers = serverWebExchange.getRequest().getHeaders();List<String> pwds = headers.get(config.getName());if (pwds.contains(config.getPassword())){return true;}return false;};}
}
5.2、配置文件内容
spring:gateway: routes:- id: my_routeuri: https://www.cnblogs.com/predicates:- Path=/1114zwl- After=2023-01-21T17:42:47.789-07:00- Before=2023-12-21T17:42:47.789-07:00- Between=2023-01-21T17:42:47.789-07:00,2023-12-21T17:42:47.789-07:00- Auth=weilong,123456  # 自定义断言路由工厂配置

6、filter 过滤器
6.1、AddRequestHeader/AddRequestHeadersIfNotPresent/AddRequestParameter/AddResponseHeader过滤工厂

1)、AddRequestHeader过滤器工厂会对匹配上的请求添加指定的 header,可以出现重复请求头。

2)、AddRequestHeadersIfNotPresent过滤器工厂会对匹配上的请求添加指定的 header,前提是该 header 在当前请求中尚未出现过。

3)、AddRequestParameter过滤器工厂会对匹配上的请求添加指定的请求参数。

4)、AddResponseHeader过滤器工厂会给从网关返回的响应添加上指定的 header。

配置文件方式:

spring:application:name: gateway_8085cloud:nacos:discovery:server-addr: localhost:8848gateway:  # 使用gateway调用服务,服务不正常时,将状态码从503改成404loadbalancer:use404: truediscovery:locator:enabled: trueglobalcors:  # 全局跨域设置cors-configurations:'[/**]':allowedOrigins: "*"allowedMethods:- GET- POSTroutes:- id: my_routeuri: https://www.cnblogs.com/predicates:- Path=/1114zwl- After=2023-01-21T17:42:47.789-07:00- Before=2023-12-21T17:42:47.789-07:00- Between=2023-01-21T17:42:47.789-07:00,2023-12-21T17:42:47.789-07:00- Auth=weilong,123456metadata:  # 针对单个路由跨域配置 cors:allowedOrigins: "*"allowedMethods:- GET- POST#  配置过滤器工厂filters:- AddRequestHeader=X-Request-Color,blue- AddRequestHeadersIfNotPresent=X-Request-Color:blue,City:beijing- AddRequestParameter=color,blue- AddRequestParameter=color,red- AddRequestParameter=size,red
6.2、CircuitBreaker过滤工厂

该过滤器工厂完成网关层的服务熔断与降级。

6.2.1、添加依赖
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-circuitbreaker-resilience4j</artifactId>
</dependency>
6.2.2、降级配置
filters:- name: CircuitBreakerargs:name: myCircuitBreakerfallbackUri: forward:/testFallback  # 在访问指定路由的时候会降级到指定的uri

注:

1)、第一个 name 属性用于指定要使用的 filter 类型,不能随意写。

2)、args 是对指定 filter 的配置参数。

3)、第二个 name 属性用于指定当前所使用断路器的名称,可以随意。fallbackUri 属性用于指定发生断路后要提交的降级 URI。

6.2.3、api方式
@Beanpublic RouteLocator routeFillerLocator(RouteLocatorBuilder builder){return builder.routes().route("my_route", ps -> ps.path("/**").filters(fs -> fs.addRequestHeader("X-Request-Header","blue").circuitBreaker(conf -> {conf.setName("myCircuitBreaker").setFallbackUri("forward:/testFallback");})).uri("https://baidu.com")).build();}
6.3、PrefixPath/StripPrefix/RewritePath 过滤工厂

1)、PrefixPath过滤器工厂会为指定的 URI 自动添加上一个指定的 URI 前辍。

2)、StripPrefix过滤器工厂会为指定的 URI 去掉指定长度的前辍。

3)、RewritePath 过滤器工厂会将请求 URI 替换为另一个指定的 URI 进行访问。RewritePath 有两个参数,第一个是正则表达式,第二个是要替换为的目标表达式。

配置文件方式:

 #  配置过滤器工厂
filters:- PrefixPath=/test # 会将请求uri添加/test 前缀- StripPrefix=2  # 会将请求的uri去掉两个前缀- RewritePath=/test/t1, /test/t2   # 将请求的uri中/test/t1替换成 /test/t2,支持使用正则
6.4、RequestRateLimiterGateway过滤工厂(限流)

        该过滤器工厂通过令牌桶算法对进来的请求进行限流。这个限流器是基于 Redis 的,所以需要导入 Redis 的 Starter 依赖。

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>

添加限流键解析器

        限流 key可以是用户、URI,也可以是目标服务器的 host 或 IP。本例指定的是根据请求要访问的目标服务器的 host 或 ip 进行限流。

filters:- name: RequestRateLimiterargs:key-resolver: "#{@userKeyResolver}"redis-rate-limiter.replenishRate: 2redis-rate-limiter.burstCapacity: 5redis-rate-limiter.requestedTokens: 1
# redis配置
spring:data:redis:host: localhostport: 6379
6.5、全局过滤器配置
spring:cloud:gateway:default-filters:- name: CircuitBreakerargs:name: myCircuitBreakerfallbackUri: forward:/testFallback

注:对于相同 filter 工厂,在不同位置设置了不同的值,则优先级为:

局部 filter 的优先级高于默认 filter 的, API 式的 filter 优先级高于配置式 filter 的。

7、自定义网关过滤工厂

类名由两部分构成:后面必须是 GatewayFilterFactory,前面为功能前缀,该前缀将来要用在配置文件中。

@Component
public class AddHeaderGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {@Overridepublic GatewayFilter apply(NameValueConfig config) {return (es, chain) -> {ServerHttpRequest request = es.getRequest().mutate().header(config.getName(), config.getValue()).build();ServerWebExchange webExchange = es.mutate().request(request).build();return chain.filter(webExchange);};}
}

配置文件:

filters:- AddHeader=new-color, red
8、负载均衡全局过滤器

添加依赖

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

注:此服务要注册到注册中心,才能根据服务名进行负载均衡。

配置文件

spring:application:name: gateway_8085cloud:nacos:discovery:server-addr: localhost:8848gateway:# 使用gateway调用服务,服务不正常时,将状态码从503改成404loadbalancer:use404: true# 开启向注册中心注册功能discovery:locator:enabled: trueroutes:- id: my_routeuri:lb://provider-service  # 负载均衡配置predicates:- Path=/1114zwl
9、自定义全局过滤器

Global Filter 不需要在任何具体的路由规则中进行注册,只需在类上添加@Compoment 注解,将其生命周期交给 Spring 容器来管理即可。

示例:判断请求中是否携带了 token 请求参数。

@Component
public class URLValidateFilter implements GlobalFilter, Ordered {@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {String token = exchange.getRequest().getQueryParams().getFirst("token");if (!StringUtils.hasText(token)){exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);return exchange.getResponse().setComplete();}return chain.filter(exchange);}@Overridepublic int getOrder() {return Ordered.HIGHEST_PRECEDENCE;}
}
10、跨域问题

为了安全,浏览器中启用了一种称为同源策略的安全机制,禁止从一个域名页面中请求另一个域名下的资源。当两个请求的访问协议、域名与端口号三者都相同时,才称它们是同源的。只要有一个不同,就称为跨域请求。

配置方式解决跨域问题:

spring:application:name: gateway_8085cloud:globalcors:  # 全局跨域设置cors-configurations:'[/**]':allowedOrigins: "*"allowedMethods:- GET- POSTroutes:- id: my_routeuri: https://www.cnblogs.com/predicates:- Path=/1114zwl- After=2023-01-21T17:42:47.789-07:00- Before=2023-12-21T17:42:47.789-07:00- Between=2023-01-21T17:42:47.789-07:00,2023-12-21T17:42:47.789-07:00- Auth=weilong,123456metadata:  # 针对单个路由局部跨域配置 cors:allowedOrigins: "*"allowedMethods:- GET- POST

总结:本文详细介绍Gateway的使用,路由、断言、过滤器使用都进行了详细介绍,帮助初学者快速入门Gateway的使用。

        本人是一个从小白自学计算机技术,对运维、后端、各种中间件技术、大数据等有一定的学习心得,想获取自学总结资料(pdf版本)或者希望共同学习,关注微信公众号:上了年纪的小男孩。后台回复相应技术名称/技术点即可获得。(本人学习宗旨:学会了就要免费分享)

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

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

相关文章

静态S5的常见问题与解决方法

静态S5作为一款功能强大的数据分析工具&#xff0c;被广泛应用于各个行业。然而&#xff0c;在使用过程中&#xff0c;用户可能会遇到一些常见问题。本文将针对这些问题提供相应的解决方法&#xff0c;帮助用户更好地使用静态S5。 一、数据导入问题 在导入数据时&#xff0c;…

RocketMQ源码 创建Topic流程源码分析

前言 MQAdminImpl MQ管理组件提供了大量对mq进行管理的工具&#xff0c;其中一个就是创建Topic。它内部实现是通过 mqClient工具从 NameServer拉取当前 Topic对应的路由元数据信息&#xff0c;解析遍历和当前topic有关的 broker高可用分组集合&#xff0c;找到分组中的 master…

老胡的周刊(第122期)

老胡的信息周刊[1]&#xff0c;记录这周我看到的有价值的信息&#xff0c;主要针对计算机领域&#xff0c;内容主题极大程度被我个人喜好主导。这个项目核心目的在于记录让自己有印象的信息做一个留存以及共享。 &#x1f3af; 项目 movie-web[2] 开源可自部署的简约在线电影搜…

JAVA中对登录进行IP限制

一、获取登录用户的网络IP public String getIpAddress(HttpServletRequest request) {String ipAddress request.getHeader("x-forwarded-for");if (ipAddress null || ipAddress.length() 0 || "unknown".equalsIgnoreCase(ipAddress)) {ipAddress …

jdk和IDEA教育版下载和安装详解

前言 研究生专业是通信系统,为了寻找实习于是在研二时期学习java。但是在学习java的过程中没有进行系统总结,很多知识点或者一些细节已经忘记。由于工作找的是某行软件中心的软件开发。准备在毕业前对java知识进行系统性学习。本专栏将从零基础开始,从最简单的jdk和IDEA下载…

李沐机器学习系列3---深度学习计算

1 层和块 1.1 定义块 用class表示层&#xff0c;并只需要实现构造函数和前向传播函数 class MLP(nn.Module):# 用模型参数声明层。这里&#xff0c;我们声明两个全连接的层def __init__(self):# 调用MLP的父类Module的构造函数来执行必要的初始化。# 这样&#xff0c;在类实…

delete后,指针还能使用?!

int *bnew int(10);delete b;*b5;qDebug()<<*b; 结果&#xff1a;5 delete释放后的指针为什么还可以用-CSDN社区 delete后&#xff0c;系统只是把指针指向的堆空间回收&#xff0c; 但是没有将这个指针变量的值赋值为nullptr&#xff0c; 指针还是指向原来的堆空间&#…

Java学习苦旅(十六)——List

本篇博客将详细讲解Java中的List。 文章目录 预备知识——初识泛型泛型的引入泛型小结 预备知识——包装类基本数据类型和包装类直接对应关系装包与拆包 ArrayList简介ArrayList使用ArrayList的构造ArrayList常见操作ArrayList遍历 结尾 预备知识——初识泛型 泛型的引入 我…

vmware安装龙蜥操作系统

vmware安装龙蜥操作系统 1、下载龙蜥操作系统 8.8 镜像文件2、安装龙蜥操作系统 8.83、配置龙蜥操作系统 8.83.1、配置静态IP地址 和 dns3.2、查看磁盘分区3.3、查看系统版本 1、下载龙蜥操作系统 8.8 镜像文件 这里选择 2023年2月发布的 8.8 版本 官方下载链接 https://mirro…

Cytoscape3.8安装下载及安装教程

Cytoscape3.8下载链接&#xff1a;https://docs.qq.com/doc/DUmhZQ1lqTWhuSXJC 1.选中下载好的安装包右键选择“解压到 Cytoscape3.8.0”文件夹 2.打开解压好的”Cytoscape3.8.0“文件夹 3.选中“Cytoscape_3_8_0_windows_64bit.exe“右键以管理员身份运行 4.点击”Download“&…

MP3音乐播放器搜索引擎-在线搜索MP3歌曲实现(一)

首先添加网络模块和播放模块 下载文件&#xff0c;获取响应&#xff0c;错误处理,加上可以进行网络访问 要加上头文件#include<QNetworkAccessManager> 上面头文件发送请求后返回的响应类用下边的头文件 #include<QNetworkReply> 添加多媒体播放列表#include&…

四川天蝶电子商务有限公司带货服务可信吗?

四川天蝶电子商务有限公司&#xff0c;一个充满活力和创新精神的企业&#xff0c;近年来在抖音带货服务领域取得了令人瞩目的成绩。作为一家致力于提供全方位电子商务解决方案的企业&#xff0c;天蝶公司紧跟时代潮流&#xff0c;积极布局抖音电商市场&#xff0c;为商家提供了…