Spring Cloud Gateway 如何将请求分发到各个服务

前言

在微服务架构中,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 的工作流程图:
客户端发送请求 Gateway 接收请求 匹配路由规则 执行全局过滤器 转发请求到目标服务 目标服务处理请求 返回响应到 Gateway 执行后置过滤器 返回响应给客户端


二、配置 Spring Cloud Gateway

2.1 引入依赖

pom.xml 文件中添加以下依赖:

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 中定义路由规则。以下是一个简单的示例:

yaml 复制代码
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 来匹配请求。以下是一个基于路径的分发逻辑示例:

java 复制代码
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-1USER-SERVICE-2 注册到了 Eureka 注册中心,Gateway 会根据负载均衡策略自动选择一个实例来处理请求。


3.3 自定义过滤器

除了内置过滤器,您还可以自定义过滤器来实现特定功能,例如鉴权、日志记录等。

以下是一个自定义过滤器的示例:

java 复制代码
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 中引用自定义过滤器:

yaml 复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: user_service_route
          uri: lb://USER-SERVICE
          predicates:
            - Path=/user/**
          filters:
            - LoggingFilter

四、完整示例

以下是一个完整的 Spring Cloud Gateway 示例,包括服务注册与发现、负载均衡和自定义过滤器。

4.1 项目结构

plaintext 复制代码
gateway-service/
├── src/main/java/com/example/gateway/
│   ├── GatewayApplication.java
│   ├── GatewayConfig.java
│   └── LoggingFilter.java
├── src/main/resources/
│   └── application.yml
└── pom.xml

4.2 启动类

java 复制代码
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 配置文件

yaml 复制代码
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 的核心概念、配置方式以及如何实现请求分发。以下是关键点总结:

  1. 核心组件:Route、Predicate 和 Filter 是 Gateway 的三大核心组件。
  2. 动态路由 :通过 Path 断言实现请求分发。
  3. 负载均衡:结合 Eureka 注册中心实现服务发现和负载均衡。
  4. 自定义过滤器:扩展 Gateway 功能,实现日志记录、鉴权等需求。

希望本文能帮助您快速上手 Spring Cloud Gateway,并将其应用到实际项目中。如果您有任何问题或建议,请随时留言交流!


参考资料

相关推荐
bxlj_jcj1 天前
Nacos注册中心:从服务注册到负载均衡
spring cloud·nacos
qq_5470261791 天前
SpringCloud--Sleuth 分布式链路追踪
后端·spring·spring cloud
青鱼入云1 天前
介绍Spring Cloud Gateway
spring cloud·微服务
戮戮1 天前
一次深入排查:Spring Cloud Gateway TCP 连接复用导致 K8s 负载均衡失效
tcp/ip·spring cloud·kubernetes·gateway·负载均衡·netty
后端小张2 天前
【JAVA 进阶】Mybatis-Plus 实战使用与最佳实践
java·spring boot·spring·spring cloud·tomcat·mybatis·mybatis plus
青鱼入云2 天前
介绍Spring Cloud Stream
spring cloud·微服务
青鱼入云2 天前
介绍一下Ribbon的工作原理
spring cloud·微服务·ribbon
青鱼入云2 天前
Ribbon是如何与服务注册中心nacos交互的
spring cloud·微服务·ribbon
青鱼入云3 天前
OpenFeign介绍
spring cloud·微服务
勇往直前plus3 天前
学习和掌握RabbitMQ及其与springboot的整合实践(篇一)
spring boot·学习·spring cloud·rabbitmq·java-rabbitmq