微服务统一入口——Gateway
目录
一、网关的概念
二、Spring Cloud 中的网关
1. Zuul(已逐渐被替代)
2. Spring Cloud Gateway(推荐使用)
三、快速上手
1.创建网关服务启动类
2.引入依赖
3.添加配置
4.测试
四、路由断言工厂
1.核心原理
2.内置网关过滤工厂
3.自定义路由断言工厂
五、网关过滤工厂
1.GatewayFilter
2.GlobalFilter
3.Default Filters
4.自定义网关过滤工厂
六、过滤器的执行顺序
在之前的朱皮皮呀-CSDN博客中,我们通过Eureka,Nacos解决了服务注册,服务发现的问题,使用Spring Cloud LoadBalance解决了负载均衡的问题,使用OpenFeign解决了远程调用的问题,接下来则是使用Gateway解决API网关问题。
一、网关的概念
网关是位于客户端与后端服务之间,充当 “入口” 角色。它统一接收客户端请求,再根据配置的规则将请求转发到对应的后端服务,同时提供路由、过滤、安全等附加功能。
例子:外部人员去一家公司办理业务,这个公司里分为多个部门,每个部门办理业务之前都要进行身份校验,重复校验降低了班是效率,因此该公司成立一个前台来统一进行身份校验,校验成功后其他部门就无需校验了,这个"前台"就类似于"API网关"
网关的核心功能
权限控制:微服务的入口,对用户进行权限校验,如果校验失败则进行拦截。
路由转发:将请求按照规则转发到目标微服务。
负载均衡:将请求分配给不同的服务实例,提高可用性。
安全防护:防止恶意攻击、限制请求频率、过滤无效请求,有限流的功能。
日志与监控:记录请求日志,便于追踪和问题排查。
协议适配:支持 HTTP、WebSocket 等多种协议转发。
二、Spring Cloud 中的网关
1. Zuul(已逐渐被替代)
Zuul 是 Netflix 开源的网关组件,早期在 Spring Cloud 中广泛使用,基于 Servlet 技术栈实现。
特点:
基于同步阻塞 IO 模型(Servlet 2.5),性能较低。
集成 Spring Cloud 生态(如与 Eureka、Ribbon 配合实现服务发现和负载均衡)。
支持过滤器机制,可自定义请求处理逻辑。
缺点:
阻塞 IO 导致高并发场景下性能瓶颈明显。
扩展性较差,过滤器链执行效率低。
目前 Zuul 1.x 已停止更新,Zuul 2.x 虽改为非阻塞模型,但与 Spring Cloud 集成不够紧密,应用较少。
2. Spring Cloud Gateway(推荐使用)
Spring Cloud Gateway 是 Spring 官方推出的网关组件,旨在替代 Zuul,基于 Spring 5、Spring Boot 2 和 Project Reactor 开发,采用非阻塞响应式编程模型,性能远优于 Zuul。
核心优势:
非阻塞 IO:基于 Netty 实现,支持高并发,吞吐量是 Zuul 的数倍。
动态路由:支持通过配置中心(如 Nacos、Config)动态修改路由规则,无需重启服务。
强大的断言(Predicate)和过滤器(Filter):可灵活匹配请求、修改请求 / 响应。
原生集成 Spring 生态:无缝对接 Spring Security(认证授权)、Spring Cloud Circuit Breaker(熔断)等。
支持 WebSocket:适合实时通信场景(如聊天、消息推送)
三、快速上手
下面为gateway核心内容,前置代码配置请参考告别 RestTemplate,OpenFeign 才是微服务通信的正确姿势-CSDN博客
1.创建网关服务启动类
@SpringBootApplication
public class GatewayApplication {public static void main(String[] args) {SpringApplication.run(GatewayApplication.class,args);}
}
2.引入依赖
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
3.添加配置
server:port: 10030 #⽹关端⼝
spring:application:name: gateway #服务名称cloud:nacos:discovery:server-addr: 110.41.51.65:10020gateway:routes: #⽹关路由配置- id: product-service #路由ID,⾃定义,唯⼀即可uri: lb://product-service #⽬标服务地址predicates: #路由条件- Path=/product/**- id: order-serviceuri: lb://order-servicepredicates:- Path=/order/**
核心概念
id:自定义路由标识,保持唯一。
uri:目标服务地址,⽀持普通URI 及 lb://应用注册服务名称,lb表示负载均衡,使用 lb:// 方
式表示从注册中心获取服务地址。
predicates:匹配条件,根据匹配结果决定是否执行该请求路由,上述代码中,我们把符合Path规则的⼀切请求,都代理到uri参数指定的地址。
4.测试
启动API网关服务
访问:http://127.0.0.1:10030/product/1001,路由转发到http://product-service/product/1001
访问:http://127.0.0.1:10030/order/1,路由转发到http://order-service/product/1
四、路由断言工厂
路由断言工厂(Route Predicate Factory)的作用是创建 Predicate(断言),用于判断请求是否符合某个路由的匹配条件。当请求到达网关时,网关会通过这些断言工厂生成的 Predicate,筛选出最合适的路由进行转发。
1.核心原理
过滤器分为局部过滤器(仅对当前路由生效)和全局过滤器(对所有路由生效),这里的 “过滤工厂” 特指局部过滤器的工厂。
命名规则:工厂类名以GatewayFilterFactory
结尾(如AddRequestHeaderGatewayFilterFactory
),配置时使用前缀(如AddRequestHeader
)。
执行时机:分为 “前置过滤”(请求转发前执行,如权限校验)和 “后置过滤”(服务响应后执行,如日志记录)。
2.内置网关过滤工厂
Spring Cloud Gateway 内置了 很多种过滤工厂,覆盖请求修改、路径处理、限流、熔断等场景。以下是最常用的几种:
配置示例:
spring:cloud:gateway:routes:- id: product-serviceuri: lb://product-servicepredicates:- Path=/product/** # 路径匹配:/user/开头的请求- Method=GET # 方法匹配:只接受GET请求- Query=token # 参数匹配:必须包含token参数- Header=X-Request-Source,app # 头匹配:X-Request-Source必须为app
3.自定义路由断言工厂
定义工厂类:继承
AbstractRoutePredicateFactory
,泛型为配置类(存储断言参数)。实现方法:重写
apply
方法(生成 Predicate)和shortcutFieldOrder
方法(指定参数顺序)。注册为 Bean:通过
@Component
注解注册。
代码示例:自定义 “请求 IP 在白名单中” 的断言工厂
// 配置类:存储白名单参数
@Data
public class IpWhiteListConfig {private List<String> allowedIps; // 允许的IP列表
}
// 自定义断言工厂
@Component
public class IpWhiteListRoutePredicateFactory extends AbstractRoutePredicateFactory<IpWhiteListConfig> {
// 构造方法:指定配置类public IpWhiteListRoutePredicateFactory() {super(IpWhiteListConfig.class);}
// 生成Predicate:判断请求IP是否在白名单中@Overridepublic Predicate<ServerWebExchange> apply(IpWhiteListConfig config) {return exchange -> {// 获取客户端IPString clientIp = exchange.getRequest().getRemoteAddress().getAddress().getHostAddress();// 检查是否在白名单中return config.getAllowedIps().contains(clientIp);};}
// 指定配置参数的顺序(用于简化配置)@Overridepublic List<String> shortcutFieldOrder() {return Collections.singletonList("allowedIps");}
}
配置示例:
spring:cloud:gateway:routes:- id: admin-serviceuri: lb://admin-servicepredicates:- Path=/admin/**- name: IpWhiteList # 自定义断言的前缀(类名去掉RoutePredicateFactory)args:allowedIps: 192.168.1.100,127.0.0.1 # 允许的IP列表
五、网关过滤工厂
网关过滤工厂(Gateway Filter Factory)的作用是创建过滤器,用于在请求转发到目标服务前后修改请求或响应,实现横切功能(如添加头信息、路径处理、限流等)。
Filter分为两种类型:Pre类型和Post类型。
Pre类型过滤器: 路由处理之前执行(请求转发到后端服务之前执行),在Pre 类型过滤器中可以做鉴权,限流等。
Post类型过滤器:请求执行完成后, 将结果返回给客户端之前执行。
Spring Cloud Gateway 中内置了很多Filter,用于拦截和链式处理web请求,比如权限校验,访问超时等设定,Spring Cloud Gateway从作⽤范围上, 把Filter可分为GatewayFilter和GlobalFilter。
GatewayFilter:应用到单个路由或者⼀个分组的路由上。
GlobalFilter:应用到所有的路由上,也就是对所有的请求生效。
1.GatewayFilter
内置网关过滤工厂
Spring Cloud Gateway 内置了多种过滤工厂,覆盖请求修改、路径处理、限流、熔断等场景。以下是最常用的几种:
配置示例:
spring:cloud:gateway:routes:- id: order-serviceuri: lb://order-servicepredicates:- Path=/order/**filters:- StripPrefix=1 # 去除1层前缀(/order/1 → /1)- AddRequestHeader=X-From-Gateway, true # 添加请求头- AddResponseHeader=X-Cache-Time, 60 # 添加响应头# 限流配置- name: RequestRateLimiterargs:redis-rate-limiter.replenishRate: 5 # 每秒允许5个请求redis-rate-limiter.burstCapacity: 10 # 突发允许10个请求key-resolver: "#{@ipKeyResolver}" # 基于IP限流(需自定义Bean)
2.GlobalFilter
GlobalFilter是Spring Cloud Gateway中的全局过滤器,它和GatewayFilter的作用是相同的,GlobalFilter会应用到所有的路由请求上,全局过滤器通常用于实现与安全性,性能监控和日志记录等相关的全局功能。
Spring Cloud Gateway 内置的全局过滤器也有很多,比如:
Gateway Metrics Filter:网关指标, 提供监控指标
Forward Routing Filter:用于本地forword, 请求不转发到下游服务器
LoadBalancer Client Filter:针对下游服务, 实现负载均衡
快速上手
1.添加依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2.代码示例
@Component // 注册成 Spring Bean,Gateway 自动识别
public class LogGlobalFilter implements GlobalFilter, Ordered {
private static final Logger log = LoggerFactory.getLogger(LogGlobalFilter.class);
@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {// 前置逻辑log.info("请求路径:{}", exchange.getRequest().getURI());
// 继续执行下一个过滤器return chain.filter(exchange).then(Mono.fromRunnable(() -> {// 后置逻辑log.info("响应状态码:{}", exchange.getResponse().getStatusCode());}));}
@Overridepublic int getOrder() {return -1; //数字越小优先级越高,Ordered.HIGHEST_PRECEDENCE = Integer.MIN_VALUE}
}
3.配置示例
spring:cloud:gateway:metrics:enabled: true # 启用 Gateway 的监控指标(Metrics)
management:endpoints:web:exposure:include: "*" # 暴露所有 Actuator 端点endpoint:health:show-details: always # 健康检查时总是显示详细信息(shutdown:enabled: true # 开启优雅关闭(/actuator/shutdown 接口),生产环境一般建议关闭
4.测试
访问http://127.0.0.1:10030/actuator, 显⽰所有监控的信息链接
3.Default Filters
前面的filter添加在指定路由下,所以只对当前路由生效,若需要对全部路由生效,可以使用spring.cloud.gateway.default-filters 这个属性需要⼀个filter的列表。
示例:
spring:cloud:gateway:default-filters:# 给所有响应都加一个响应头- AddResponseHeader=X-Response-Default-Red, Default-Blue# 给所有请求的路径都自动加上前缀- PrefixPath=/httpbin
4.自定义网关过滤工厂
自定义过滤工厂用于实现业务特定的过滤逻辑(如自定义签名校验、日志记录等)。步骤如下:
定义工厂类:继承
AbstractGatewayFilterFactory
,泛型为配置类(存储过滤参数)。实现方法:重写
apply
方法(生成 GatewayFilter)和shortcutFieldOrder
方法(指定参数顺序)。注册为 Bean:通过
@Component
注解注册。
代码示例:自定义 “请求耗时统计” 过滤器工厂
// 配置类:存储是否打印日志的参数
@Data
public class RequestTimeLogConfig {private boolean enabled; // 是否启用日志
}
// 自定义过滤工厂
@Component
public class RequestTimeLogGatewayFilterFactory extends AbstractGatewayFilterFactory<RequestTimeLogConfig> {
public RequestTimeLogGatewayFilterFactory() {super(RequestTimeLogConfig.class);}
@Overridepublic GatewayFilter apply(RequestTimeLogConfig config) {return (exchange, chain) -> {if (!config.isEnabled()) {return chain.filter(exchange); // 不启用则直接放行}
// 前置逻辑:记录请求开始时间long startTime = System.currentTimeMillis();// 执行后续过滤器链return chain.filter(exchange).then(Mono.fromRunnable(() -> {// 后置逻辑:计算耗时并打印long endTime = System.currentTimeMillis();long cost = endTime - startTime;log.info("请求路径:{},耗时:{}ms", exchange.getRequest().getPath(), cost);}));};}
@Overridepublic List<String> shortcutFieldOrder() {return Collections.singletonList("enabled");}
}
配置示例
spring:cloud:gateway:routes:- id: product-serviceuri: lb://product-servicepredicates:- Path=/product/**filters:- name: RequestTimeLog # 自定义过滤器前缀args:enabled: true # 启用耗时统计日志
六、过滤器的执行顺序
请求路由后,网关会把当前项目中的GatewayFilter和GlobalFilter合并到⼀个过滤器链(集合)中,并进行排序,依次执行过滤器。
每⼀个过滤器都必须指定⼀个int类型的order值,默认值为0,表示该过滤的优先级,order值越小,优先级越高,执行顺序越靠前。
Filter通过实现Order接口或者添加@Order注解来指定order值。
Spring Cloud Gateway提供的Filter由Spring指定,用户也可以自定义Filter,由用户指定。当过滤器的order值⼀样时, 会按照 defaultFilter > GatewayFilter > GlobalFilter的顺序执行。