行业资讯
📅 2026/8/13 8:30:28
Spring Cloud Gateway 微服务网关入门:10分钟搭建动态路由与鉴权
1. 项目概述为什么我们需要一个服务网关在微服务架构里一个应用通常会被拆分成十几个甚至几十个独立的服务。想象一下你有一个电商应用用户服务、商品服务、订单服务、支付服务各自独立部署。从前端App或者网页发来的一个“下单”请求可能需要依次调用用户鉴权、查询商品库存、创建订单、调用支付接口这四个不同的服务。如果让前端直接去记住这几十个服务的IP地址和端口那简直就是一场运维和开发的噩梦服务地址一变所有客户端都得跟着改每个服务都要自己处理鉴权、限流、日志代码重复且难以维护更别提监控和排查问题了请求散落在各处像大海捞针。这时候服务网关API Gateway就扮演了“前台接待”和“交通警察”的核心角色。它作为整个系统对外的唯一入口所有外部请求都必须先经过它。由它来统一处理那些与业务逻辑无关的“横切关注点”比如身份验证、权限校验、流量控制、请求路由、协议转换、监控指标收集等等。这样背后的各个微服务就可以专心致志地处理自己的业务逻辑变得非常“纯粹”。Spring Cloud Gateway正是Spring官方基于响应式编程模型Reactor推出的第二代网关组件它性能强悍、功能丰富配置方式也相当灵活是目前构建微服务入口的主流选择之一。今天我们就来手把手完成一个Spring Cloud Gateway的最简配置让你能在10分钟内搭建起一个具备基本路由功能的服务网关。别看是“简单配置”这里面涉及的路由断言、过滤器链、动态路由等概念是理解网关工作原理的基石。我会在每一步都解释清楚“为什么这么做”并分享我在实际项目中趟过的坑和积累的技巧。2. 核心概念与项目环境准备在开始敲代码之前我们必须先搞清楚Spring Cloud Gateway里几个最核心的“零件”不然配置起来就是一头雾水。路由Route这是网关最核心的构建块。一个路由由三部分组成ID路由的唯一标识随便起个名字就行比如user_route。目标URI这个路由最终要把请求转发到哪去。比如lb://USER-SERVICE这里的lb表示使用负载均衡USER-SERVICE是注册中心里的服务名。断言Predicate集合一组判断条件。只有当当前请求满足所有这些条件时这个路由才会被匹配上。比如“路径是/api/user/**”或者“请求方法为GET”。过滤器Filter集合一组在处理请求前后执行的逻辑。可以在请求转发前修改请求头、增加参数Pre Filter也可以在收到响应后修改响应体、记录日志Post Filter。断言Predicate这是Java 8中Predicate函数式接口的实现。它接收一个ServerWebExchange对象可以理解为封装了当前HTTP请求-响应交换的所有信息返回一个布尔值。Spring Cloud Gateway内置了十几种实用的断言工厂比如基于路径的Path、基于请求头的Header、基于时间的After、Before、Between基于Cookie的Cookie基于查询参数的Query等等。多个断言是“与AND”的关系。过滤器Filter这是GatewayFilter接口的实例。它们可以修改请求和响应。过滤器分为两种Gateway Filter作用于单个路由。Global Filter全局过滤器作用于所有路由。理解了这些我们再来准备环境。我强烈建议使用Spring Boot 3.x和Spring Cloud 2022.x及以上版本即“Release Train”版本名称为2022.0.x代号Kilburn进行开发这是目前的主流和长期支持版本。我们将创建一个最简单的父子工程结构。1. 创建父工程管理依赖创建一个Maven项目pom.xml中主要定义依赖管理?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd modelVersion4.0.0/modelVersion groupIdcom.example/groupId artifactIdgateway-demo/artifactId version1.0.0/version packagingpom/packaging !-- 注意这里是pom -- parent groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-parent/artifactId version3.1.5/version !-- 使用较新的Boot版本 -- relativePath/ /parent properties java.version17/java.version spring-cloud.version2022.0.4/spring-cloud.version !-- 对应的Cloud版本 -- /properties dependencyManagement dependencies dependency groupIdorg.springframework.cloud/groupId artifactIdspring-cloud-dependencies/artifactId version${spring-cloud.version}/version typepom/type scopeimport/scope /dependency /dependencies /dependencyManagement modules modulegateway-service/module !-- 未来可以添加其他微服务模块 -- /modules /project2. 创建网关子模块在父工程下新建一个模块gateway-service。其pom.xml只需要引入两个关键依赖?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd parent artifactIdgateway-demo/artifactId groupIdcom.example/groupId version1.0.0/version /parent modelVersion4.0.0/modelVersion artifactIdgateway-service/artifactId dependencies !-- Spring Cloud Gateway 核心依赖 -- dependency groupIdorg.springframework.cloud/groupId artifactIdspring-cloud-starter-gateway/artifactId /dependency !-- 如果需要从Nacos/Eureka获取服务列表还需要添加对应客户端依赖 -- !-- dependency groupIdcom.alibaba.cloud/groupId artifactIdspring-cloud-starter-alibaba-nacos-discovery/artifactId /dependency -- !-- 健康检查与Actuator端点可选但推荐 -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-actuator/artifactId /dependency /dependencies /project注意这里有一个新手极易踩的巨坑Spring Cloud Gateway底层基于Netty和WebFlux是响应式编程栈。因此它绝对不能引入spring-boot-starter-web这个依赖。因为spring-boot-starter-web是基于Servlet的如Tomcat两者会冲突导致应用无法启动。如果你发现启动时报错说找不到javax.servlet.Servlet之类的类99%是因为不小心引入了Web依赖。3. 基于配置文件的路由配置详解这是最简单直观的配置方式适合路由规则相对固定、不需要频繁变更的场景。我们在gateway-service模块的application.yml文件中进行配置。3.1 基础路由路径匹配与转发假设我们有两个虚构的微服务用户服务user-service和商品服务product-service。我们希望网关实现以下规则所有以/api/user/**开头的请求转发到用户服务。所有以/api/product/**开头的请求转发到商品服务。我们先假设你知道这两个服务的实际IP和端口比如在开发测试环境。配置文件如下server: port: 8080 # 网关自身端口 spring: application: name: gateway-service cloud: gateway: routes: # 路由配置列表 - id: user_route # 路由ID唯一即可 uri: http://localhost:8081 # 目标服务地址这里是用户服务假设运行在8081端口 predicates: # 断言数组满足所有条件才匹配 - Path/api/user/** # 路径匹配断言 filters: - StripPrefix1 # 过滤器去掉路径前缀的第一部分/api - id: product_route uri: http://localhost:8082 # 商品服务地址 predicates: - Path/api/product/** filters: - StripPrefix1关键点解析id每个路由的唯一标识在监控、动态更新时会用到。uri这是请求最终要被转发到的地址。目前写的是具体的HTTP地址。predicates这里只用了Path断言。/api/user/**是一个Ant风格的路径模式**表示匹配任意多级目录。filters这里使用了内置的StripPrefix过滤器。这是网关配置中最常用也最易出错的过滤器之一。它的作用是在将请求转发给下游服务之前去掉原始请求路径中的前N个部分。为什么要用StripPrefix1假设前端请求的是http://localhost:8080/api/user/info。没有过滤器网关匹配到user_route后会将请求原封不动地转发给http://localhost:8081/api/user/info。这意味着你的用户服务也必须提供/api/user/info这个接口。这造成了路径耦合网关并没有起到“解耦”的作用。使用StripPrefix1网关在转发前会去掉路径中以/分隔的第一部分即/api。于是转发给用户服务的请求路径就变成了http://localhost:8081/user/info。这样用户服务只需要实现/user/info这个接口即可。网关统一了对外API前缀/api内部服务可以使用更简洁的路径。你可以根据需求调整数字。例如如果你的路径是/gateway/api/user/info想保留/user/info就需要设置StripPrefix2。3.2 集成服务发现动态路由在实际生产环境中服务的实例地址、端口甚至是数量都是动态变化的。我们不可能在网关配置里写死IP。这时就需要集成服务注册中心如Nacos、Eureka。我们以Nacos为例。首先在pom.xml中添加Nacos发现依赖dependency groupIdcom.alibaba.cloud/groupId artifactIdspring-cloud-starter-alibaba-nacos-discovery/artifactId /dependency然后修改application.ymlserver: port: 8080 spring: application: name: gateway-service cloud: nacos: discovery: server-addr: localhost:8848 # Nacos服务器地址 gateway: discovery: locator: enabled: true # 开启根据服务名自动创建路由的功能简易模式 routes: - id: user_route # uri不再写死IP使用 lb://服务名 格式。lb代表LoadBalancer启用负载均衡 uri: lb://user-service predicates: - Path/api/user/** filters: - StripPrefix1 - id: product_route uri: lb://product-service predicates: - Path/api/product/** filters: - StripPrefix1核心变化uri格式从http://host:port变成了lb://service-name。lb协议告诉Gateway要使用负载均衡器默认是Ribbon或Spring Cloud LoadBalancer从注册中心Nacos获取user-service的所有实例列表并选择一个进行转发。spring.cloud.gateway.discovery.locator.enabledtrue这是一个非常方便的配置。开启后Gateway会自动为注册中心里的每一个服务创建一个默认的路由规则。访问时可以使用http://网关地址:端口/大写的服务名/**的格式。例如http://localhost:8080/USER-SERVICE/user/info会被路由到user-service的/user/info接口。但在正式项目中我通常建议关闭它设为false因为这种路由方式不够直观且暴露了服务名不如我们手动配置的/api/xxx这种方式清晰、安全。实操心得在开发初期可以开启locator.enabledtrue来快速测试网关到服务的连通性。但在确定API规划后应关闭此功能转而使用精心设计的、带统一前缀的静态路由配置这样API风格更统一也更利于后续的鉴权、流控等过滤器的配置。3.3 常用断言与过滤器工厂示例Gateway提供了丰富的内置工厂让我们通过配置就能实现复杂逻辑。更多断言配置示例spring: cloud: gateway: routes: - id: complex_route uri: lb://some-service predicates: - Path/api/items/{segment} # 路径匹配{segment}是路径变量 - MethodGET,POST # 请求方法必须是GET或POST - HeaderX-Request-Id, \d # 请求头X-Request-Id必须存在且值为数字 - Querycolor, red|blue # 查询参数color必须存在且值是red或blue - CookiesessionId, . # 必须存在名为sessionId的Cookie - After2023-01-20T17:42:47.789-08:00[America/Los_Angeles] # 在此时间之后生效 # 多个断言是AND关系更多过滤器配置示例filters: - StripPrefix1 - AddRequestHeaderX-Request-Gateway, gateway-service # 添加请求头 - AddRequestParameterfoo, bar # 添加请求参数 - AddResponseHeaderX-Response-Gateway, processed # 添加响应头 - PrefixPath/v1 # 与StripPrefix相反为路径添加前缀 - RewritePath/api/v1/(?segment.*), /$\{segment} # 使用正则重写路径将/api/v1/xxx 重写为 /xxx - SetPath/api/{segment} # 设置路径可结合路径变量 - SetStatus401 # 强制设置响应状态码常用于鉴权失败 # 过滤器按配置顺序执行RewritePath过滤器详解这是一个比StripPrefix更强大的路径处理工具。它使用正则表达式进行捕获和替换。例如上面的配置原始请求/api/v1/user/info正则/api/v1/(?segment.*)会匹配整个路径并将user/info捕获到名为segment的变量中。替换模板/$\{segment}会使用捕获的变量生成新的路径/user/info。最终转发给下游服务的路径就是/user/info。注意事项在YAML中$是一个特殊字符所以需要用$\进行转义。如果你在属性文件.properties中配置直接写/${segment}即可。4. 基于Java Bean的编程式配置当路由规则非常复杂或者需要根据数据库、配置中心动态生成时配置文件就显得力不从心了。这时我们可以使用编程式配置。在Spring Boot主类或一个Configuration配置类中通过Bean定义RouteLocator。下面是一个等效于之前YAML配置的Java Bean示例import org.springframework.cloud.gateway.route.RouteLocator; import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; Configuration public class GatewayRoutesConfig { Bean public RouteLocator customRouteLocator(RouteLocatorBuilder builder) { return builder.routes() .route(user_route, r - r .path(/api/user/**) // 路径断言 .filters(f - f.stripPrefix(1)) // 过滤器 .uri(lb://user-service) // 目标URI ) .route(product_route, r - r .path(/api/product/**) .filters(f - f.stripPrefix(1)) .uri(lb://product-service) ) .build(); } }编程式配置的优势类型安全编译器会检查方法名和参数减少拼写错误。逻辑复杂可以在定义路由时嵌入复杂的判断逻辑例如从外部服务获取配置。动态性结合ApplicationEventPublisher可以在运行时动态添加、删除或更新路由虽然更复杂的动态路由通常借助RedisSpring Cloud Gateway的动态路由特性或Nacos配置中心。一个更复杂的例子结合自定义断言假设我们有一个需求只允许在特定时间段内访问某个路由。Bean public RouteLocator timedRoute(RouteLocatorBuilder builder) { // 定义一个时间断言仅在 2023年内有效 PredicateServerWebExchange timePredicate exchange - { ZonedDateTime now ZonedDateTime.now(); ZonedDateTime start ZonedDateTime.of(2023, 1, 1, 0, 0, 0, 0, ZoneId.systemDefault()); ZonedDateTime end ZonedDateTime.of(2023, 12, 31, 23, 59, 59, 999, ZoneId.systemDefault()); return now.isAfter(start) now.isBefore(end); }; return builder.routes() .route(timed_route, r - r .path(/api/special/**) .and() // 使用 and 组合多个断言 .predicate(timePredicate) // 添加自定义断言 .filters(f - f.stripPrefix(1).addRequestHeader(X-Special-Time, 2023)) .uri(lb://special-service) ) .build(); }实操心得对于绝大多数项目YAML配置完全够用且更易于维护。只有当路由规则需要与业务逻辑深度耦合例如根据用户权限动态生成路由或者需要高度动态化时才考虑使用编程式配置。初期建议先用YAML结构清晰一目了然。5. 全局过滤器与自定义过滤器实战全局过滤器会对所有经过网关的请求生效非常适合实现跨切面功能如全局鉴权、日志记录、全局流量染色等。5.1 内置全局过滤器Gateway自带的利器Spring Cloud Gateway默认已经启用了一些全局过滤器比如LoadBalancerClientFilter负责将lb://service这样的URI解析为具体的实例地址。ForwardRoutingFilter处理forward://这样的URI用于网关内部转发。NettyWriteResponseFilter和NettyRoutingFilter负责实际的网络请求写入和路由。这些我们无需配置框架已经帮我们做好了。5.2 实现自定义全局过滤器以鉴权为例让我们实现一个简单的全局鉴权过滤器检查请求头中是否包含有效的Token。步骤1创建过滤器类实现GlobalFilter接口和Ordered接口用于控制过滤器执行顺序。import org.springframework.cloud.gateway.filter.GatewayFilterChain; import org.springframework.cloud.gateway.filter.GlobalFilter; import org.springframework.core.Ordered; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; import org.springframework.web.server.ServerWebExchange; import reactor.core.publisher.Mono; Component // 声明为Spring Bean自动被加载为全局过滤器 public class AuthGlobalFilter implements GlobalFilter, Ordered { private static final String AUTH_HEADER X-Auth-Token; private static final String VALID_TOKEN secret-token-123; // 实际应从数据库或配置中心读取 Override public MonoVoid filter(ServerWebExchange exchange, GatewayFilterChain chain) { // 1. 获取请求头中的Token String token exchange.getRequest().getHeaders().getFirst(AUTH_HEADER); // 2. 简单的鉴权逻辑实际项目应使用JWT等方案 if (token null || !token.equals(VALID_TOKEN)) { // 3. 鉴权失败拦截请求 exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED); // 可以设置响应体这里简单返回空 return exchange.getResponse().setComplete(); } // 4. 鉴权通过将Token或其他用户信息传递给下游服务 // 通常我们会将解析出的用户ID等信息放入请求头 ServerHttpRequest mutatedRequest exchange.getRequest().mutate() .header(X-User-Id, parsed-user-id-from-token) // 示例 .build(); // 5. 使用修改后的请求继续执行过滤器链 return chain.filter(exchange.mutate().request(mutatedRequest).build()); } Override public int getOrder() { // 返回过滤器的执行顺序值越小优先级越高 // 鉴权过滤器通常需要在高优先级执行 return Ordered.HIGHEST_PRECEDENCE; } }关键点解析GlobalFilter接口只有一个filter方法入参是ServerWebExchange和GatewayFilterChain。ServerWebExchange可以获取请求 (getRequest())、响应 (getResponse())以及修改它们。GatewayFilterChain过滤器链调用chain.filter(exchange)会将请求传递给下一个过滤器最终到达目标服务。Ordered接口全局过滤器的执行顺序至关重要。例如鉴权 (AuthGlobalFilter) 应该在路由 (RouteToRequestUrlFilter) 之前执行否则请求可能已经被转发到下游服务了。内置过滤器都有默认的Order值我们自定义的过滤器需要通过getOrder()方法来指定。响应式编程注意返回值是MonoVoid所有操作都是非阻塞的。不要在里面执行阻塞操作如同步HTTP调用、复杂的数据库查询否则会严重影响网关性能。5.3 实现自定义网关过滤器作用于特定路由如果你希望某个过滤器只对部分路由生效可以创建自定义的GatewayFilterFactory。Spring Cloud Gateway的约定是配置文件中写的过滤器名如StripPrefix、AddRequestHeader对应一个XXXGatewayFilterFactory类。下面我们实现一个简单的“请求耗时记录”过滤器配置方式为- Elapsedtrue。步骤1创建过滤器工厂类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; import java.util.Arrays; import java.util.List; Component public class ElapsedGatewayFilterFactory extends AbstractGatewayFilterFactoryElapsedGatewayFilterFactory.Config { private static final String ELAPSED_TIME_BEGIN elapsedTimeBegin; private static final String KEY withParams; // 构造函数传递配置类 public ElapsedGatewayFilterFactory() { super(Config.class); } // 指定配置字段对应配置文件中的参数 Override public ListString shortcutFieldOrder() { return Arrays.asList(KEY); // 对应配置中的 Elapsedtrue 的 true 部分 } Override public GatewayFilter apply(Config config) { return (exchange, chain) - { // Pre Filter: 在转发请求前执行 exchange.getAttributes().put(ELAPSED_TIME_BEGIN, System.currentTimeMillis()); return chain.filter(exchange).then( Mono.fromRunnable(() - { // Post Filter: 在收到响应后执行 Long startTime exchange.getAttribute(ELAPSED_TIME_BEGIN); if (startTime ! null) { long elapsed System.currentTimeMillis() - startTime; String path exchange.getRequest().getURI().getRawPath(); System.out.println(String.format([%s] %s elapsed %d ms, exchange.getRequest().getId(), path, elapsed)); // 实际项目中应使用SLF4J日志框架并可将耗时打入监控系统如Prometheus if (config.isWithParams()) { System.out.println(Request Params: exchange.getRequest().getQueryParams()); } } }) ); }; } // 静态内部配置类 public static class Config { private boolean withParams; // 是否打印请求参数 public boolean isWithParams() { return withParams; } public void setWithParams(boolean withParams) { this.withParams withParams; } } }步骤2在路由配置中使用spring: cloud: gateway: routes: - id: user_route uri: lb://user-service predicates: - Path/api/user/** filters: - StripPrefix1 - name: Elapsed # 使用自定义过滤器 args: withParams: true # 传递给Config类的参数原理解析工厂类命名必须是XXXGatewayFilterFactory使用时配置- XXX...。继承AbstractGatewayFilterFactoryConfig其中Config是一个静态内部类用于接收YAML中的配置参数。shortcutFieldOrder()方法定义了配置参数的顺序和名称映射。apply(Config config)方法是核心它返回一个GatewayFilter函数。在这个函数里我们实现了记录开始时间Pre逻辑并在chain.filter(exchange).then()中实现记录结束时间和计算耗时的逻辑Post逻辑。这是Gateway过滤器实现“前后处理”的典型模式。避坑技巧自定义过滤器工厂时确保类名规范并且被Spring容器管理Component。如果配置了但不起作用首先检查控制台日志看过滤器工厂是否被成功加载。另外在Post Filter中操作exchange.getResponse()时要小心因为响应可能已经被提交了。6. 高级配置、监控与生产级考量一个简单的网关跑起来不难但要稳定可靠地服务于生产环境还需要考虑很多方面。6.1 高可用与集群部署网关作为流量入口必须保证高可用。常见的方案是部署多个网关实例前端通过负载均衡器如Nginx、F5、云厂商的SLB进行流量分发。无状态设计Gateway实例本身是无状态的这很方便水平扩展。只需确保所有实例连接到同一个服务注册中心Nacos/Eureka和配置中心即可。会话保持如果下游服务需要Session需要在网关或负载均衡器层面配置会话保持或者更推荐的做法是将Session外部化到Redis等存储中使服务本身无状态。6.2 集成配置中心实现动态路由生产环境的路由规则可能需要动态变更而不重启服务。可以与Nacos Config、Apollo等配置中心集成。1. 添加Nacos Config依赖dependency groupIdcom.alibaba.cloud/groupId artifactIdspring-cloud-starter-alibaba-nacos-config/artifactId /dependency2. 创建bootstrap.yml(优先级高于application.yml)spring: application: name: gateway-service profiles: active: dev cloud: nacos: config: server-addr: localhost:8848 file-extension: yaml # 指定配置格式 group: DEFAULT_GROUP namespace: public discovery: server-addr: localhost:88483. 在Nacos控制台创建Data ID为gateway-service-dev.yaml的配置内容就是你的路由规则spring: cloud: gateway: routes: - id: user_route uri: lb://user-service predicates: - Path/api/user/** filters: - StripPrefix1这样当你在Nacos中修改这个配置并发布时Gateway会自动刷新路由无需重启。6.3 监控与可观测性网关是观察系统流量的绝佳位置。务必开启监控。Spring Boot Actuator在pom.xml中引入spring-boot-starter-actuator并在配置中暴露端点特别是gateway端点。management: endpoints: web: exposure: include: health,info,gateway # 暴露gateway端点 endpoint: gateway: enabled: true # 启用gateway端点访问/actuator/gateway/routes可以查看所有已定义的路由/actuator/gateway/refresh可以手动刷新路由缓存集成配置中心后自动。指标收集Gateway自动集成了Micrometer可以将路由的请求计数、耗时、状态码等指标输出到Prometheus、InfluxDB等时序数据库再通过Grafana展示。分布式链路追踪集成Sleuth或Micrometer Tracing将网关产生的Trace ID传递到下游服务便于在Zipkin、Jaeger中查看完整请求链路。6.4 性能调优与常见问题排查1. 日志级别调整Gateway底层使用Netty和Reactor日志可能很冗长。在生产环境建议将相关日志级别调高如调整为WARN。logging: level: org.springframework.cloud.gateway: DEBUG # 开发时可设为DEBUG查看路由匹配细节 reactor.netty: WARN org.springframework.http.server.reactive: WARN2. 超时与重试配置下游服务可能响应慢或偶尔失败网关需要合理的超时和重试机制。spring: cloud: gateway: httpclient: connect-timeout: 1000 # 连接超时(ms) response-timeout: 5s # 响应超时 routes: - id: user_route uri: lb://user-service predicates: - Path/api/user/** filters: - StripPrefix1 - name: Retry # 重试过滤器 args: retries: 3 # 重试次数 statuses: BAD_GATEWAY,INTERNAL_SERVER_ERROR,SERVICE_UNAVAILABLE # 针对哪些状态码重试 methods: GET,POST # 针对哪些方法重试 backoff: firstBackoff: 100ms maxBackoff: 1s factor: 2 basedOnPreviousValue: false3. 常见问题速查表问题现象可能原因排查步骤与解决方案启动报错Failed to bind Netty server on port 8080端口被占用使用netstat -ano | findstr :8080查找占用进程并终止或修改server.port。路由配置正确但返回4041. 断言路径不匹配2. 下游服务不存在/未注册3.StripPrefix配置错误1. 检查请求路径是否完全匹配。2. 检查注册中心服务是否健康在线。3. 使用/actuator/gateway/routes端点确认路由信息使用/actuator/gateway/refresh刷新。检查过滤器是否错误地修改了路径。请求超时或无响应1. 下游服务处理慢或宕机2. 网关网络问题3. 未配置超时或配置过长1. 检查下游服务健康状态和日志。2. 检查网关与下游服务网络连通性。3. 合理配置spring.cloud.gateway.httpclient.response-timeout。集成Nacos后路由不到服务1. Nacos地址配置错误2. 服务名大小写问题3. 依赖缺失1. 检查spring.cloud.nacos.discovery.server-addr。2. Gateway默认使用服务名的小写进行查找确保Nacos中服务名是小写或使用lb://SERVICE-NAME中的服务名与注册中心完全一致。3. 确认已引入spring-cloud-starter-alibaba-nacos-discovery依赖。自定义过滤器不生效1. 过滤器类未被Spring扫描2. Order顺序问题被其他过滤器拦截3. 配置参数名称不匹配1. 确保类上有Component注解且在启动类扫描包路径下。2. 调试getOrder()返回值或通过/actuator/gateway/filters查看过滤器顺序。3. 检查shortcutFieldOrder()返回的列表与配置文件中的args键是否对应。4. 内存与线程池调优Gateway基于Netty和Reactor默认配置对大多数场景已足够。在极端高并发下可以关注以下JVM和Netty参数JVM堆内存根据流量预估设置-Xms和-Xmx。Netty工作线程通过-Dreactor.netty.ioWorkerCount(默认CPU核数*2) 和-Dreactor.netty.pool.maxConnections来调整。通常不需要改动除非监控发现明显的IO线程瓶颈。配置一个Spring Cloud Gateway网关从简单的路径转发到集成服务发现、配置动态路由再到实现自定义的全局鉴权、日志过滤器每一步都是在为你的微服务体系搭建一个稳固、智能的“城门”。记住网关的核心价值在于解耦、统一管控和提升非业务能力。启动你的第一个Gateway从监控第一个经过它的请求开始你会逐渐体会到它作为微服务架构“守门人”的重要性。在实际使用中多结合Actuator端点进行调试多观察日志和指标你会对流量有更深刻的感知。