前言
在微服务架构中,API 网关(API Gateway)扮演着非常重要的角色。它负责接收客户端请求,并根据预定义的规则将请求路由到对应的后端服务。Spring Cloud Gateway 是 Spring 官方推出的一款高性能网关,支持动态路由、负载均衡、限流等功能。本文将详细介绍 Spring Cloud Gateway 的工作原理、配置方式以及如何实现请求分发,并附带源码和 UML 图示。
一、Spring Cloud Gateway 的核心概念
1.1 核心组件
- Route(路由):网关的基本构建块,包含一个 ID、目标 URI 和一组断言(Predicate)和过滤器(Filter)。只有当请求满足断言条件时,才会被路由到指定的目标服务。
- Predicate(断言):用于匹配 HTTP 请求中的特定条件,例如路径、方法、头信息等。
- Filter(过滤器):对请求和响应进行处理,如修改请求头、添加日志、鉴权等。
1.2 工作流程图
以下是 Spring Cloud Gateway 的工作流程图:
二、配置 Spring Cloud Gateway
2.1 引入依赖
在 pom.xml
文件中添加以下依赖:
<dependencies>
<!-- Spring Cloud Gateway -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- Spring Boot WebFlux -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<!-- Spring Cloud Load Balancer (用于负载均衡) -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
</dependencies>
2.2 配置路由规则
在 application.yml
中定义路由规则。以下是一个简单的示例:
spring:
cloud:
gateway:
routes:
- id: user_service_route
uri: lb://USER-SERVICE
predicates:
- Path=/user/**
filters:
- AddRequestHeader=X-Gateway-Version, v1.0
- id: order_service_route
uri: lb://ORDER-SERVICE
predicates:
- Path=/order/**
filters:
- AddResponseHeader=X-Gateway-Version, v1.0
配置说明:
id
:路由的唯一标识符。uri
:目标服务地址,lb://
表示使用负载均衡器(Load Balancer)。predicates
:定义匹配条件,例如路径/user/**
。filters
:定义请求或响应的处理逻辑,例如添加请求头或响应头。
三、实现请求分发的核心逻辑
3.1 动态路由匹配
Spring Cloud Gateway 使用 Predicate
来匹配请求。以下是一个基于路径的分发逻辑示例:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.ServerResponse;
@Configuration
public class GatewayConfig {
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("user_service_route", r -> r.path("/user/**")
.filters(f -> f.addRequestHeader("X-Gateway-Version", "v1.0"))
.uri("lb://USER-SERVICE"))
.route("order_service_route", r -> r.path("/order/**")
.filters(f -> f.addResponseHeader("X-Gateway-Version", "v1.0"))
.uri("lb://ORDER-SERVICE"))
.build();
}
}
代码解析:
RouteLocatorBuilder
用于构建路由规则。.path("/user/**")
匹配以/user/
开头的路径。.uri("lb://USER-SERVICE")
将请求转发到注册中心的服务USER-SERVICE
。
3.2 负载均衡
Spring Cloud Gateway 内置了对负载均衡的支持,通过 lb://
协议可以实现服务发现和负载均衡。
示例场景:
假设有两个用户服务实例 USER-SERVICE-1
和 USER-SERVICE-2
注册到了 Eureka 注册中心,Gateway 会根据负载均衡策略自动选择一个实例来处理请求。
3.3 自定义过滤器
除了内置过滤器,您还可以自定义过滤器来实现特定功能,例如鉴权、日志记录等。
以下是一个自定义过滤器的示例:
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;
@Component
public class LoggingFilter extends AbstractGatewayFilterFactory<LoggingFilter.Config> {
public LoggingFilter() {
super(Config.class);
}
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
System.out.println("请求路径:" + exchange.getRequest().getPath());
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
System.out.println("响应状态码:" + exchange.getResponse().getStatusCode());
}));
};
}
public static class Config {
// 可以在这里定义配置参数
}
}
使用自定义过滤器:
在 application.yml
中引用自定义过滤器:
spring:
cloud:
gateway:
routes:
- id: user_service_route
uri: lb://USER-SERVICE
predicates:
- Path=/user/**
filters:
- LoggingFilter
四、完整示例
以下是一个完整的 Spring Cloud Gateway 示例,包括服务注册与发现、负载均衡和自定义过滤器。
4.1 项目结构
gateway-service/
├── src/main/java/com/example/gateway/
│ ├── GatewayApplication.java
│ ├── GatewayConfig.java
│ └── LoggingFilter.java
├── src/main/resources/
│ └── application.yml
└── pom.xml
4.2 启动类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
4.3 配置文件
server:
port: 8080
spring:
application:
name: gateway-service
cloud:
gateway:
routes:
- id: user_service_route
uri: lb://USER-SERVICE
predicates:
- Path=/user/**
filters:
- LoggingFilter
- id: order_service_route
uri: lb://ORDER-SERVICE
predicates:
- Path=/order/**
filters:
- AddResponseHeader=X-Gateway-Version, v1.0
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
五、总结
通过本文,我们详细介绍了 Spring Cloud Gateway 的核心概念、配置方式以及如何实现请求分发。以下是关键点总结:
- 核心组件:Route、Predicate 和 Filter 是 Gateway 的三大核心组件。
- 动态路由:通过
Path
断言实现请求分发。 - 负载均衡:结合 Eureka 注册中心实现服务发现和负载均衡。
- 自定义过滤器:扩展 Gateway 功能,实现日志记录、鉴权等需求。
希望本文能帮助您快速上手 Spring Cloud Gateway,并将其应用到实际项目中。如果您有任何问题或建议,请随时留言交流!
参考资料
- Spring Cloud Gateway 官方文档
- Spring Cloud Netflix Eureka 文档