SpringBoot3升级后QuotaGuard代理调用API报NoHttpResponseException求助
升级至Java 17+Spring Boot 3.0+HttpClient5 5.2.1后通过QuotaGuard代理调用外部API出现NoHttpResponseException异常
我们的应用原本基于Java 8+Spring Boot 2.7+HttpClient 4.5,通过QuotaGuard代理连接外部API,近期升级到Java 17+Spring Boot 3.0+HttpClient5 5.2.1后,调用API时频繁抛出org.apache.hc.core5.http.NoHttpResponseException异常,报错日志如下:
Nov 29 02:57:08 app/web.1 org.springframework.web.client.ResourceAccessException: I/O error on POST request for "[https://test.com/postInfo]": [test.com:443] failed to respond Nov 29 02:57:08 app/web.1 at org.springframework.web.client.RestTemplate.createResourceAccessException(RestTemplate.java:888) Nov 29 02:57:08 app/web.1 at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:868) Nov 29 02:57:08 app/web.1 at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:764) Nov 29 02:57:08 app/web.1 at org.springframework.web.client.RestTemplate.postForEntity(RestTemplate.java:512) Nov 29 02:57:08 app/web.1 at jp.co.demo.service.WinnerExportServiceImpl$3.doWithRetry(WinnerExportServiceImpl.java:381) Nov 29 02:57:08 app/web.1 at jp.co.demo.service.WinnerExportServiceImpl$3.doWithRetry(WinnerExportServiceImpl.java:376) Nov 29 02:57:08 app/web.1 at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:286) Nov 29 02:57:08 app/web.1 at org.springframework.retry.support.RetryTemplate.execute(RetryTemplate.java:179) Nov 29 02:57:08 app/web.1 at jp.co.demo.service.WinnerExportServiceImpl.execute(WinnerExportServiceImpl.java:376) Nov 29 02:57:08 app/web.1 at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) Nov 29 02:57:08 app/web.1 at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) Nov 29 02:57:08 app/web.1 at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) Nov 29 02:57:08 app/web.1 at java.base/java.lang.reflect.Method.invoke(Method.java:568) Nov 29 02:57:08 app/web.1 at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343) Nov 29 02:57:08 app/web.1 at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196) Nov 29 02:57:08 app/web.1 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) Nov 29 02:57:08 app/web.1 at org.springframework.aop.interceptor.AsyncExecutionInterceptor.lambda$invoke$0(AsyncExecutionInterceptor.java:115) Nov 29 02:57:08 app/web.1 at org.springframework.util.concurrent.FutureUtils.lambda$toSupplier$0(FutureUtils.java:74) Nov 29 02:57:08 app/web.1 at java.base/java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1768) Nov 29 02:57:08 app/web.1 at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) Nov 29 02:57:08 app/web.1 at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) Nov 29 02:57:08 app/web.1 at java.base/java.lang.Thread.run(Thread.java:840) Nov 29 02:57:08 app/web.1 Caused by: org.apache.hc.core5.http.NoHttpResponseException: [test.com:443] failed to respond Nov 29 02:57:08 app/web.1 at org.apache.hc.core5.http.impl.io.DefaultHttpResponseParser.createConnectionClosedException(DefaultHttpResponseParser.java:87) Nov 29 02:57:08 app/web.1 at org.apache.hc.core5.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:243) Nov 29 02:57:08 app/web.1 at org.apache.hc.core5.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:53) Nov 29 02:57:08 app/web.1 at org.apache.hc.core5.http.impl.io.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:298) Nov 29 02:57:08 app/web.1 at org.apache.hc.core5.http.impl.io.HttpRequestExecutor.execute(HttpRequestExecutor.java:175) Nov 29 02:57:08 app/web.1 at org.apache.hc.core5.http.impl.io.HttpRequestExecutor.execute(HttpRequestExecutor.java:218) Nov 29 02:57:08 app/web.1 at org.apache.hc.client5.http.impl.io.PoolingHttpClientConnectionManager$InternalConnectionEndpoint.execute(PoolingHttpClientConnectionManager.java:712) Nov 29 02:57:08 app/web.1 at org.apache.hc.client5.http.impl.classic.InternalExecRuntime.execute(InternalExecRuntime.java:216) Nov 29 02:57:08 app/web.1 at org.apache.hc.client5.http.impl.classic.ConnectExec.createTunnelToTarget(ConnectExec.java:233) Nov 29 02:57:08 app/web.1 at org.apache.hc.client5.http.impl.classic.ConnectExec.execute(ConnectExec.java:151) Nov 29 02:57:08 app/web.1 at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51) Nov 29 02:57:08 app/web.1 at org.apache.hc.client5.http.impl.classic.ProtocolExec.execute(ProtocolExec.java:192) Nov 29 02:57:08 app/web.1 at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51) Nov 29 02:57:08 app/web.1 at org.apache.hc.client5.http.impl.classic.HttpRequestRetryExec.execute(HttpRequestRetryExec.java:96) Nov 29 02:57:08 app/web.1 at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51) Nov 29 02:57:08 app/web.1 at org.apache.hc.client5.http.impl.classic.ContentCompressionExec.execute(ContentCompressionExec.java:152) Nov 29 02:57:08 app/web.1 at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51) Nov 29 02:57:08 app/web.1 at org.apache.hc.client5.http.impl.classic.RedirectExec.execute(RedirectExec.java:115) Nov 29 02:57:08 app/web.1 at org.apache.hc.client5.http.impl.classic.ExecChainElement.execute(ExecChainElement.java:51) Nov 29 02:57:08 app/web.1 at org.apache.hc.client5.http.impl.classic.InternalHttpClient.doExecute(InternalHttpClient.java:170) Nov 29 02:57:08 app/web.1 at org.apache.hc.client5.http.impl.classic.CloseableHttpClient.execute(CloseableHttpClient.java:106) Nov 29 02:57:08 app/web.1 at org.apache.hc.client5.http.impl.classic.CloseableHttpClient.execute(CloseableHttpClient.java:55) Nov 29 02:57:08 app/web.1 at org.springframework.http.client.HttpComponentsClientHttpRequest.executeInternal(HttpComponentsClientHttpRequest.java:93) Nov 29 02:57:08 app/web.1 at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48) Nov 29 02:57:08 app/web.1 at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:66) Nov 29 02:57:08 app/web.1 at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:862) Nov 29 02:57:08 app/web.1 ... 20 more
当前使用的代理配置及请求代码如下:
URL proxy; proxy = new URL(proxyUrl); String userInfo = proxy.getUserInfo(); String user = userInfo.substring(0, userInfo.indexOf(':')); String password = userInfo.substring(userInfo.indexOf(':') + 1); final CredentialsProvider credsProvider = new BasicCredentialsProvider(); Credentials credentials = new UsernamePasswordCredentials(user, password.toCharArray()); ((BasicCredentialsProvider) credsProvider).setCredentials(new AuthScope(proxy.getHost(), proxy.getPort()), credentials); HttpHost p = new HttpHost(proxy.getHost(), proxy.getPort()); HttpClient httpClient = HttpClients.custom().setProxy(p).setDefaultCredentialsProvider(credsProvider).build(); final HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(); factory.setHttpClient(httpClient); RestTemplate restTemplate = new RestTemplate(factory); ResponseEntity<ResponseData> response = restTemplate.postForEntity(APIURL, req, ResponseData.class); ResponseData responseBody = response.getBody();
通过命令行curl和Postman借助QuotaGuard代理请求同一API均能成功,求解决思路或可行方案。
内容的提问来源于stack exchange,提问作者Monirul Islam
相关产品推荐
相关产品推荐

