java - 间歇性接收连接重置异常
问题描述
当服务器响应时间超过 4 分钟时,我收到“连接重置”异常。该服务直到上周都运行良好,但现在我间歇性地面临这个问题。
我使用 OkHttpClient 连接到外部服务。OkHttpClient 中的所有超时都配置为 0(零),因此永远不会发生连接和读取超时。当我尝试用 curl 发出相同的请求时,我成功地得到了响应。我什至尝试将 curl 与 java 以及 REST 模板一起使用,但仍然面临同样的问题。
这是异常的完整堆栈跟踪。
javax.net.ssl.SSLException: java.net.SocketException: Connection reset
at sun.security.ssl.Alert.createSSLException(Alert.java:127) ~[na:1.8.0_271]
at sun.security.ssl.TransportContext.fatal(TransportContext.java:353) ~[na:1.8.0_271]
at sun.security.ssl.TransportContext.fatal(TransportContext.java:296) ~[na:1.8.0_271]
at sun.security.ssl.TransportContext.fatal(TransportContext.java:291) ~[na:1.8.0_271]
at sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1453) ~[na:1.8.0_271]
at sun.security.ssl.SSLSocketImpl.access$400(SSLSocketImpl.java:75) ~[na:1.8.0_271]
at sun.security.ssl.SSLSocketImpl$AppInputStream.read(SSLSocketImpl.java:931) ~[na:1.8.0_271]
at okio.Okio$2.read(Okio.java:140) ~[okio-1.15.0.jar:na]
at okio.AsyncTimeout$2.read(AsyncTimeout.java:237) ~[okio-1.15.0.jar:na]
at okio.RealBufferedSource.indexOf(RealBufferedSource.java:354) ~[okio-1.15.0.jar:na]
at okio.RealBufferedSource.readUtf8LineStrict(RealBufferedSource.java:226) ~[okio-1.15.0.jar:na]
at okhttp3.internal.http1.Http1Codec.readHeaderLine(Http1Codec.java:215) ~[okhttp-3.12.0.jar:na]
at okhttp3.internal.http1.Http1Codec.readResponseHeaders(Http1Codec.java:189) ~[okhttp-3.12.0.jar:na]
at okhttp3.internal.http.CallServerInterceptor.intercept(CallServerInterceptor.java:88) ~[okhttp-3.12.0.jar:na]
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) ~[okhttp-3.12.0.jar:na]
at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:45) ~[okhttp-3.12.0.jar:na]
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) ~[okhttp-3.12.0.jar:na]
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121) ~[okhttp-3.12.0.jar:na]
at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:93) ~[okhttp-3.12.0.jar:na]
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) ~[okhttp-3.12.0.jar:na]
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121) ~[okhttp-3.12.0.jar:na]
at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93) ~[okhttp-3.12.0.jar:na]
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) ~[okhttp-3.12.0.jar:na]
at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:126) ~[okhttp-3.12.0.jar:na]
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147) ~[okhttp-3.12.0.jar:na]
at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121) ~[okhttp-3.12.0.jar:na]
at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:254) ~[okhttp-3.12.0.jar:na]
at okhttp3.RealCall.execute(RealCall.java:92) ~[okhttp-3.12.0.jar:na]
at com.walmart.samsclub.payment.ccpa.service.services.CCPAExternalWSClient.processRequest(CCPAExternalWSClient.java:56) ~[classes/:na]
at com.walmart.samsclub.payment.ccpa.service.services.CCPASamsPaymentService.lambda$0(CCPASamsPaymentService.java:70) [classes/:na]
at java.util.ArrayList.forEach(ArrayList.java:1259) ~[na:1.8.0_271]
at com.walmart.samsclub.payment.ccpa.service.services.CCPASamsPaymentService.sendRequestToPaymentService(CCPASamsPaymentService.java:66) [classes/:na]
at com.walmart.samsclub.payment.ccpa.service.scheduler.CCPATicketUpdateSchedulerJob.updateMembershipInfo(CCPATicketUpdateSchedulerJob.java:190) ~[classes/:na]
at com.walmart.samsclub.payment.ccpa.service.scheduler.CCPATicketUpdateSchedulerJob.scheduleTaskUsingCronExpression(CCPATicketUpdateSchedulerJob.java:115) ~[classes/:na]
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) ~[spring-context-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:93) ~[spring-context-5.2.8.RELEASE.jar:5.2.8.RELEASE]
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[na:1.8.0_271]
at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[na:1.8.0_271]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) ~[na:1.8.0_271]
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) ~[na:1.8.0_271]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[na:1.8.0_271]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[na:1.8.0_271]
at java.lang.Thread.run(Thread.java:748) ~[na:1.8.0_271]
Suppressed: java.net.SocketException: Broken pipe (Write failed)
at java.net.SocketOutputStream.socketWrite0(Native Method) ~[na:1.8.0_271]
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:111) ~[na:1.8.0_271]
at java.net.SocketOutputStream.write(SocketOutputStream.java:155) ~[na:1.8.0_271]
at sun.security.ssl.SSLSocketOutputRecord.encodeAlert(SSLSocketOutputRecord.java:83) ~[na:1.8.0_271]
at sun.security.ssl.TransportContext.fatal(TransportContext.java:384) ~[na:1.8.0_271]
... 41 common frames omitted
Caused by: java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:210) ~[na:1.8.0_271]
at java.net.SocketInputStream.read(SocketInputStream.java:141) ~[na:1.8.0_271]
at sun.security.ssl.SSLSocketInputRecord.read(SSLSocketInputRecord.java:475) ~[na:1.8.0_271]
at sun.security.ssl.SSLSocketInputRecord.readHeader(SSLSocketInputRecord.java:469) ~[na:1.8.0_271]
at sun.security.ssl.SSLSocketInputRecord.bytesInCompletePacket(SSLSocketInputRecord.java:69) ~[na:1.8.0_271]
at sun.security.ssl.SSLSocketImpl.readApplicationRecord(SSLSocketImpl.java:1228) ~[na:1.8.0_271]
at sun.security.ssl.SSLSocketImpl.access$300(SSLSocketImpl.java:75) ~[na:1.8.0_271]
at sun.security.ssl.SSLSocketImpl$AppInputStream.read(SSLSocketImpl.java:915) ~[na:1.8.0_271]
... 36 common frames omitted
OkHttpClient 设置配置代码
TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
trustManagerFactory.init((KeyStore) null);
TrustManager[] trustManagers = trustManagerFactory.getTrustManagers();
if (trustManagers.length != 1 || !(trustManagers[0] instanceof X509TrustManager)) {
throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustManagers));
}
X509TrustManager trustManager = (X509TrustManager) trustManagers[0];
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[] { trustManager }, new java.security.SecureRandom());
SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
OkHttpClient.Builder builder = new OkHttpClient().newBuilder();
builder.connectTimeout(0, TimeUnit.HOURS);
builder.readTimeout(0, TimeUnit.HOURS);
builder.writeTimeout(0, TimeUnit.HOURS);
OkHttpClient okHttpClient = builder.sslSocketFactory(sslSocketFactory, trustManager).build();
logger.debug("OkHttpClient created successfully");
return okHttpClient;
调用函数
public Response processRequest(String queryParam, Headers headers, RequestBody body, HttpMethod method) {
Response res = null;
try {
Request request = buldRequest(queryParam, headers, body, method);
String requestBody = bodyToString(request);
logger.info("Request triggered {}", request.toString());
if (StringUtils.isNotBlank(requestBody)) {
logger.info("Request body {}", requestBody);
}
Call call = client.newCall(request);
res = call.execute();
if (res != null && !res.isSuccessful()) {
String responseBodyString = res.peekBody(Long.MAX_VALUE).string();
logger.error("The request was not successfull and the response code received id {} and body {}", res.code(), responseBodyString);
}
}
catch (IOException e) {
logger.error("Error while parsing data", e);
}
catch (Exception e) {
logger.error("Error occured while connecting to extenal service", e);
}
return res;
}
解决方案
推荐阅读
- ubuntu-16.04 - Salt-minions 服务在 ubuntu 上消耗超过 100% 的 CPU,无法删除它或找到它如何重新启动
- php - Laravel 对关系中的集合使用唯一性
- xamarin.forms - Xamarin Forms:以编程方式暂停在 webview 中播放的视频或音频
- python - 浏览器自动化处理基本授权登录提示
- java - 如何在 Java 中为大数编写幂函数
- javascript - mousemove 总是会在 mouseup 之前被触发吗?
- ios - 用于从超链接电话号码启动基于 SMS 的支持聊天的 iOS SDK?
- python - 将哈希“#”解析为烧瓶路由中 URL 请求中的字符串
- java - 如何使用 selenium-webdriver 和 Java 单击日历图像图标
- javascript - 如何在 Vue 中创建可重用的外部函数?