SpringBoot应用调用myhost.com API陷入等待状态问题求助
问题描述
我需要调用以下GET API:https://myhost.com/api/option-chain-indices?symbol=ALL
该接口在浏览器、PostMan等REST客户端中能正常返回结果,但在SpringBoot项目中调用时会陷入无限等待(超过30分钟仍无响应)。项目中调用其他第三方API均正常,仅该域名下的此接口出现问题。
我尝试了两种调用方式均失败:
方式1:HttpURLConnection
public void myFunction() { String output = ""; Root data = null; try { URL url1 = new URL("https://myhost.com/api/option-chain-indices?symbol=ALL"); HttpURLConnection connection1 = (HttpURLConnection) url1.openConnection(); connection1.setRequestMethod("GET"); connection1.setRequestProperty("Accept", "application/json"); if (connection1.getResponseCode() != 200) { System.out.println("NSE INIT : Failed : HTTP Error code : " + connection1.getResponseCode()); } else { InputStreamReader in = new InputStreamReader(connection1.getInputStream()); BufferedReader br = new BufferedReader(in); while ((output = br.readLine()) != null) { data = objectMapper.readValue(output, Root.class); } } connection1.disconnect(); } catch (Exception e) { System.out.println("Exception" + e); } }
方式2:WebClient
@Service public class MyService { private final WebClient webClient; public MyService(WebClient.Builder webClientBuilder) { this.webClient = webClientBuilder.build(); } public void fetchDataFromAPI() { System.out.println("Get Data ...."); this.webClient.get() .uri("https://myhost.com/api/option-chain-indices?symbol=ALL") .retrieve() .bodyToMono(String.class) .subscribe(response -> { // Handle the response here System.out.println("Received response: " + response); }); } }
请求协助排查问题原因及解决方法。
排查方向与解决方法
1. 补充请求头差异
浏览器、PostMan会自动携带User-Agent、Accept-Encoding等请求头,部分服务端会依赖这些头判断请求合法性,缺失可能导致响应卡住。
- 给HttpURLConnection添加请求头:
connection1.setRequestProperty("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"); connection1.setRequestProperty("Accept-Encoding", "gzip, deflate, br");
- 给WebClient添加请求头:
this.webClient.get() .uri("https://myhost.com/api/option-chain-indices?symbol=ALL") .header("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36") .header("Accept-Encoding", "gzip, deflate, br") .retrieve() .bodyToMono(String.class) .subscribe(response -> { System.out.println("Received response: " + response); });
2. 强制设置超时时间
你的代码未配置超时,导致请求无限制挂起,必须添加连接超时和读取超时:
- HttpURLConnection设置超时:
connection1.setConnectTimeout(10000); // 10秒连接超时 connection1.setReadTimeout(30000); // 30秒读取超时
- WebClient全局配置超时:
@Bean public WebClient webClient() { HttpClient httpClient = HttpClient.create() .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 10000) .responseTimeout(Duration.ofSeconds(30)); return WebClient.builder() .clientConnector(new ReactorClientHttpConnector(httpClient)) .build(); }
3. 检查代理配置
浏览器/PostMan可能配置了代理,而SpringBoot默认未使用代理导致无法访问目标服务。可以在代码中手动设置代理:
- HttpURLConnection设置代理:
Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("你的代理地址", 代理端口)); HttpURLConnection connection1 = (HttpURLConnection) url1.openConnection(proxy);
- WebClient设置代理:
HttpClient httpClient = HttpClient.create() .proxy(proxy -> proxy.type(ProxyProvider.Proxy.HTTP) .host("你的代理地址") .port(代理端口)); WebClient webClient = WebClient.builder() .clientConnector(new ReactorClientHttpConnector(httpClient)) .build();
4. 排查SSL证书信任问题
目标服务的SSL证书可能未被JVM信任,导致连接卡住。可以:
- 将目标证书导入JVM信任库(生产环境推荐);
- 临时禁用SSL验证(仅测试用,生产环境禁止):
WebClient禁用SSL验证示例:
SslContext sslContext = SslContextBuilder.forClient() .trustManager(InsecureTrustManagerFactory.INSTANCE) .build(); HttpClient httpClient = HttpClient.create() .secure(t -> t.sslContext(sslContext)); WebClient webClient = WebClient.builder() .clientConnector(new ReactorClientHttpConnector(httpClient)) .build();
5. 抓包对比请求差异
用Wireshark或tcpdump抓包,对比浏览器/PostMan和SpringBoot项目的请求:
- 确认请求是否成功发送到目标服务器;
- 检查服务端是否返回响应;
- 排查是否存在请求参数、头信息的差异。
也可以联系目标服务运维人员,查看服务器日志,确认请求是否被接收、处理时是否出现异常。
内容的提问来源于stack exchange,提问作者nSense
相关产品推荐
相关产品推荐

