HttpClient-timeout

1. Oversigt

Denne vejledning viser, hvordan man gør det konfigurer en timeout med Apache HttpClient 4.

Hvis du vil grave dybere og lære andre seje ting, kan du gøre med HttpClient - gå videre til det vigtigste HttpClient vejledning.

2. Konfiguration af timeouts før HttpClient 4.3

2.1. Rå Snor Parametre

Før version 4.3 kom ud, blev HttpClient kom med mange konfigurationsparametre, og alle disse kunne indstilles på en generisk kortlignende måde.

Der var 3 timeout-parametre, der skal konfigureres:

DefaultHttpClient httpClient = ny DefaultHttpClient (); int timeout = 5; // sekunder HttpParams httpParams = httpClient.getParams (); httpParams.setParameter (CoreConnectionPNames.CONNECTION_TIMEOUT, timeout * 1000); httpParams.setParameter (CoreConnectionPNames.SO_TIMEOUT, timeout * 1000); httpParams.setParameter (ClientPNames.CONN_MANAGER_TIMEOUT, ny lang (timeout * 1000));

2.2. API

De vigtigere af disse parametre - nemlig de to første - kunne også indstilles via en mere typesikker API:

DefaultHttpClient httpClient = ny DefaultHttpClient (); int timeout = 5; // sekunder HttpParams httpParams = httpClient.getParams (); HttpConnectionParams.setConnectionTimeout (httpParams, timeout * 1000); // http.connection.timeout HttpConnectionParams.setSoTimeout (httpParams, timeout * 1000); // http.socket.timeout

Den tredje parameter har ikke en brugerdefineret setter i HttpConnectionParams, og det skal stadig indstilles manuelt via sæt Parameter metode.

3. Konfigurer timeouts ved hjælp af den nye 4.3. Bygger

Den flydende, builder API introduceret i 4.3 giver den rigtige måde at indstille timeouts på et højt niveau:

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

Det er den anbefalede måde at konfigurere alle tre timeouts på en typesikker og læsbar måde.

4. Timeout-egenskaber forklaret

Lad os nu forklare, hvad disse forskellige typer timeouts betyder:

  • det Forbindelsestimeout (http.connection.timeout) - tidspunktet for at oprette forbindelsen til fjernværten
  • det Socket timeout (http.socket.timeout) - den tid, der venter på data - efter oprettelse af forbindelsen; maksimal inaktivitetstid mellem to datapakker
  • det Connection Manager timeout (http.connection-manager.timeout) - tiden til at vente på en forbindelse fra forbindelsesadministratoren / poolen

De to første parametre - forbindelses- og stikkontakt-timeouts - er de vigtigste. Imidlertid er det absolut vigtigt at indstille en timeout til at opnå en forbindelse i scenarier med høj belastning, hvorfor den tredje parameter ikke bør ignoreres.

5. Brug af HttpClient

Efter at have konfigureret det, kan vi nu bruge klienten til at udføre HTTP-anmodninger:

HttpGet getMethod = ny HttpGet ("// vært: 8080 / sti"); HttpResponse respons = httpClient.execute (getMethod); System.out.println ("HTTP-status for svar:" + respons.getStatusLine (). GetStatusCode ());

Med den tidligere definerede klient forbindelsen til værten vil timeout på 5 sekunder. Hvis forbindelsen er etableret, men der ikke modtages data, vil timeout'en også være Yderligere 5 sekunder.

Bemærk, at timeout for forbindelsen vil resultere i en org.apache.http.conn.ConnectTimeoutException bliver kastet, mens stop-timeout vil resultere i en java.net.SocketTimeoutException.

6. Hård timeout

Mens det er meget nyttigt at indstille timeouts til oprettelse af HTTP-forbindelse og ikke modtage data, er vi undertiden nødt til at indstille en hård timeout for hele anmodningen.

For eksempel passer download af en potentielt stor fil ind i denne kategori. I dette tilfælde kan forbindelsen muligvis oprettes med succes, data kan konsekvent komme igennem, men vi skal stadig sikre, at operationen ikke går over en bestemt tidsgrænse.

