Prise en compte et contre-mesures selon lesquelles les erreurs de communication SSL sont plus susceptibles de se produire à partir de Java 11

2020/03/13 PostScript

J'en suis toujours assez content, donc j'ajouterai le statut de support.

https://github.com/apache/httpcomponents-client/pull/178 Il est pris en charge ci-dessus. https://github.com/apache/httpcomponents-client/blob/master/httpclient5/src/main/java/org/apache/hc/client5/http/impl/DefaultHttpRequestRetryStrategy.java#L123-L135

Si vous utilisez 5.0, cela semble être une solution. Seule la version RC est encore disponible.

introduction

Au moment de Java8 + Spring Boot 1.5.X, la communication était réussie à 99,9999999% ou plus, mais depuis Java11 + Spring Boot 2.1.X, l'incidence des erreurs de communication a augmenté d'environ 0,002% ... ?? J'ai pensé, je l'ai recherché.

Peut-être que c'est faux, alors je suis vraiment heureux si vous pouvez souligner diverses choses. Cela aide beaucoup.

Erreur qui se produit

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

Ce qui m'a dérangé.

La réponse à laquelle vous êtes arrivé

Lorsque je vérifiais sur le bureau et que je recherchais des bogues dans JDK, Spring Boot et HttpClient, j'ai soudainement remarqué quelque chose.

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

est. L'erreur renvoyée a changé ...? Certainement SSLException. Ce n'est pas une erreur comme la poignée de main, mais SSLException. Pour SSLException, DefaultHttpRequestRetryHandler # INSTANCE de httpclient (/org/apache/http/impl/client/DefaultHttpRequestRetryHandler.html#INSTANCE) ne réessaye pas la communication.

Je vois. Je me demande s'il semble qu'il y ait eu plus d'erreurs parce qu'elles n'ont pas été retentées. Je suis arrivé maintenant. Bien sûr, lorsque vous obtenez cette erreur, vous obtenez l'erreur juste après avoir essayé de démarrer la connexion.

Il semble qu'il soit rétroporté, mais il semble que SSLException soit toujours retourné.

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

Pour autant que je puisse voir, cela ressemble à ce qui suit ... Je veux dire, tant que j'appelle ʻAlert # createSSLException`, je ne peux rien renvoyer d'autre que SSLException.

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

Correspondance

Remplacez le retryRequest de DefaultHttpRequestRetryHandler comme indiqué ci-dessous

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);
    }
  }

Je me demande si je devrais le définir comme suit.

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

Mais y a-t-il une meilleure façon? Je pose une question sur le débordement de pile.

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

Cependant, comme je l'ai écrit ci-dessus, il est difficile d'obtenir une réponse sur la réinitialisation de la connexion, et je ne sais pas si je peux comprendre l'anglais en premier lieu, alors je me demande si je peux obtenir des opinions.

référence

Erreur pour 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

Prise en compte et contre-mesures selon lesquelles les erreurs de communication SSL sont plus susceptibles de se produire à partir de Java 11
10 barrages de dessin avec ● ou ■ qui sont susceptibles d'apparaître dans la formation (Java)
[Ruby] 5 erreurs courantes qui ont tendance à se produire lors du scraping avec Selenium et comment les gérer
Fonctionnalités susceptibles d'entrer dans Java 10 pour le moment
Trouvez la classe d'adresse et le type d'adresse à partir de l'adresse IP avec Java
Je veux revenir à l'écran précédent avec kotlin et java!
Gère diverses erreurs (exceptions) qui se produisent lors de la communication HTTP avec RestTemplate
De Java naissant (3 ans) à Node.js (4 ans). Et l'impression de retourner à Java
[Java] Comment convertir du type String en type Path et obtenir le chemin
La route de JavaScript à Java
Trouvez la classe d'adresse et le type d'adresse à partir de l'adresse IP avec Java [décoction n ° 2]
Mettez à jour JAVA vers la dernière version vers 1.8.0_144 (lors du téléchargement à partir du Web et de la mise à jour)
J'ai essayé de traduire la grammaire de R et Java [Mis à jour de temps en temps]
J'ai créé un programme qui recherche la classe cible à partir du processus surchargé avec Java