网站首页 > 技术文章 正文
一、简介
Spring Cloud Gateway 是 Spring 官方基于 Spring 5.x,Spring Boot 2.0 和 Project Reactor 等技术开发的网关,旨在为微服务架构提供一种简单而有效的统一的 API 路由管理方式,目标是替代 Netflix Zuul,底层是Netty网络编程框架-ServerSocket,其不仅提供统一的路由方式,并且基于 Filter 链的方式提供了网关基本的功能,可用于身份认证、权限校验、服务路由、负载均衡、请求限流。
二、分类
在SpringCloud中网关的实现包括两种:
- gateway
- zuul
Zuul是基于Servlet的实现,属于阻塞式编程。而SpringCloudGateway则是基于Spring5中提供的WebFlux,属于响应式编程的实现,具备更好的性能。
三、快速入门
第一步:创建gateway模块(创建springboot项目,这里不详细介绍啦),然后pom文件加网关依赖。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
第二步:yml文件中添加相关配置
server:
port: 9000
spring:
application:
name: gateway
cloud:
gateway:
routes: #配置网关路由规则
- id: route01 #路由id,自己指定一个唯一值即可
# uri: http://localhost:8082 # 网关帮我们转发的url,即访问provider 只能一个实例,不能负载均衡
uri: lb://provider # 路由的目标地址 lb就是负载均衡,后面跟服务名称
predicates: #匹配请求规则 断言(谓词)
- Path=/nacos/provider/** #请求路径定义,只要以/provider/开头就符合要求
filters: #网关过滤器,对谓词中的内容进行判断分析及处理
- StripPrefix=1 #转发之前去掉path中的第一层路径,例如nacos
- RewritePath=/system/v2/api-docs, /v2/api-docs # 将/system/v2/api-docs配置,转发到 /v2/api-docs
# 开发阶段打开gateway日志
logging:
level:
org.springframework.cloud.gateway: debug
其中:路由(routes) 是 gateway 中最基本的组件之一,表示一个具体的路由信息载体。主要定义了下面的几个信息:
- id,路由标识符,区别于其他 Route
- uri,路由指向的目的地 uri,即客户端请求最终被转发到的微服务
- predicate,断言(谓词)的作用是进行条件判断,只有断言都返回真,才会执行路由。
- filter,过滤器用于修改请求和响应信息
第三步:依次启动provider,gateway服务,然后打开浏览器,进行访问测试,
三、负载均衡实现
项目实现负载均衡是通过将服务注册到注册中心(这里用nacos)来实现的。
第一步、项目添加nacos依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
访问服务是通过服务名来访问的,所有需要修改配置文件中的url方式,改用 lb://服务名 来实现。修改配置文件url的内容:
uri: lb://provider # 路由的目标地址 lb就是负载均衡,后面跟服务名称
四、Predicate(断言)增强分析
说明:Predicate(断言)又称谓词,用于条件判断,只有断言结果都为真,才会真正的执行路由。断言其本质就是定义路由转发的条件。
1、基于Datetime类型的断言工厂
此类型的断言根据时间做判断,主要有三个:
- AfterRoutePredicateFactory:判断请求日期是否晚于指定日期
- BeforeRoutePredicateFactory:判断请求日期是否早于指定日期
- BetweenRoutePredicateFactory:判断请求日期是否在指定时间段内
2、基于header的断言工厂HeaderRoutePredicateFactory
判断请求Header是否具有给定名称且值与正则表达式匹配。例如:-Header=X-Request-Id, \d+
3、基于Method请求方法的断言工厂
MethodRoutePredicateFactory接收一个参数,判断请求类型是否跟指定的类型匹配。例如:-Method=GET
4、基于Query请求参数的断言工厂,QueryRoutePredicateFactory
接收两个参数,请求param和正则表达式, 判断请求参数是否具 有给定名称且值与正则表达式匹配。例如:-Query=pageSize,\d+
spring:
application:
name: gateway
cloud:
nacos:
discovery:
server-addr: localhost:8848
gateway:
discovery:
locator:
enabled: true #开启通过服务名查找服务实例的特性
routes: #配置网关路由规则
- id: route01 #路由id,自己指定一个唯一值即可
#uri: http://localhost:8082 # 网关帮我们转发的url,即访问provider 只能一个实例,不能负载均衡
uri: lb://provider
predicates: #匹配请求规则 断言(谓词)
- Path=/nacos/provider/echo/** #请求路径定义,此路径对应uri中的资源
#- After=2021-08-01T23:59:59.789+08:00[Asia/Shanghai] #在2020-08-01时间后才可以访问
#- Before=2021-08-25T23:59:59.789+08:00[Asia/Shanghai] #在2020-08-01时间后之前才可以访问
#- Between=2020-08-03T23:59:59.789+08:00[Asia/Shanghai],2023-08-05T23:59:59.789+08:00[Asia/Shanghai]
#- Header=X-Request-Id, \d+ #请求头 \d+ 正则表达式,这里表示任意数字
- Method=GET #请求方式
#- Query=pageSize,\d+ #请求参数
filters: #网关过滤器,对谓词中的内容进行判断分析及处理
- StripPrefix=1 #转发之前去掉path中的第一层路径,例如nacos
#- AddRequestHeader=X-Request-Foo,Bar #往转发地址的请求头加入数据 X-Request-Foo请求头的名称,Bar请求头的值
五、过滤器增强
过滤器(Filter)就是在请求传递过程中,对请求和响应做一个处理。Gateway 的Filter从作用范围可分为以下两种:
- GatewayFilter:应用到单个路由或者一个分组的路由上。
- GlobalFilter:应用到所有的路由上。
1、局部过滤器
1.1、基于AddRequestHeaderGatewayFilterFactory,为原始请求添加Header
例如,为原始请求添加名为 X-Request-Foo ,值为 Bar 的请求头:
spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri: https://example.org
filters:
- AddRequestHeader=X-Request-Foo, Bar
1.2、基于AddRequestParameterGatewayFilterFactory,为原始请求添加请求参数及值:
例如,为原始请求添加名为foo,值为bar的参数,即:foo=bar
spring:
cloud:
gateway:
routes:
- id: add_request_parameter_route
uri: https://example.org
filters:
- AddRequestParameter=foo, bar
2、全局过滤器
/**
* 定义一个全局过滤器,模拟统一认证,Spring Cloud Gateway规范中,要求所有全局过滤器必须实现GlobalFilter接口
*/
@Component
public class AuthGlobalFilter implements GlobalFilter, Ordered {
/**
* 对请求进行过滤
*
* @param exchange (网管层面的交换器,通过此对象获取请求和响应对象)
* @param chain 过滤器链(这个过滤器链中包含0个或多个过滤器)
* @return Mono是Spring WebFlux技术中的0个或1个响应序列
* http://localhost:9000/nacos/provider/echo/9000?username=admin
*/
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
//获取请求和响应对象
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
//获取请求参数数据,并进行数据响应
String username = request.getQueryParams().getFirst("username");
if (!"admin".equals(username)) {
System.out.println("认证失败");
response.setStatusCode(HttpStatus.UNAUTHORIZED);
//终止请求继续传递
return response.setComplete();
}
//请求链继续传递(假如用户名为admin则继续执行后续操作)
return chain.filter(exchange);
}
@Override
public int getOrder() {
return Integer.MIN_VALUE;//数字越小,优先级约高
}
}
六、限流实现
网关是所有请求的公共入口,所以可以在网关进行限流,而且限流的方式也很多,这里采用Sentinel组件来实现网关的限流。Sentinel支持对SpringCloud Gateway、Zuul等主流网关进行限流。
1、限流快速入门
添加sentinel限流的相关依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
</dependency>
yml文件添加sentinel相关配置
spring:
application:
name: gateway
cloud:
sentinel:
transport:
port: 8719 #客户端监控API的端口
dashboard: localhost:8180 #Sentinel 控制台地址
eager: true #取消Sentinel控制台懒加载,即项目启动即连接
启动网关项目,添加sentinel的jvm参数,通过此菜单可以让网关服务在sentinel控制台显示不一样的菜单
-Dcsp.sentinel.app.type=1
在sentinel面板中设置限流策略
测试限流策略是否生效
2、基于请求属性限流
3、自定义API维度限流
自定义API分组,是一种更细粒度的限流规则定义,它允许我们利用sentinel提供的API,将请求路径进行分组,然后在组上设置限流规则
第一步:新建API分组
第二步:新建分组流控规则
猜你喜欢
- 2024-12-23 Kong 优雅实现微服务网关鉴权,登录场景落地实战篇
- 2024-12-23 微服务实战系列(九)-注册中心与网关高可用架构设计
- 2024-12-23 使用Kong作为微服务网关 微服务api网关
- 2024-12-23 微服务架构中API网关介绍 微服务api网关的作用
- 2024-12-23 万字长文详解微服务网关(中) 微服务网关是什么?
- 2024-12-23 微服务API聚合网关 An Aggregation API Gateway
- 2024-12-23 浅谈微服务:通信之网关 Ready 微服务架构中网关的作用
- 2024-12-23 国产微服务网关Apache APISIX 上手
- 2024-12-23 微服务网关 Gateway 进阶 - 认证鉴权
- 2024-12-23 微服务架构之API网关——在微服务项目中的技术框架和用法实践
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- oraclesql优化 (66)
- 类的加载机制 (75)
- feignclient (62)
- 一致性hash算法 (71)
- dockfile (66)
- 锁机制 (57)
- javaresponse (60)
- 查看hive版本 (59)
- phpworkerman (57)
- spark算子 (58)
- vue双向绑定的原理 (68)
- springbootget请求 (58)
- docker网络三种模式 (67)
- spring控制反转 (71)
- data:image/jpeg (69)
- base64 (69)
- java分页 (64)
- kibanadocker (60)
- qabstracttablemodel (62)
- java生成pdf文件 (69)
- deletelater (62)
- com.aspose.words (58)
- android.mk (62)
- qopengl (73)
- epoch_millis (61)
本文暂时没有评论,来添加一个吧(●'◡'●)