HttpClient-tidsavbrudd

1. Oversikt

Denne opplæringen viser hvordan du gjør det konfigurer en tidsavbrudd med Apache HttpKlient 4.

Hvis du vil grave dypere og lære andre kule ting du kan gjøre med HttpClient - gå videre til hoved HttpClient opplæringen.

2. Konfigurere tidsavbrudd før HttpClient 4.3

2.1. Rå String Parametere

Før versjon 4.3 kom ut, ble HttpClient kom med mange konfigurasjonsparametere, og alle disse kunne settes på en generisk, kartlignende måte.

Det var 3 tidsavbruddsparametere å konfigurere:

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, new Long (timeout * 1000));

2.2. API

De viktigste av disse parametrene - nemlig de to første - kan også settes via en mer 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 parameteren har ikke en egendefinert setter i HttpConnectionParams, og det må fortsatt stilles inn manuelt via setParameter metode.

3. Konfigurer tidsavbrudd ved hjelp av nye 4.3. Bygger

Den flytende byggmester-API introdusert i 4.3 gir riktig måte å sette tidsavbrudd på høyt nivå:

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

Dette er den anbefalte måten å konfigurere alle tre tidsavbrudd på en typesikker og lesbar måte.

4. Egenskaper for tidsavbrudd

La oss nå forklare hva disse forskjellige typene tidsavbrudd betyr:

  • de Tidsavbrudd for tilkobling (http.connection.timeout) - tiden for å opprette forbindelse med den eksterne verten
  • de Socket Timeout (http.socket.timeout) - tiden som venter på data - etter at forbindelsen er opprettet; maksimal tid for inaktivitet mellom to datapakker
  • de Connection Manager Timeout (http.connection-manager.timeout) - tiden for å vente på en tilkobling fra tilkoblingsadministratoren / bassenget

De to første parameterne - tilkoblingen og tidsavbrudd for kontakten - er de viktigste. Imidlertid er det absolutt viktig å sette en tidsavbrudd for å oppnå en forbindelse i scenarier med høy belastning, og det er grunnen til at den tredje parameteren ikke skal ignoreres.

5. Bruke HttpClient

Etter å ha konfigurert den, kan vi nå bruke klienten til å utføre HTTP-forespørsler:

HttpGet getMethod = new HttpGet ("// host: 8080 / path"); HttpResponse respons = httpClient.execute (getMethod); System.out.println ("HTTP Status of response:" + response.getStatusLine (). GetStatusCode ());

Med den tidligere definerte klienten, forbindelsen til verten vil gå ut på fem sekunder. Også, hvis forbindelsen er opprettet, men ingen data mottas, vil tidsavbruddet også være 5 ekstra sekunder.

Merk at tidsavbrudd for tilkobling vil resultere i en org.apache.http.conn.ConnectTimeoutException kastes, mens stikkontakt for timeout vil resultere i java.net.SocketTimeoutException.

6. Hard timeout

Selv om det er veldig nyttig å sette tidsavbrudd for å opprette HTTP-tilkobling og ikke motta data, må vi noen ganger sette en vanskelig timeout for hele forespørselen.

For eksempel passer nedlastingen av en potensielt stor fil inn i denne kategorien. I dette tilfellet kan forbindelsen være vellykket, data kan konsekvent komme gjennom, men vi må fortsatt sørge for at operasjonen ikke går over en bestemt tidsgrense.

HttpClient har ingen konfigurasjon som lar oss sette en total tidsavbrudd for en forespørsel; det gir imidlertid avbryte funksjonalitet for forespørsler, slik at vi kan utnytte den mekanismen for å implementere en enkel timeout-mekanisme:

HttpGet getMethod = new HttpGet ("// localhost: 8080 / httpclient-simple / api / bars / 1"); int hardTimeout = 5; // sekunder TimerTask-oppgave = ny TimerTask () {@Override public void run () {if (getMethod! = null) {getMethod.abort (); }}}; ny tidtaker (sann) .plan (oppgave, hardTimeout * 1000); HttpResponse respons = httpClient.execute (getMethod); System.out.println ("HTTP-status for svar:" + respons.getStatusLine (). GetStatusCode ());

Vi bruker java.util.Timer og java.util.TimerTask å sette opp en enkel forsinket oppgave som avbryter HTTP GET-forespørselen etter 5 sekunders hard timeout.

7. Timeout og DNS Round Robin - Noe å være klar over

Det er ganske vanlig at noen større domener bruker en DNS-robinkonfigurasjon - i hovedsak har det samme domenet tilordnet flere IP-adresser. Dette introduserer en ny utfordring for en tidsavbrudd mot et slikt domene, bare på grunn av måten HttpClient vil prøve å koble til det domenet som går ut på tid:

  • HttpClient får listen over IP-ruter til det domenet
  • prøver det den første - at time out (med tidsavbrudd vi konfigurerer)
  • prøver det den andre - som også går ut
  • og så videre …

Så som du kan se - den totale driften vil ikke gå ut når vi forventer at den skal. I stedet - det vil gå ut når alle mulige ruter er tidsavbrutt. Hva mer - dette vil skje helt transparent for klienten (med mindre du har loggen din konfigurert på DEBUG-nivå).

Her er et enkelt eksempel du kan kjøre og replikere dette problemet:

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-forespørsel = ny HttpGet ("// www.google.com:81"); respons = klient.utfør (forespørsel);

Du vil merke logikken på nytt med et DEBUG-loggnivå:

DEBUG o.a.h.i.c.HttpClientConnectionOperator - Koble til www.google.com/173.194.34.212:81 DEBUG o.a.h.i.c.HttpClientConnectionOperator - Koble til www.google.com/173.194.34.212:81 tidsavbrutt. Forbindelsen vil bli prøvd på nytt ved hjelp av en annen IP-adresse DEBUG o.a.h.i.c.HttpClientConnectionOperator - Koble til www.google.com/173.194.34.208:81 DEBUG o.a.h.i.c.HttpClientConnectionOperator - Koble til www.google.com/173.194.34.208:81 tidsbestemt Tilkoblingen vil bli prøvd på nytt ved hjelp av en annen IP-adresse DEBUG o.a.h.i.c.HttpClientConnectionOperator - Koble til www.google.com/173.194.34.209:81 DEBUG o.a.h.i.c.HttpClientConnectionOperator - Koble til www.google.com/173.194.34.209:81 tidsbestemt. Tilkoblingen vil bli prøvd på nytt ved hjelp av en annen IP-adresse // ...

8. Konklusjon

Denne opplæringen diskuterte hvordan du konfigurerer de forskjellige typene tidsavbrudd som er tilgjengelige for en HttpClient. Det illustrerte også en enkel mekanisme for hard timeout for en pågående HTTP-forbindelse.

Implementeringen av disse eksemplene finnes i GitHub-prosjektet.


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