SpringCloud Gateway配置自定义路由404坑

一、场景复现

微服务自定义路由,返回404页面。

①如图:

(1)springcloud-gateway的路由设置

@Configuration
public class RouteConfig {

    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route("test", r -> r.path("/csdn/**")
                        .uri("https://blog.csdn.net"))
                .route("micro-service", r -> r.path("/micro-service/**")
                        .uri("lb://micro-service"))
                .build();
    }
}

(2)micro-service的controller

@RestController
public class TestController {

    @GetMapping("/test")
    public String test(HttpServletRequest request){
        return "hello world, uri:" + request.getRequestURI();
    }

}

(3)nacos注册中心

(4)请求CSDN生效

猜测应该是lb路由不生效,于是改成yaml试试

 

 

二、route改为yaml配置

(1)配置/micro-service/**则有效②

访问结果:

(2)配置/micro/**则访问无效

访问/micro/test 404:

无意中访问/micro-service/test有结果③:

访问/micro-service1/test 抛异常:

 

三、反思现象

(1)深探问题

访问配置的路由404,访问注册的服务名有结果,访问不存在的路由则报错。非常郁闷,究竟哪里配置错误了。

猜测肯定是访问到了micro-service,但为什么没用结果。于是给micro-service服务配置默认路径,才发现原因

@RestController
public class TestController {

    @GetMapping("/test")
    public String test(HttpServletRequest request){
        return "hello world, uri:" + request.getRequestURI();
    }



    @GetMapping("/**")
    public String defaultPath(HttpServletRequest request){
        return "hello world, uri:" + request.getRequestURI();
    }
}

/micro/test请求有结果,如下: 

转发的路径多了/micro,带多一级路径转发了。

(2)查看gateway的说明文档

1)发现path和PrefixPath 的区别

path是带匹配路径转发请求,需要StripPrefix来截掉匹配模式不转发。

PrefixPath是不转发匹配的模式。

gateway path这里跟zuul的默认去掉匹配模式路径不一样,被zuul误导了。

2)gateway自动服务注册发现路由

①问题是没有gateway网关自动服务注册发现路由,通过编码的RouteLocator设置带前缀请求404

②问题是yaml配置加载后,配置了gateway网关自动服务注册发现路由,覆盖了yaml的配置,所以能访问成功

③问题是配置了gateway网关自动服务注册发现路由

 

 

四、解决方案

(1)使用服务注册自动发现路由

  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower-case-service-id: true

(2)path路由加去掉前缀信息

  cloud:
    gateway:
      routes:
      - id: micro-service
        uri: lb://micro-service
        predicates:
        - Path=/micro-service/**
        filters:
        - StripPrefix=1

 

 

Spring Cloud Gateway支持多种负载均衡策略,例如随机、轮询、权重等。如果现有的负载均衡策略不能满足你的需求,你可以自定义负载均衡策略。 首先,你需要实现`org.springframework.cloud.client.loadbalancer.reactive.LoadBalancer`接口来定义你的负载均衡策略。然后,你需要创建一个`org.springframework.cloud.gateway.filter.factory.rewrite.RewriteFunction`实例,用于将服务的URI重写为负载均衡的服务实例地址。最后,你需要将这个自定义的负载均衡策略应用到Spring Cloud Gateway路由规则中。 以下是一个示例,展示了如何定义一个基于特定请求头的自定义负载均衡策略: ```java public class CustomLoadBalancer implements LoadBalancer<ServiceInstance> { private final String headerName; public CustomLoadBalancer(String headerName) { this.headerName = headerName; } @Override public Mono<Response<ServiceInstance>> choose(Request request) { Object headerValue = request.headers().getFirst(headerName); String serviceName = "my-service"; // 根据请求头的值选择服务实例 ServiceInstance serviceInstance = ...; return Mono.just(new DefaultResponse(serviceInstance)); } } public class CustomLoadBalancerGatewayFilterFactory extends AbstractGatewayFilterFactory<CustomLoadBalancerGatewayFilterFactory.Config> { public CustomLoadBalancerGatewayFilterFactory() { super(Config.class); } @Override public GatewayFilter apply(Config config) { LoadBalancer<ServiceInstance> loadBalancer = new CustomLoadBalancer(config.getHeaderName()); RewriteFunction<String, String> rewriteFunction = uri -> { // 将URI重写为负载均衡的服务实例地址 ServiceInstance serviceInstance = loadBalancer.choose(Request.create("", new HttpHeaders())).block().getServer(); return "http://" + serviceInstance.getHost() + ":" + serviceInstance.getPort() + uri; }; return new RewritePathGatewayFilterFactory().apply(new RewritePathGatewayFilterFactory.Config().setRewriteFunction(rewriteFunction)); } public static class Config { private String headerName; public String getHeaderName() { return headerName; } public void setHeaderName(String headerName) { this.headerName = headerName; } } } ``` 在上面的示例中,`CustomLoadBalancer`实现了`LoadBalancer`接口,并基于特定的请求头选择服务实例。`CustomLoadBalancerGatewayFilterFactory`则将`CustomLoadBalancer`应用到Spring Cloud Gateway路由规则中,并将服务的URI重写为负载均衡的服务实例地址。最后,你可以在路由规则中使用`CustomLoadBalancerGatewayFilterFactory`来定义自定义的负载均衡策略。 ```yaml spring: cloud: gateway: routes: - id: my-route uri: http://my-service filters: - CustomLoadBalancer=my-header ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值