您现在的位置是:首页 >其他 >0201概述-网关Gateway-微服务架构网站首页其他
0201概述-网关Gateway-微服务架构
文章目录
1 前言
Spring Cloud Gateway是一个基于Spring Framework 5、Spring Boot 2和Project Reactor等技术开发的API网关,它提供了一系列的过滤器(Filter)来处理HTTP请求和响应,可以轻松地实现路由、负载均衡、限流、重试、熔断、安全控制等功能,可以作为微服务架构中的入口和边缘服务。
Spring Cloud Gateway的核心组件包括路由(Route)、断言(Predicate)、过滤器(Filter)等。路由用来将请求映射到不同的微服务上,断言则用来匹配请求的条件,过滤器则可以对请求进行修改和拦截。
Spring Cloud Gateway提供了丰富的可扩展性,可以通过编写自定义的路由、断言、过滤器等组件来满足各种复杂的业务需求。同时,它还集成了Spring Cloud的服务发现和负载均衡机制,可以自动地从注册中心中获取微服务的信息并进行负载均衡
下面我们根据官网文档和我们正在学习的开源项目pig文档以及其他相关文档,介绍一些我们开发中会用到的一些内容。
2 项目引入
项目工程pom.xml文件用引入:
<!-- 版本在spring-cloud-gateway-dependencies中指定 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
3 术语
核心概念 | 描述 |
---|---|
Route(路由) | 网关最基本的模块。它由一个 ID、一个目标 URI、一组断言(Predicate)和一组过滤器(Filter)组成。 |
Predicate(断言) | 路由转发的判断条件,我们可以通过 Predicate 对 HTTP 请求进行匹配,例如请求方式、请求路径、请求头、参数等,如果请求与断言匹配成功,则将请求转发到相应的服务。 |
Filter(过滤器) | 过滤器,我们可以使用它对请求进行拦截和修改,还可以使用它对上文的响应进行再处理。 |
注意:其中Route和Predicate必须同时申明
4 工作原理
gateway工作原理如下图4-1所示:
Spring Cloud Gateway是Spring Cloud生态系统中的一个API网关服务,它基于Spring 5,Spring Boot 2和Project Reactor构建,提供了一种简单而有效的方式来路由请求、进行限流、进行身份验证和授权、实现负载均衡等功能。
Spring Cloud Gateway的工作原理可以简单概括如下:
- 路由规则配置:开发人员通过配置文件或代码配置路由规则,定义请求的匹配规则和目标服务的位置。
- 请求到达网关:客户端请求到达Spring Cloud Gateway,被路由到对应的处理器。
- 过滤器链处理:Spring Cloud Gateway通过一系列过滤器链处理请求,每个过滤器可以进行一些操作,如修改请求头、重定向、转发、限流、身份验证等。
- 路由转发:根据路由规则,将请求转发到对应的目标服务,可以是Spring Boot应用程序、其他微服务或外部API。
- 响应处理:Spring Cloud Gateway收到目标服务的响应后,可以通过过滤器链对响应进行修改,然后将响应返回给客户端。
总之,Spring Cloud Gateway作为一种轻量级的API网关服务,可以通过路由规则和过滤器链处理请求,将请求转发到目标服务并处理响应,从而为微服务架构中的应用提供了一种高效、灵活和可扩展的解决方案。
5 配置示例
5.1 简洁配置
application.xml配置示例
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- Cookie=mycookie,mycookievalue
5.2 展开配置
application.xml配置示例
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- name: Cookie
args:
name: mycookie
regexp: mycookievalue
6 Predicate
路由转发判断条件,可以根据很多信息去判断,包括时间、Cookie、Header、Host、Method、Path等等。
我们这里以开发中的常用的Path为例,示例如下:
routes:
- id: admin-service_router
uri: lb://admin-service
predicates:
- Path=/admin/**
filters:
- StripPrefix=1
- /admin/**:**表示任意,匹配任意一级路径是admin的请求,转发到对应的uri
7 GatewayFilter
网关过滤器,可以对HTTP请求或者响应做修改。下面介绍2个开发用常用的网关过滤器:
- StripPrefix:忽略前缀
- RequestRateLimiter:请求限流
7.1 StripPrefix GatewayFilter
以#6中路由配置为例讲解,后面参数为数字,表示在向下转发的时候,忽略几段路径前缀。
routes:
- id: admin-service_router
uri: lb://admin-service
predicates:
- Path=/admin/**
filters:
- StripPrefix=1
- 这里stripPrefix值为1,对应的请求示例/admin/user在向下转发的时候忽略掉/admin/,变为/user;
- 路径分隔符默认/,StripPrefix值对应几个/xxx/分隔符包围的路径。
7.2 RequestRateLimiter
GatewayFilter
网关限流实例:
① pom 依赖
这里一定要注意,是网关引入的redis-reactive,背压模式的redis。
<!--基于 reactive stream 的redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
② 配置按照请求IP 的限流
spring:
cloud:
gateway:
routes:
- id: requestratelimiter_route
uri: lb://pig-upms
order: 10000
predicates:
- Path=/admin/**
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 1 # 令牌桶每秒填充平均速率
redis-rate-limiter.burstCapacity: 3 # 令牌桶总容量
key-resolver: "#{@remoteAddrKeyResolver}" #SPEL表达式去的对应的bean
- StripPrefix=1
- 配置bean,多维度限流量的入口 对应上边key-resolver
/**
* 自定义限流标志的key,多个维度可以从这里入手
* exchange对象中获取服务ID、请求信息,用户信息等
*/
@Bean
KeyResolver remoteAddrKeyResolver() {
return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getHostName());
}
6 Global Filters
全局过滤器,配合Ordered接口用来指定在过滤器执行链中的顺序。在开发中,我们一般用来做日志记录,获取自定义请求头信息,做校验等等。
下面看下日志记录的实例:
@Slf4j
@Component
public class ApiLoggingFilter implements GlobalFilter, Ordered {
private static final String START_TIME = "startTime";
private static final String X_REAL_IP = "X-Real-IP";// nginx需要配置
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
if (log.isDebugEnabled()) {
String info = String.format("Method:{%s} Host:{%s} Path:{%s} Query:{%s}",
exchange.getRequest().getMethod().name(), exchange.getRequest().getURI().getHost(),
exchange.getRequest().getURI().getPath(), exchange.getRequest().getQueryParams());
log.debug(info);
}
exchange.getAttributes().put(START_TIME, System.currentTimeMillis());
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
Long startTime = exchange.getAttribute(START_TIME);
if (startTime != null) {
Long executeTime = (System.currentTimeMillis() - startTime);
List<String> ips = exchange.getRequest().getHeaders().get(X_REAL_IP);
String ip = ips != null ? ips.get(0) : null;
String api = exchange.getRequest().getURI().getRawPath();
int code = 500;
if (exchange.getResponse().getStatusCode() != null) {
code = exchange.getResponse().getStatusCode().value();
}
// 当前仅记录日志,后续可以添加日志队列,来过滤请求慢的接口
if (log.isDebugEnabled()) {
log.debug("来自IP地址:{}的请求接口:{},响应状态码:{},请求耗时:{}ms", ip, api, code, executeTime);
}
}
}));
}
@Override
public int getOrder() {
return Ordered.LOWEST_PRECEDENCE;
}
}
7 网关超时配置
路由超时配置可以为所有路由配置Http超时(响应和连接),并为每个特定路由覆盖Http超时。
7.① 配置全局路由超时时间
spring:
cloud:
gateway:
httpclient:
connect-timeout: 1000
response-timeout: 10s
- connect-timeout 必须以毫秒为单位指定连接超时时间.
- response-timeout 必须指定为java.time.Duration
7.② 特定接口配置超时时间
- id: pig-upms # 唯一的服务ID
uri: lb://pig-upms # 注册中心的服务名称,实现负载均衡
predicates:
- Path=/admin/demo #所有业务的请求前缀
metadata:
response-timeout: 200
connect-timeout: 200
可以通过路由的metadata以下两个参数配置每个路由超时:
- connect-timeout 必须以毫秒为单位指定连接超时时间.
- response-timeout 必须以毫秒为单位指定响应超时时间.
8 网关CORS 跨域配置
CORS跨域配置,可以以不同的方式进行配置,这里介绍在网关进行配置的方式。
在网关的配置文件中加入以下内容(请根据实际情况修改)
spring:
cloud:
gateway:
# default-filters:
# - DedupeResponseHeader=Access-Control-Allow-Origin
globalcors:
corsConfigurations:
'[/**]':
allowedOriginPatterns: "*" #注意这个设置只对 spring boot 2.4+ 有效,低版本 使用 allowedOrigins: "*" 属性
allowed-methods: "*"
allowed-headers: "*"
allow-credentials: true
exposedHeaders: "Content-Disposition,Content-Type,Cache-Control"
- 以上配置可作为开发环境使用,生成环境建议你根据实际情况修改(请先理解CORS,并参考
org.springframework.cloud.gateway.config.GlobalCorsProperties
) - 跨域时会产生预检请求(Pre-Flight Request),这样就会对你的服务器产生额外的网络请求。如果可以通过部署手段解决跨域,则可以关闭跨域支持,方法是把以上配置信息清理掉。
结语
如果小伙伴什么问题或者指教,欢迎交流。
❓QQ:806797785
⭐️源代码仓库地址:https://gitee.com/gaogzhen/micro
参考地址:
[2] Gateway:Spring Cloud API网关组件(非常详细)
[3] Spring Cloud——微服务网关Spring Cloud GateWay
[4] lengleng /pig