HttpClient vremensko ograničenje

1. Pregled

Ovaj vodič će pokazati kako konfigurirajte timeout s Apacheom HttpClient 4.

Ako želite dublje kopati i naučiti druge cool stvari koje možete učiniti s HttpClientom, krenite na glavni HttpClient udžbenik.

2. Konfiguriranje vremenskih ograničenja prije HttpClient 4.3

2.1. Sirovo Niz Parametri

Prije nego što je izašla verzija 4.3, HttpClient dolazili su s puno konfiguracijskih parametara i svi su se mogli postaviti na generički način sličan mapi.

Bilo ih je 3 parametra vremenskog ograničenja za konfiguriranje:

DefaultHttpClient httpClient = novi DefaultHttpClient (); int timeout = 5; // sekunde HttpParams httpParams = httpClient.getParams (); httpParams.setParameter (CoreConnectionPNames.CONNECTION_TIMEOUT, timeout * 1000); httpParams.setParameter (CoreConnectionPNames.SO_TIMEOUT, timeout * 1000); httpParams.setParameter (ClientPNames.CONN_MANAGER_TIMEOUT, novi Long (timeout * 1000));

2.2. API

Važniji od ovih parametara - naime prva dva - također se mogu postaviti putem API-ja sigurnijeg za tip:

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

Treći parametar nema prilagođeni postavljač HttpConnectionParams, i dalje će ga trebati postaviti ručno putem setParameter metoda.

3. Konfigurirajte vremenska ograničenja pomoću novog 4.3. Graditelj

Tečni, graditeljski API predstavljen u 4.3 pravi način postavljanja vremenskih ograničenja na visokoj razini:

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

To je preporučeni način konfiguriranja sva tri vremenska ograničenja na siguran i čitljiv način.

4. Objašnjena svojstva vremenskog ograničenja

Sad, objasnimo što znače ove razne vrste vremenskih ograničenja:

  • the Vrijeme povezanosti je isteklo (http.connection.timeout) - vrijeme uspostavljanja veze s udaljenim hostom
  • the Istek utičnice utičnice (http.socket.timeout) - vrijeme čekanja na podatke - nakon uspostavljanja veze; maksimalno vrijeme neaktivnosti između dva paketa podataka
  • the Vremensko ograničenje upravitelja veze (http.connection-manager.timeout) - vrijeme čekanja veze od upravitelja / spremišta veza

Prva dva parametra - vremenska ograničenja veze i utičnice - najvažnija su. Međutim, postavljanje vremenskog ograničenja za dobivanje veze definitivno je važno u scenarijima velikog opterećenja, zbog čega treći parametar ne bi trebao biti zanemaren.

5. Korištenje HttpClient

Nakon što smo ga konfigurirali, sada možemo koristiti klijenta za izvršavanje HTTP zahtjeva:

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

S prethodno definiranim klijentom, veza s hostom isteći će za 5 sekundi. Također, ako je veza uspostavljena, ali ne primi podatke, bit će i vremensko ograničenje 5 dodatnih sekundi.

Imajte na umu da će vremensko ograničenje veze rezultirati znakom org.apache.http.conn.ConnectTimeoutException biti bačen, dok će istek utičnice utičnice rezultirati a java.net.SocketTimeoutException.

6. Tvrdi timeout

Iako je postavljanje vremenskih ograničenja za uspostavljanje HTTP veze i neprimanje podataka vrlo korisno, ponekad moramo postaviti a teško vrijeme čekanja za cijeli zahtjev.

Primjerice, preuzimanje potencijalno velike datoteke uklapa se u ovu kategoriju. U ovom slučaju, veza se može uspješno uspostaviti, podaci mogu neprestano prolaziti, ali svejedno moramo osigurati da operacija ne prijeđe neki određeni vremenski prag.

HttpClient nema nijednu konfiguraciju koja nam omogućuje postavljanje ukupnog vremenskog ograničenja za zahtjev; međutim, pruža prekinuti funkcionalnost zahtjeva, tako da taj mehanizam možemo iskoristiti za primjenu jednostavnog mehanizma vremenskog ograničenja:

HttpGet getMethod = novi HttpGet ("// localhost: 8080 / httpclient-simple / api / bars / 1"); int hardTimeout = 5; // sekunde TimerTask zadatak = novi TimerTask () {@Preuzmi javno void vođenje () {if (getMethod! = null) {getMethod.abort (); }}}; novi timer (true) .schedule (zadatak, hardTimeout * 1000); HttpResponse odgovor = httpClient.execute (getMethod); System.out.println ("HTTP status odgovora:" + response.getStatusLine (). GetStatusCode ());

Koristimo java.util.Timer i java.util.TimerTask postaviti a jednostavan odgođeni zadatak koji prekida HTTP GET zahtjev nakon teškog vremena od 5 sekundi.

7. Istek vremena i DNS Round Robin - Nečega čega treba biti svjestan

Uobičajeno je da će neke veće domene upotrebljavati DNS okrugle konfiguracije - u biti ista domena preslikana na više IP adresa. Ovo predstavlja novi izazov za vremensko ograničenje protiv takve domene, jednostavno zbog načina na koji će se HttpClient pokušati povezati s tom domenom koji istekne:

  • HttpClient dobiva popis IP ruta na tu domenu
  • pokušava prvi - taj time out (s vremenskim ograničenjima koja konfiguriramo)
  • pokušava drugi - to također istječe
  • i tako dalje …

Pa, kao što vidite - cjelokupna operacija neće isteći kad to očekujemo. Umjesto toga - isteći će kada isteknu sve moguće rute. Štoviše - to će se dogoditi potpuno transparentno za klijenta (osim ako imate svoj dnevnik konfiguriran na razini DEBUG).

Evo jednostavnog primjera koji možete pokrenuti i ponoviti ovaj 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 zahtjev = novi HttpGet ("// www.google.com:81"); odgovor = klijent.izvršiti (zahtjev);

Primijetit ćete logiku ponovnog pokušaja na razini zapisnika DEBUG:

DEBUG o.a.h.i.c.HttpClientConnectionOperator - povezivanje s www.google.com/173.194.34.212:81 DEBUG o.a.h.i.c.HttpClientConnectionOperator - Povezivanje s www.google.com/173.194.34.212:81 isteklo je. Ponovno će se uspostaviti veza pomoću druge IP adrese DEBUG o.a.h.i.c.HttpClientConnectionOperator - Povezivanje s www.google.com/173.194.34.208:81 DEBUG o.a.h.i.c.HttpClientConnectionOperator - Povežite se s www.google.com/173.194.34.208:81 timeded Ponovno će se pokušati uspostaviti veza pomoću druge IP adrese DEBUG o.a.h.i.c.HttpClientConnectionOperator - povezivanje s www.google.com/173.194.34.209:81 DEBUG o.a.h.i.c.HttpClientConnectionOperator - povezivanje s www.google.com/173.194.34.209:81 timeded. Ponovno će se uspostaviti veza pomoću druge IP adrese // ...

8. Zaključak

U ovom se vodiču govorilo o tome kako konfigurirati različite vrste vremenskih ograničenja dostupnih za HttpClient. Također je ilustrirao jednostavan mehanizam za teško istek trenutne HTTP veze.

Provedba ovih primjera može se naći u projektu GitHub.


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