Time-out van HttpClient

1. Overzicht

Deze tutorial laat zien hoe configureer een time-out met de Apache HttpClient 4.

Als je dieper wilt graven en andere coole dingen wilt leren die je kunt doen met de HttpClient - ga dan naar de belangrijkste HttpClient tutorial.

2. Time-outs eerder configureren HttpClient 4.3

2.1. Rauw Draad Parameters

Voordat versie 4.3 uitkwam, was het HttpClient kwam met veel configuratieparameters, en deze konden allemaal op een generieke, kaartachtige manier worden ingesteld.

Er waren 3 time-outparameters om te configureren:

DefaultHttpClient httpClient = nieuwe DefaultHttpClient (); int time-out = 5; // seconden HttpParams httpParams = httpClient.getParams (); httpParams.setParameter (CoreConnectionPNames.CONNECTION_TIMEOUT, time-out * 1000); httpParams.setParameter (CoreConnectionPNames.SO_TIMEOUT, time-out * 1000); httpParams.setParameter (ClientPNames.CONN_MANAGER_TIMEOUT, nieuw Lang (time-out * 1000));

2.2. API

De belangrijkste van deze parameters - namelijk de eerste twee - zou ook kunnen worden ingesteld via een meer typeveilige API:

DefaultHttpClient httpClient = nieuwe DefaultHttpClient (); int time-out = 5; // seconden HttpParams httpParams = httpClient.getParams (); HttpConnectionParams.setConnectionTimeout (httpParams, time-out * 1000); // http.connection.timeout HttpConnectionParams.setSoTimeout (http.connection.timeout * 1000); // http.socket.timeout

De derde parameter heeft geen aangepaste setter in HttpConnectionParams, en het moet nog steeds handmatig worden ingesteld via de setParameter methode.

3. Configureer time-outs met behulp van de nieuwe 4.3. Bouwer

De vloeiende, bouwer-API die in 4.3 is geïntroduceerd, biedt de juiste manier om time-outs op een hoog niveau in te stellen:

int time-out = 5; RequestConfig config = RequestConfig.custom () .setConnectTimeout (time-out * 1000) .setConnectionRequestTimeout (time-out * 1000) .setSocketTimeout (time-out * 1000) .build (); CloseableHttpClient client = HttpClientBuilder.create (). SetDefaultRequestConfig (config) .build ();

Dat is de aanbevolen manier om alle drie de time-outs op een typeveilige en leesbare manier te configureren.

4. Time-outeigenschappen uitgelegd

Laten we nu uitleggen wat deze verschillende soorten time-outs betekenen:

  • de Time-out verbinding (http.connection.timeout) - de tijd om de verbinding met de externe host tot stand te brengen
  • de Socket time-out (http.socket.timeout) - de wachttijd op gegevens - na het tot stand brengen van de verbinding; maximale tijd van inactiviteit tussen twee datapakketten
  • de Time-out van Connection Manager (http.connection-manager.timeout) - de tijd om te wachten op een verbinding van de verbindingsbeheerder / pool

De eerste twee parameters - de time-outs voor verbinding en socket - zijn de belangrijkste. Het instellen van een time-out voor het verkrijgen van een verbinding is echter zeker belangrijk in scenario's met hoge belasting, daarom mag de derde parameter niet worden genegeerd.

5. Gebruik de HttpClient

Na het configureren kunnen we de client nu gebruiken om HTTP-verzoeken uit te voeren:

HttpGet getMethod = nieuwe HttpGet ("// host: 8080 / pad"); HttpResponse-antwoord = httpClient.execute (getMethod); System.out.println ("HTTP-status van antwoord:" + response.getStatusLine (). GetStatusCode ());

Met de eerder gedefinieerde klant, de verbinding met de host wordt binnen 5 seconden verbroken. Als de verbinding tot stand is gebracht maar geen gegevens worden ontvangen, is de time-out ook geldig 5 extra seconden.

Merk op dat de time-out van de verbinding zal resulteren in een org.apache.http.conn.ConnectTimeoutException wordt gegooid, terwijl socket time-out zal resulteren in een java.net.SocketTimeoutException.

6. Harde time-out

Hoewel het instellen van time-outs voor het tot stand brengen van de HTTP-verbinding en het niet ontvangen van gegevens erg handig is, moeten we soms een moeilijke time-out voor het hele verzoek.

