一、场景复现
微服务自定义路由,返回404页面。
①如图:
(1)springcloud-gateway的路由设置
@Configuration
public class RouteConfig {@Beanpublic 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: truelower-case-service-id: true
(2)path路由加去掉前缀信息
cloud:gateway:routes:- id: micro-serviceuri: lb://micro-servicepredicates:- Path=/micro-service/**filters:- StripPrefix=1