Časový limit HttpClient

1. Prehľad

Tento návod ukáže, ako na to nakonfigurovať časový limit s Apache HttpClient 4.

Ak sa chcete prehĺbiť a naučiť sa ďalšie super veci, ktoré môžete s HttpClient robiť - choďte ďalej hlavný HttpClient návod.

2. Konfigurácia časových limitov predtým HttpClient 4.3

2.1. Surový String Parametre

Predtým, ako vyšla verzia 4.3, HttpClient priniesol veľa konfiguračných parametrov a všetky tieto parametre bolo možné nastaviť všeobecne, podobne ako na mape.

Boli 3 parametre časového limitu na konfiguráciu:

DefaultHttpClient httpClient = nový DefaultHttpClient (); int timeout = 5; // sekundy HttpParams httpParams = httpClient.getParams (); httpParams.setParameter (CoreConnectionPNames.CONNECTION_TIMEOUT, časový limit * 1 000); httpParams.setParameter (CoreConnectionPNames.SO_TIMEOUT, časový limit * 1000); httpParams.setParameter (ClientPNames.CONN_MANAGER_TIMEOUT, nový Long (časový limit * 1 000));

2.2. API

Dôležitejšie z týchto parametrov - konkrétne prvé dva - je možné nastaviť aj pomocou viac typovo bezpečného rozhrania API:

DefaultHttpClient httpClient = nový DefaultHttpClient (); int timeout = 5; // sekundy HttpParams httpParams = httpClient.getParams (); HttpConnectionParams.setConnectionTimeout (httpParams, časový limit * 1 000); // http.connection.timeout HttpConnectionParams.setSoTimeout (httpParams, timeout * 1000); // http.socket.timeout

Tretí parameter nemá vlastné nastavovacie zariadenie HttpConnectionParams, a stále to bude potrebné nastaviť ručne cez setParameter metóda.

3. Konfigurácia časových limitov pomocou nového 4.3. Staviteľ

Plynulé, staviteľské API predstavené v 4.3 poskytuje správnym spôsobom nastaviť časové limity na vysokej úrovni:

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

Toto je odporúčaný spôsob konfigurácie všetkých troch časových limitov typovo bezpečným a čitateľným spôsobom.

4. Vysvetlenie vlastností časového limitu

Teraz si vysvetlíme, čo tieto rôzne typy časových limitov znamenajú:

  • the Spojenie vypršalo (http.connection.timeout) - čas na nadviazanie spojenia so vzdialeným hostiteľom
  • the Časový limit zásuvky (http.socket.timeout) - čas čakania na dáta - po vytvorení spojenia; maximálna doba nečinnosti medzi dvoma dátovými paketmi
  • the Časový limit Správcu pripojení (http.connection-manager.timeout) - čas čakania na pripojenie od správcu spojenia / fondu

Najdôležitejšie sú prvé dva parametre - časové limity pripojenia a zásuvky. Nastavenie časového limitu na získanie pripojenia je však určite dôležité v scenároch vysokého zaťaženia, a preto by sa tretí parameter nemal ignorovať.

5. Pomocou HttpClient

Po jeho nakonfigurovaní teraz môžeme klienta používať na vykonávanie požiadaviek HTTP:

HttpGet getMethod = nový HttpGet ("// hostiteľ: 8080 / cesta"); HttpResponse response = httpClient.execute (getMethod); System.out.println ("Stav HTTP odpovede:" + response.getStatusLine (). GetStatusCode ());

S predtým definovaným klientom pripojenie k hostiteľovi vyprší o 5 sekúnd. Ak je pripojenie nadviazané, ale nie sú prijaté žiadne údaje, uplynie tiež časový limit Ďalších 5 sekúnd.

Upozorňujeme, že časový limit pripojenia bude mať za následok org.apache.http.conn.ConnectTimeoutException bude vyhodený, zatiaľ čo časový limit zásuvky spôsobí a java.net.SocketTimeoutException.

6. Tvrdý časový limit

Aj keď je nastavenie časových limitov na nadviazanie spojenia HTTP a neprijímanie údajov veľmi užitočné, niekedy je potrebné nastaviť a tvrdý časový limit pre celú žiadosť.

