微服务架构已成为构建现代化应用程序的关键范式之一,它将应用程序拆分成多个小型、可独立部署的服务。Spring Cloud Gateway是Spring Cloud生态系统中的一个关键组件,用于构建和管理微服务架构中的网关。本报告旨在调查和介绍Spring Cloud Gateway的核心概念、架构、功能以及其在微服务架构中的作用。
Spring Cloud Gateway 是 Spring 官方基于 Spring 5.0,Spring Boot 2.0 和 Project Reactor 等技术开发的网关,旨在为微服务架构提供一种简单而有效的统一的 API 路由管理方式,统一访问接口。Spring Cloud Gateway 作为 Spring Cloud 生态系中的网关,目标是替代 Netflix ZUUL,其不仅提供统一的路由方式,并且基于 Filter 链的方式提供了网关基本的功能,例如:安全,监控/埋点,和限流等。它是基于Nttey的响应式开发模式。
路由(Route):路由是网关最基础的部分,路由信息由一个ID、一个目标的URL、一组断言工程和一组过滤器组成。如果断言为真,则说明请求URL和配置的路由匹配。
断言(Predicates):Java8中的断言函数,Spring Cloud Gateway中的断言函数允许开发者去定义函数匹配来自Http Request中的任何信息,比如请求头和参数等。
过滤器(Filter):一个标准的Spring webFilter, 可以分为Gateway Filter和Global Filter。过滤器Filter可以对请求和响应进行处理。
示例:
server:
port: 8080
spring:
application:
name: api-gateway
cloud:
gateway:
routes:
- id: product-service
uri:http://127.0.0.1:9002
predicates:
- Path=/product/**
动态路由,即自动从注册中心获取服务列表并访问。
现在以spring cloud gateway 集成nacos为例
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-gatewayartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-configartifactId>
dependency>
spring:
application:
name: gateway-service
cloud:
nacos:
discovery:
server-addr: localhost:8848
gateway:
discovery:
locator:
enabled: true # 启用服务发现
routes:
- id: service-route
uri: lb://service-name # 后端服务名称
predicates:
- Path=/service-path/** # 匹配的请求路径
filters:
- StripPrefix=1 # 去掉前缀
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class GatewayServiceApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayServiceApplication.class, args);
}
}
在Spring Cloud gateway中,路由转发是直接将匹配的路由path直接拼接到映射路径(URL)之后,那么在微服务中开发往往没有那么便利,这里可以通过RewritePath机制来进行路径重写。
spring:
application:
name: gateway-service
cloud:
nacos:
discovery:
server-addr: localhost:8848
gateway:
discovery:
locator:
enabled: true # 启用服务发现
routes:
- id: service-route
uri: lb://service-name # 后端服务名称
predicates:
- Path=/service-path/** # 匹配的请求路径
filters:
- RewritePath=/serive-path/(? >.*), /$\{segment}
Spring Cloud Gateway的Filter从作用范围可分为两种:GatewayFilter与GlobalFilter
局部过滤器是针对单个路由的过滤器,可以对访问的URL过滤,进行切面处理。常见的局部过滤器:
全局过滤器作用于所有路由,Spring Cloud Gateway定义了GlobalFilter接口,用户可以自定义实现自己的Global Filter。通过全局过滤器可以实现对权限的统一检验,安全性验证等功能。
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-redis-reactiveartifactId>
<version>2.2.10.RELEASEversion>
dependency>
public class IpKeyResolver implements KeyResolver {
/***
* 根据IP限流
* @param exchange
* @return
*/
@Override
public Mono<String> resolve(ServerWebExchange exchange) {
return Mono.just(exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());
}
}
需要将IpKeyResolver的实例交给Spring容器管理。
@Configuration
public class GatewayRateLimitConfig {
@Bean("ipKeyResolver")
public KeyResolver userIpKeyResolver(){
return new IpKeyResolver();
}
}
spring:
cloud:
gateway:
routes:
#商品服务
- id: goods_route
uri: lb://mall-goods
predicates:
- Path=/mall/brand/**
filters:
- StripPrefix=1
# 指定过滤器
- name: RequestRateLimiter
args:
# 指定限流标识
key-resolver: '#{@ipKeyResolver}'
# 速率限流
redis-rate-limiter.replenishRate: 1
# 能容纳的并发流量总数
redis-rate-limiter.burstCapacity: 2
监控每个请求的响应参数是否包含手机号码
首先,您需要创建一个自定义过滤器类,该类将检查响应参数中是否包含手机号码。这可以通过解析响应内容并搜索手机号码的正则表达式来完成。下面是一个示例:
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Component
@Order(1) // 设置过滤器顺序
public class PhoneNumberCheckFilter implements GlobalFilter {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 检查响应内容是否包含手机号码的逻辑
// 解析响应内容并搜索手机号码的正则表达式
// 如果包含手机号码,则可以进行相关处理,例如记录日志或触发警报
// 这里仅提供示例框架,具体实现需要根据需求编写
return chain.filter(exchange);
}
}
然后配置过滤器
spring:
cloud:
gateway:
routes:
- id: route-name
uri: http://example.com
filters:
- PhoneNumberCheck= # 这里填写自定义过滤器的名字