Het downloaden van een mogelijk groot bestand past bijvoorbeeld in deze categorie. In dit geval kan de verbinding met succes tot stand worden gebracht, kunnen er constant gegevens binnenkomen, maar we moeten er nog steeds voor zorgen dat de bewerking een bepaalde tijdsdrempel niet overschrijdt.

HttpClient heeft geen configuratie waarmee we een algemene time-out voor een verzoek kunnen instellen; het biedt echter wel afbreken functionaliteit voor verzoeken, zodat we dat mechanisme kunnen gebruiken om een ​​eenvoudig time-outmechanisme te implementeren:

HttpGet getMethod = nieuwe HttpGet ("// localhost: 8080 / httpclient-simple / api / bars / 1"); int hardTimeout = 5; // seconden TimerTask-taak = nieuwe TimerTask () {@Override public void run () {if (getMethod! = null) {getMethod.abort (); }}}; nieuwe timer (waar) .schedule (taak, hardTimeout * 1000); HttpResponse-antwoord = httpClient.execute (getMethod); System.out.println ("HTTP-status van antwoord:" + response.getStatusLine (). GetStatusCode ());

We maken gebruik van de java.util.Timer en java.util.TimerTask om een eenvoudige vertraagde taak die het HTTP GET-verzoek afbreekt na een harde time-out van 5 seconden.

7. Time-out en DNS Round Robin - Iets om op te letten

Het komt vrij vaak voor dat sommige grotere domeinen een DNS-round robin-configuratie gebruiken - in wezen hetzelfde domein toegewezen aan meerdere IP-adressen. Dit introduceert een nieuwe uitdaging voor een time-out tegen een dergelijk domein, simpelweg vanwege de manier waarop HttpClient zal proberen verbinding te maken met dat domein die een time-out heeft:

  • HttpClient krijgt de lijst met IP-routes naar dat domein
  • het probeert de eerste - die time-out (met de time-outs die we configureren)
  • het probeert de tweede - dat is ook een time-out
  • enzovoorts …

Dus, zoals je kunt zien - de algehele operatie zal niet aflopen wanneer we dat verwachten. In plaats daarvan zal er een time-out optreden wanneer alle mogelijke routes zijn verlopen. Wat meer is - dit zal volledig transparant gebeuren voor de client (tenzij je je log hebt geconfigureerd op het DEBUG-niveau).

Hier is een eenvoudig voorbeeld dat u kunt uitvoeren en dit probleem kunt repliceren:

int time-out = 3; RequestConfig config = RequestConfig.custom (). setConnectTimeout (time-out * 1000). setConnectionRequestTimeout (time-out * 1000). setSocketTimeout (time-out * 1000) .build (); CloseableHttpClient client = HttpClientBuilder.create () .setDefaultRequestConfig (config) .build (); HttpGet request = nieuwe HttpGet ("// www.google.com:81"); response = client.execute (verzoek);

U zult de logica voor het opnieuw proberen opmerken met een DEBUG-logniveau:

DEBUG o.a.h.i.c.HttpClientConnectionOperator - Verbinding maken met www.google.com/173.194.34.212:81 DEBUG o.a.h.i.c.HttpClientConnectionOperator - Verbinding maken met www.google.com/173.194.34.212:81 time-out. Verbinding wordt opnieuw geprobeerd met een ander IP-adres DEBUG o.a.h.i.c. HTTPClientConnectionOperator - Verbinding maken met www.google.com/173.194.34.208:81 DEBUG o.a.h.i.c. HTTPClientConnectionOperator - Verbinding maken met www.google.com/173.194.34.208:81 time-out. Verbinding wordt opnieuw geprobeerd met een ander IP-adres DEBUG o.a.h.i.c.HttpClientConnectionOperator - Verbinding maken met www.google.com/173.194.34.209:81 DEBUG o.a.h.i.c. HTTPClientConnectionOperator - Verbinding maken met www.google.com/173.194.34.209:81 time-out. Er wordt opnieuw geprobeerd verbinding te maken met een ander IP-adres // ...

8. Conclusie

In deze tutorial werd besproken hoe je de verschillende soorten time-outs configureert die beschikbaar zijn voor een HttpClient. Het illustreerde ook een eenvoudig mechanisme voor een moeilijke time-out van een lopende HTTP-verbinding.

De implementatie van deze voorbeelden is te vinden in het GitHub-project.