Spring WebClient调用同Docker网络微服务返回无信息404如何解决
问题根因与解决思路
可能的核心原因
- 路由匹配条件不满足:你的路由配置明确指定了
accept(APPLICATION_JSON)匹配规则,仅接收Accept头为application/json的请求,但WebClient请求中设置的Accept是APPLICATION_OCTET_STREAM,头信息不匹配导致路由未命中,返回404。 - 路径拼接规则异常:路由嵌套前缀
"/list/"末尾携带斜杠,和后续路径"{id}/attachment"拼接后实际匹配规则为/list//{id}/attachment,和实际请求路径/list/25283/attachment不匹配。 - Spring Cloud服务发现干扰:项目引入Eureka和负载均衡依赖后,Spring会自动增强WebClient,将baseUrl中的
attachment-loader-sec作为服务名从注册中心拉取实例,可能拉取到错误的实例地址,导致请求发往错误的服务。 - 服务监听地址配置错误:目标服务的Spring进程仅监听了容器内的
127.0.0.1:8086,未绑定0.0.0.0,导致外部容器的请求无法进入Spring进程,被容器内其他进程返回404。 - 上下文路径配置遗漏:目标服务配置了
server.webflux.base-path(WebFlux)或server.servlet.context-path(Spring MVC)前缀,实际接口路径比请求路径多了一层上下文前缀,导致404。
排查解决步骤
- 优先修改路由匹配条件:要么删除路由配置中的
accept(APPLICATION_JSON)规则,要么将WebClient的Accept配置修改为同时支持两种类型:.accept(MediaType.APPLICATION_JSON, MediaType.APPLICATION_OCTET_STREAM),验证接口是否能通。 - 修正路径拼接格式:将路由嵌套前缀修改为
"/list"(去掉末尾斜杠),避免多斜杠导致的路径匹配失败。 - 验证请求是否到达目标服务:进入
attachment-loader-prim容器执行以下命令,模拟WebClient请求,同时观察目标容器日志:
如果curl返回404且目标容器无日志,进入目标容器执行curl -v -X POST -H "Content-Type: application/json" -H "Accept: application/octet-stream" -d '[{"测试参数"}]' http://attachment-loader-sec:8086/list/25283/attachmentnetstat -tunlp | grep 8086,检查端口绑定地址是否为0.0.0.0,如果不是修改服务监听地址配置。 - 排除服务发现干扰:临时将WebClient的baseUrl修改为目标容器的实际IP+端口
http://[目标容器IP]:8086/list,如果访问正常说明Eureka负载均衡逻辑干扰了WebClient的请求路径,可通过声明非负载均衡的WebClient.Builder Bean解决:@Bean @Qualifier("nonLoadBalanced") fun fetcherWebClientBuilder(): WebClient.Builder = WebClient.builder().baseUrl("http://attachment-loader-sec:8086/list") - 调整日志级别:将目标服务的
org.springframework.web包日志级别调整为DEBUG,确认404请求是否被Spring接收,避免因日志级别过高导致请求记录缺失。 - 检查上下文路径配置:查看目标服务配置文件是否存在
server.webflux.base-path或server.servlet.context-path配置,如果存在需要将该前缀添加到WebClient的baseUrl中。
内容的提问来源于stack exchange,提问作者Vladislav Ashikhin
相关产品推荐
相关产品推荐

