Überlegungen und Gegenmaßnahmen, dass SSL-Kommunikationsfehler häufiger in Java 11 auftreten

Nachtrag 2020/03/13

Ich bin immer noch ziemlich zufrieden damit, also werde ich den Support-Status hinzufügen.

https://github.com/apache/httpcomponents-client/pull/178 Es wird oben unterstützt. https://github.com/apache/httpcomponents-client/blob/master/httpclient5/src/main/java/org/apache/hc/client5/http/impl/DefaultHttpRequestRetryStrategy.java#L123-L135

Wenn Sie 5.0 verwenden, scheint dies eine Lösung zu sein. Bisher ist nur die RC-Version verfügbar.

Einführung

Zum Zeitpunkt von Java8 + Spring Boot 1.5.X war die Kommunikation mit 99,9999999% oder mehr erfolgreich, aber seit Java11 + Spring Boot 2.1.X hat die Häufigkeit von Kommunikationsfehlern um etwa 0,002% zugenommen ... ?? Ich dachte, ich habe nachgeschlagen.

Vielleicht ist es falsch, also bin ich wirklich froh, wenn Sie auf verschiedene Dinge hinweisen können. Das hilft sehr.

Fehler, der auftritt

javax.net.ssl.SSLException: Connection reset
    at java.base/sun.security.ssl.Alert.createSSLException(Alert.java:127)
    at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:321)
    at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:264)
    at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:259)
    at java.base/sun.security.ssl.SSLSocketImpl.handleException(SSLSocketImpl.java:1314)
    at java.base/sun.security.ssl.SSLSocketImpl$AppInputStream.read(SSLSocketImpl.java:839)
    at org.apache.http.impl.io.SessionInputBufferImpl.streamRead(SessionInputBufferImpl.java:137)
    at org.apache.http.impl.io.SessionInputBufferImpl.fillBuffer(SessionInputBufferImpl.java:153)
    at org.apache.http.impl.io.SessionInputBufferImpl.readLine(SessionInputBufferImpl.java:280)
    at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:138)
    at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:56)
    at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:259)
    at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:163)
    at org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:157)
    at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:273)
    at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:125)
    at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:272)
    at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:186)
    at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
    at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:110)
    at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
    at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56)
    at org.springframework.http.client.HttpComponentsClientHttpRequest.executeInternal(HttpComponentsClientHttpRequest.java:87)
    at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
    at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53)
    at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:735)
    ... 81 common frames omitted
    Suppressed: java.net.SocketException: Broken pipe (Write failed)
        at java.base/java.net.SocketOutputStream.socketWrite0(Native Method)
        at java.base/java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:110)
        at java.base/java.net.SocketOutputStream.write(SocketOutputStream.java:150)
        at java.base/sun.security.ssl.SSLSocketOutputRecord.encodeAlert(SSLSocketOutputRecord.java:81)
        at java.base/sun.security.ssl.TransportContext.fatal(TransportContext.java:352)
        ... 106 common frames omitted
Caused by: java.net.SocketException: Connection reset
    at java.base/java.net.SocketInputStream.read(SocketInputStream.java:186)
    at java.base/java.net.SocketInputStream.read(SocketInputStream.java:140)
    at java.base/sun.security.ssl.SSLSocketInputRecord.read(SSLSocketInputRecord.java:448)
    at java.base/sun.security.ssl.SSLSocketInputRecord.bytesInCompletePacket(SSLSocketInputRecord.java:68)
    at java.base/sun.security.ssl.SSLSocketImpl.readApplicationRecord(SSLSocketImpl.java:1104)
    at java.base/sun.security.ssl.SSLSocketImpl$AppInputStream.read(SSLSocketImpl.java:823)
    ... 102 common frames omitted

Was hat mich gestört?

--Dieser Fehler tritt eher nur bei bestimmten LBs (GCPs) auf. (Andere sind stabil und es tritt kein Fehler auf)
Also
https://stackoverflow.com/questions/49624532/java-net-socketexception-connection-reset-on-gcp
Ich zweifelte zuerst. Aber mit Java8 gibt es keinen Fehler. Immerhin Java 11 verwandt ...?

Die Antwort, zu der Sie gekommen sind

Als ich auf dem Schreibtisch nach Fehlern in JDK, Spring Boot und HttpClient suchte, bemerkte ich plötzlich etwas.

https://bugs.openjdk.java.net/browse/JDK-8214339

ist. Der zurückgegebene Fehler hat sich geändert ...? Sicherlich SSLException. Es ist kein Fehler wie Handshake, sondern SSLException. Für SSLException DefaultHttpRequestRetryHandler # INSTANCE von httpclient (/org/apache/http/impl/client/DefaultHttpRequestRetryHandler.html#INSTANCE) wiederholt die Kommunikation nicht.

Das war's. Ich frage mich, ob es anscheinend mehr Fehler gab, weil sie nicht wiederholt wurden. Ich bin jetzt angekommen. Wenn dieser Fehler auftritt, tritt der Fehler natürlich unmittelbar nach dem Versuch auf, die Verbindung herzustellen.

Es scheint, dass es zurückportiert wird, aber es scheint, dass SSLException immer noch zurückgegeben wird.