Do tejto kategórie napríklad patrí stiahnutie potenciálne veľkého súboru. V takom prípade môže byť pripojenie úspešne nadviazané, dáta môžu byť neustále v koncoch, stále je však potrebné zabezpečiť, aby operácia neprekročila určitý konkrétny časový limit.

HttpClient nemá žiadnu konfiguráciu, ktorá by nám umožňovala nastaviť celkový časový limit pre požiadavku; to však poskytuje zrušiť funkčnosť požiadaviek, takže môžeme tento mechanizmus využiť na implementáciu jednoduchého mechanizmu časového limitu:

HttpGet getMethod = nový HttpGet ("// localhost: 8080 / httpclient-simple / api / bars / 1"); int hardTimeout = 5; // sekundy TimerTask task = new TimerTask () {@Override public void run () {if (getMethod! = null) {getMethod.abort (); }}}; new Timer (true) .schedule (task, hardTimeout * 1000); HttpResponse response = httpClient.execute (getMethod); System.out.println ("Stav HTTP odpovede:" + response.getStatusLine (). GetStatusCode ());

Využívame java.util.Timer a java.util.TimerTask založiť a jednoduchá oneskorená úloha, ktorá zruší požiadavku HTTP GET po 5 sekundách tvrdého časového limitu.

7. Timeout a DNS Round Robin - na čo si treba dávať pozor

Je úplne bežné, že niektoré väčšie domény budú používať konfiguráciu DNS každý s každým - v podstate majú rovnaká doména namapovaná na viac adries IP. Toto predstavuje novú výzvu pre časový limit proti takejto doméne, jednoducho kvôli spôsobu, akým sa HttpClient pokúsi pripojiť k tejto doméne, ktorá vyprší:

  • HttpClient dostane zoznam smerov IP do tej domény
  • to sa snaží prvý - tento časový limit (s časovými limitmi, ktoré nakonfigurujeme)
  • to sa snaží druhý - to tiež vyprší
  • a tak ďalej …

Takže, ako vidíte - celková operácia nevyprší, keď to očakávame. Namiesto toho - vyprší časový limit, keď vypršal čas všetkých možných trás. A čo viac - stane sa to pre klienta úplne transparentne (pokiaľ nemáte svoj denník nakonfigurovaný na úrovni DEBUG).

Tu je jednoduchý príklad, ako môžete spustiť a replikovať tento problém:

int timeout = 3; RequestConfig config = RequestConfig.custom (). setConnectTimeout (časový limit * 1 000). setConnectionRequestTimeout (časový limit * 1 000). setSocketTimeout (časový limit * 1 000) .build (); CloseableHttpClient client = HttpClientBuilder.create () .setDefaultRequestConfig (config) .build (); HttpGet request = nový HttpGet ("// www.google.com:81"); response = client.execute (request);

Logiku opakovania s úrovňou protokolu DEBUG si všimnete:

DEBUG o.a.h.i.c.HttpClientConnectionOperator - pripájanie k www.google.com/173.194.34.212:81 DEBUG o.a.h.i.c.HttpClientConnectionOperator - pripojenie k www.google.com/173.194.34.212:81 vypršalo. Pripojenie sa zopakuje pomocou inej adresy IP. Časový limit DEBUG o.a.h.i.c.HttpClientConnectionOperator - pripájanie k www.google.com/173.194.34.208:81 DEBUG o.a.h.i.c. Pripojenie sa zopakuje pomocou inej adresy IP. Vypršal časový limit DEBUG o.a.h.i.c.HttpClientConnectionOperator - pripájanie k www.google.com/173.194.34.209:81 DEBUG o.a.h.i.c.HttpClientConnectionOperator - pripojeniu k www.google.com/173.194.34.209:81. Pripojenie sa zopakuje pomocou inej adresy IP // ...

8. Záver

V tomto výučbe sa diskutovalo o konfigurácii rôznych typov časových limitov dostupných pre server HttpClient. Tiež to ilustrovalo jednoduchý mechanizmus na vypršanie časového limitu prebiehajúceho pripojenia HTTP.

Implementáciu týchto príkladov možno nájsť v projekte GitHub.


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