HttpClient har ingen konfiguration, der giver os mulighed for at indstille en samlet timeout for en anmodning; det giver dog afbryde funktionalitet til anmodninger, så vi kan udnytte den mekanisme til at implementere en simpel timeout-mekanisme:

HttpGet getMethod = ny HttpGet ("// localhost: 8080 / httpclient-simple / api / bars / 1"); int hardTimeout = 5; // sekunder TimerTask-opgave = ny TimerTask () {@Override offentlig ugyldig kørsel () {if (getMethod! = null) {getMethod.abort (); }}} ny timer (sand) .plan (opgave, hardTimeout * 1000); HttpResponse respons = httpClient.execute (getMethod); System.out.println ("HTTP-status for svar:" + respons.getStatusLine (). GetStatusCode ());

Vi gør brug af java.util.Timer og java.util.TimerTask at oprette en enkel forsinket opgave, der afbryder HTTP GET-anmodningen efter en 5 sekunders hård timeout.

7. Timeout og DNS Round Robin - noget at være opmærksom på

Det er ret almindeligt, at nogle større domæner bruger en DNS-robin-konfiguration - i det væsentlige har det samme domæne tilknyttet flere IP-adresser. Dette introducerer en ny udfordring for en timeout mod et sådant domæne, simpelthen på grund af den måde, HttpClient vil forsøge at oprette forbindelse til dette domæne, der timeout:

  • HttpClient får listen over IP-ruter til dette domæne
  • det prøver den første - at time out (med de timeouts, vi konfigurerer)
  • det prøver den anden - det går også ud
  • og så videre …

Så som du kan se - den samlede operation vil ikke afbryde, når vi forventer, at det skal ske. I stedet - det vil timeout, når alle mulige ruter er udløbet. Hvad mere er - dette vil ske helt gennemsigtigt for klienten (medmindre du har konfigureret din log på DEBUG-niveau).

Her er et simpelt eksempel, du kan køre og replikere dette problem:

int timeout = 3; RequestConfig config = RequestConfig.custom (). setConnectTimeout (timeout * 1000). setConnectionRequestTimeout (timeout * 1000). setSocketTimeout (timeout * 1000) .build (); CloseableHttpClient client = HttpClientBuilder.create () .setDefaultRequestConfig (config) .build (); HttpGet anmodning = ny HttpGet ("// www.google.com:81"); respons = klient. udfør (anmodning);

Du vil bemærke den nye forsøgslogik med et DEBUG-logniveau:

DEBUG o.a.h.i.c.HttpClientConnectionOperator - Opretter forbindelse til www.google.com/173.194.34.212:81 DEBUG o.a.h.i.c.HttpClientConnectionOperator - Opret forbindelse til www.google.com/173.194.34.212:81 timeout. Forbindelsen vil blive prøvet igen ved hjælp af en anden IP-adresse DEBUG o.a.h.i.c.HttpClientConnectionOperator - Opretter forbindelse til www.google.com/173.194.34.208:81 DEBUG o.a.h.i.c.HttpClientConnectionOperator - Opret forbindelse til www.google.com/173.194.34.208:81 timeout. Forbindelsen vil blive prøvet igen ved hjælp af en anden IP-adresse DEBUG o.a.h.i.c.HttpClientConnectionOperator - Opretter forbindelse til www.google.com/173.194.34.209:81 DEBUG o.a.h.i.c.HttpClientConnectionOperator - Opret forbindelse til www.google.com/173.194.34.209:81 timeout. Forbindelsen vil blive prøvet igen ved hjælp af en anden IP-adresse // ...

8. Konklusion

Denne vejledning diskuterede, hvordan man konfigurerer de forskellige typer timeouts, der er tilgængelige for en HttpClient. Det illustrerede også en simpel mekanisme til hård timeout af en igangværende HTTP-forbindelse.

Implementeringen af ​​disse eksempler findes i GitHub-projektet.


$config[zx-auto] not found$config[zx-overlay] not found