解决Spring Cloud Gateway路由问题 503

发布时间 2023-11-23 22:33:30作者: just1t

近期在配置 Spring Cloud Gateway 进行路由时,遇到了一些问题,经过一番排查和调试,最终解决了问题。在这篇博客中,我将分享遇到的问题、解决过程以及最终的解决方案。

问题背景

我使用 Spring Cloud Gateway 构建微服务架构时,希望通过网关实现请求的路由。然而,在配置路由规则时,我遇到了一些意外的问题。具体来说,我发现无法通过网关将请求正确地路由到后端服务。

第一步:打印请求进行排查

为了更好地了解问题的根本原因,我决定在 Spring Cloud Gateway 中添加一个过滤器,用于打印网关获取的请求信息。通过打印请求,我希望能够判断是前端还是后端出现了问题。

import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Component
public class LoggingFilter implements GlobalFilter {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 打印请求信息
        System.out.println("Request URI: " + exchange.getRequest().getURI());
        // 其他打印操作...

        // 继续执行过滤器链
        return chain.filter(exchange);
    }
}

通过这个过滤器,我成功地在控制台上看到了每个请求的详细信息。

第二步:确认是前端还是后端出现问题

通过打印请求信息,我发现网关成功地获取到了请求,但请求未能成功路由到后端服务。为了进一步排查问题,我配置了一系列的路由规则,包括将请求直接路由到后端服务的规则,以判断是前端还是后端出现了问题。

发现问题:跨域问题

在排查过程中,我怀疑问题可能与跨域请求有关。于是,我尝试配置跨域支持,包括在网关中添加跨域配置,但问题依然存在。

@Configuration
public class CorsConfig {

    @Bean
    public CorsWebFilter corsWebFilter() {
        CorsConfiguration corsConfiguration = new CorsConfiguration();
        corsConfiguration.addAllowedHeader("*");
        corsConfiguration.addAllowedMethod("*");
        corsConfiguration.addAllowedOrigin("*");
        corsConfiguration.setAllowCredentials(true);

        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
        source.registerCorsConfiguration("/**", corsConfiguration);

        return new CorsWebFilter(source);
    }
}

最终解决:Ribbon负载均衡

最后我将uri直接修改为地址进行路由,结果成功了。

在一番搜索和资料查阅后,我发现在 Spring Cloud 2020 版本中,Ribbon 已经被弃用,无法再通过 lb 进行路由。而我的配置中正是使用了 lb 关键字。

解决办法是导入负载均衡支持,确保项目中包含了相关依赖。在我的情况下,我添加了以下依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

导入负载均衡支持后,我将路由规则中的 lb 修改为直接写明后端服务的地址,问题迎刃而解。

spring:
  cloud:
    gateway:
      routes:
        - id: my-route
          uri: http://backend-service
          predicates:
            - Path=/api/**