http://hg.openjdk.java.net/jdk/jdk12/rev/9041178a0b69

Soweit ich sehen kann, sieht es wie folgt aus ... Ich meine, solange ich "Alert # createSSLException" aufrufe, kann ich nichts anderes als SSLException zurückgeben.

+        if ((cause != null) && (cause instanceof IOException)) {
+            ssle = new SSLException(reason);
+        } 

Korrespondenz

Überschreiben Sie die retryRequest von DefaultHttpRequestRetryHandler wie unten gezeigt

HttpRequestRetryHandler.java


  public class HttpRequestRetryHandler extends DefaultHttpRequestRetryHandler {

    @Override
    public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
      IOException cause = exception;
      if (exception instanceof SSLException) {
        if (exception.getCause() != null && exception.getCause() instanceof IOException) {
          cause = (IOException) exception.getCause();
        }
      }
      return super.retryRequest(cause, executionCount, context);
    }
  }

Ich frage mich, ob ich es wie folgt einstellen soll.

CloseableHttpClient httpclient = HttpClients.custom()
        .setRetryHandler(new HttpRequestRetryHandler())
        .build();

Aber gibt es einen besseren Weg? Ich stelle eine Frage zum Stapelüberlauf.

https://stackoverflow.com/questions/56306216/how-can-i-retry-using-defaulthttprequestretryhandlerhttpclient-when-socketexce

Wie ich oben geschrieben habe, ist es jedoch schwierig, eine Antwort zum Zurücksetzen der Verbindung zu erhalten, und ich weiß nicht, ob ich überhaupt Englisch verstehen kann. Daher frage ich mich, ob ich eine Meinung dazu bekommen kann.

Referenz

Fehler für Java8

Caused by: org.springframework.web.client.ResourceAccessException: I/O error on POST request for "https://xxxxxxxxx": Connection reset; nested exception is java.net.SocketException: Connection reset
	at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:674)
	at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:636)
	at org.springframework.web.client.RestTemplate.exchange(RestTemplate.java:598)
	... 54 common frames omitted
Caused by: java.net.SocketException: Connection reset
	at java.net.SocketInputStream.read(SocketInputStream.java:210)
	at java.net.SocketInputStream.read(SocketInputStream.java:141)
	at sun.security.ssl.InputRecord.readFully(InputRecord.java:465)
	at sun.security.ssl.InputRecord.read(InputRecord.java:503)
	at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:975)
	at sun.security.ssl.SSLSocketImpl.readDataRecord(SSLSocketImpl.java:933)
	at sun.security.ssl.AppInputStream.read(AppInputStream.java:105)
	at org.apache.http.impl.io.SessionInputBufferImpl.streamRead(SessionInputBufferImpl.java:137)
	at org.apache.http.impl.io.SessionInputBufferImpl.fillBuffer(SessionInputBufferImpl.java:153)
	at org.apache.http.impl.io.SessionInputBufferImpl.readLine(SessionInputBufferImpl.java:282)
	at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:138)
	at org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:56)
	at org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:259)
	at org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:163)
	at org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:165)
	at org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:273)
	at org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:125)
	at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:272)
	at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:185)
	at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
	at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:111)
	at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
	at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:56)
	at org.springframework.http.client.HttpComponentsClientHttpRequest.executeInternal(HttpComponentsClientHttpRequest.java:89)
	at org.springframework.http.client.AbstractBufferingClientHttpRequest.executeInternal(AbstractBufferingClientHttpRequest.java:48)
	at org.springframework.http.client.AbstractClientHttpRequest.execute(AbstractClientHttpRequest.java:53)
	at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:660)
	... 58 common frames omitted

Recommended Posts

Überlegungen und Gegenmaßnahmen, dass SSL-Kommunikationsfehler häufiger in Java 11 auftreten
10 Sperrfeuer mit ● oder ■, die wahrscheinlich im Training auftreten (Java)
[Ruby] 5 häufige Fehler, die beim Schaben mit Selen auftreten und wie man damit umgeht
Funktionen, die derzeit wahrscheinlich in Java 10 eingegeben werden
Suchen Sie die Adressklasse und den Adresstyp aus der IP-Adresse mit Java
Ich möchte mit Kotlin und Java zum vorherigen Bildschirm zurückkehren!
Behandelt verschiedene Fehler (Ausnahmen), die während der HTTP-Kommunikation mit RestTemplate auftreten
Vom jungen Java (3 Jahre) bis zu Node.js (4 Jahre). Und der Eindruck, nach Java zurückzukehren
[Java] So konvertieren Sie vom Typ String in den Pfadtyp und erhalten den Pfad
Der Weg von JavaScript nach Java
Finden Sie die Adressklasse und den Adresstyp aus der IP-Adresse mit Java [Abkochung Nr. 2]
Aktualisieren Sie JAVA auf die neueste Version auf 1.8.0_144 (beim Herunterladen aus dem Internet und Aktualisieren)
Ich habe versucht, die Grammatik von R und Java zu übersetzen [Von Zeit zu Zeit aktualisiert]
Ich habe ein Programm erstellt, das aus dem mit Java überladenen Prozess nach der Zielklasse sucht