Spring Boot中WebClient通过代理访问第三方服务失败排查
问题与解决方案
问题背景
企业代理服务器后的Spring Boot应用中,使用WebClient访问第三方服务(如https://google.com)始终失败,但RestTemplate配置相同代理、curl加--proxy参数均可正常访问。仅修改/etc/hosts绑定域名IP能让WebClient工作,但该方案不被管理员允许。
WebClient日志显示DNS解析超时:
2025-04-25T11:04:13.473Z DEBUG 596368 --- [reactor-http-epoll-2] reactor.netty.http.client.HttpClient : from /156.24.14.11:53 : DefaultDnsQuestion(google.com. IN A) failure io.netty.resolver.dns.DnsNameResolverTimeoutException: [16194: /156.24.14.11:53] DefaultDnsQuestion(google.com. IN A) query '16194' via UDP timed out after 5000 milliseconds (no stack trace available)
环境版本:
- netty 4.1.114.Final
- spring-webflux-6.1.14
- spring-boot-starter-parent 3.3.5
已尝试添加.resolver(DefaultAddressResolverGroup.INSTANCE)、.proxyWithSystemProperties()均无效。
原因分析
RestTemplate默认会将域名解析请求交给代理服务器处理,而Reactor Netty的HttpClient默认是本地进行DNS解析。在企业代理环境下,本地DNS无法访问外部域名的解析服务,导致超时。
解决方案
修改WebClient的代理配置,开启resolveAddressViaProxy,让代理服务器负责DNS解析:
String someUrl = "https://google.com"; HttpClient httpclient = HttpClient.create() .proxy(proxy -> proxy .type(ProxyProvider.Proxy.HTTP) .host("10.20.30.40") .port(12345) .resolveAddressViaProxy(true) // 关键配置:让代理处理DNS解析 .build()) .wiretap("reactor.netty.http.client.HttpClient", LogLevel.DEBUG, AdvancedByteBufFormat.TEXTUAL) .resolver(spec -> spec.trace("reactor.netty.http.client.HttpClient", LogLevel.DEBUG)); WebClient webClient = WebClient.builder() .clientConnector(new ReactorClientHttpConnector(httpclient)) .build(); String response = webClient.get().uri(someUrl).retrieve().bodyToMono(String.class).block();
验证说明
添加resolveAddressViaProxy(true)后,HttpClient会将域名发送给代理服务器,由代理完成DNS解析并建立连接,和RestTemplate、curl的行为保持一致,从而解决本地DNS解析超时的问题。
内容的提问来源于stack exchange,提问作者jan
相关产品推荐
相关产品推荐

