HttpClient Timeout

1. Áttekintés

Ez az oktatóanyag megmutatja, hogyan kell állítson be időtúllépést az Apache-szal HttpClient 4.

Ha mélyebbre akarsz ásni, és további jó dolgokat akarsz megtudni, amit a HttpClient-nel tehetsz - menj tovább a fő HttpClient bemutató.

2. Időtúllépés beállítása előtte HttpClient 4.3

2.1. Nyers Húr Paraméterek

A 4.3-as verzió megjelenése előtt a HttpClient sok konfigurációs paraméterrel érkezett, és mindezeket általános, térképszerű módon lehetett beállítani.

Ott volt 3 konfigurálható időkorlát paraméter:

DefaultHttpClient httpClient = új DefaultHttpClient (); int időkorlát = 5; // másodperc HttpParams httpParams = httpClient.getParams (); httpParams.setParameter (CoreConnectionPNames.CONNECTION_TIMEOUT, timeout * 1000); httpParams.setParameter (CoreConnectionPNames.SO_TIMEOUT, timeout * 1000); httpParams.setParameter (ClientPNames.CONN_MANAGER_TIMEOUT, új Long (timeout * 1000));

2.2. API

Ezen paraméterek közül a legfontosabb - nevezetesen az első kettő - egy típusbiztonságosabb API-n keresztül is beállítható:

DefaultHttpClient httpClient = új DefaultHttpClient (); int időkorlát = 5; // másodperc HttpParams httpParams = httpClient.getParams (); HttpConnectionParams.setConnectionTimeout (httpParams, timeout * 1000); // http.connection.timeout HttpConnectionParams.setSoTimeout (httpParams, timeout * 1000); // http.socket.timeout

A harmadik paraméter nem rendelkezik egyéni beállítóval HttpConnectionParams, és akkor is manuálisan kell beállítani a setParameter módszer.

3. Állítsa be az időkorlátokat az Új 4.3 használatával. Építész

A 4.3-ban bevezetett folyékony, építő API biztosítja az időkorlátok magas szintű beállításának megfelelő módja:

int időkorlát = 5; RequestConfig config = RequestConfig.custom () .setConnectTimeout (timeout * 1000) .setConnectionRequestTimeout (timeout * 1000) .setSocketTimeout (timeout * 1000) .build (); CloseableHttpClient kliens = HttpClientBuilder.create (). SetDefaultRequestConfig (config) .build ();

Ez az ajánlott módszer mindhárom időtúllépés típusbiztonságos és olvasható konfigurálásához.

4. Időtúllépés tulajdonságok magyarázata

Most magyarázzuk el, mit jelentenek ezek a különböző típusú időtúllépések:

  • a Kapcsolat időtúllépés (http.connection.timeout) - a távoli gazdagéppel való kapcsolat létrehozásának ideje
  • a Socket Timeout (http.socket.timeout) - az adatokra való várakozás ideje - a kapcsolat létrehozása után; két inaktivitás maximális ideje két adatcsomag között
  • a Kapcsolatkezelő időkorlátja (http.connection-manager.timeout) - az az idő, amikor a kapcsolatkezelőtől / készletből várni kell a kapcsolatra

Az első két paraméter - a csatlakozás és a foglalat időkorlátja - a legfontosabb. A kapcsolat megszerzéséhez szükséges időtúllépés meghatározása azonban nagyon fontos nagy terhelés esetén, ezért nem szabad figyelmen kívül hagyni a harmadik paramétert.

5. A HttpClient

A konfigurálás után most már használhatjuk az ügyfelet HTTP-kérések végrehajtására:

HttpGet getMethod = new HttpGet ("// gazdagép: 8080 / elérési út"); HttpResponse response = httpClient.execute (getMethod); System.out.println ("A válasz HTTP állapota:" + response.getStatusLine (). GetStatusCode ());

A korábban definiált ügyféllel a gazdagéppel való kapcsolat 5 másodpercen belül időtúllép. Továbbá, ha a kapcsolat létrejön, de nem érkezik adat, akkor az időkorlát is meg lesz További 5 másodperc.

Vegye figyelembe, hogy a kapcsolat időtúllépése egy org.apache.http.conn.ConnectTimeoutException dobásra kerül, míg a foglalat időkorlátja a java.net.SocketTimeoutException.

6. Nehéz időkorlát

Bár nagyon hasznos az időkorlát beállítása a HTTP-kapcsolat létrehozására és az adatok nem fogadására, néha be kell állítanunk egy nehéz időtúllépés a teljes kéréshez.

Például egy potenciálisan nagy fájl letöltése letölthető ebbe a kategóriába. Ebben az esetben a kapcsolat sikeresen létrejöhet, az adatok következetesen beérkezhetnek, de még mindig biztosítanunk kell, hogy a művelet ne lépjen túl bizonyos időhatárt.

HttpClient nem rendelkezik olyan konfigurációval, amely lehetővé tenné számunkra a kérés teljes időtúllépését; mégis biztosítja kérelmek megszakítása, így kihasználhatjuk ezt a mechanizmust egy egyszerű időtúllépési mechanizmus megvalósítására:

HttpGet getMethod = new HttpGet ("// localhost: 8080 / httpclient-simple / api / bars / 1"); int hardTimeout = 5; // másodperc TimerTask task = new TimerTask () {@Orride public void run () {if (getMethod! = null) {getMethod.abort (); }}}; new Timer (true) .schedule (feladat, hardTimeout * 1000); HttpResponse response = httpClient.execute (getMethod); System.out.println ("A válasz HTTP állapota:" + response.getStatusLine (). GetStatusCode ());

Használjuk a java.util.Timer és java.util.TimerTask felállítani a egyszerű késleltetett feladat, amely megszakítja a HTTP GET kérést 5 másodperces kemény időkorlát után.

7. Időkorlát és DNS-körös Robin - valami, amiről tudatában kell lennie

Elég gyakori, hogy egyes nagyobb tartományok DNS körbefutó konfigurációt fognak használni - lényegében ugyanaz a tartomány több IP-címhez társítva. Ez új kihívást jelent az ilyen domain elleni időkorlátnak, pusztán azért, mert a HttpClient megpróbál csatlakozni ahhoz a domainhez, amely időtúllépést mutat:

  • HttpClient megkapja az IP útvonalak listája arra a domainre
  • megpróbálja az első - ez időtúllép (az általunk beállított időkorlátokkal)
  • megpróbálja a második - ez is időtúllép
  • stb …

Tehát, amint láthatja - az általános művelet nem késik el, amikor elvárjuk. Ehelyett - akkor fog elévülni, amikor az összes lehetséges útvonal időtúllép. Mi több - ez teljesen átláthatóan fog megtörténni az ügyfél számára (hacsak nem a DEBUG szinten van konfigurálva a napló).

Íme egy egyszerű példa, amellyel futtathatja és megismételheti ezt a problémát:

int időkorlát = 3; RequestConfig config = RequestConfig.custom (). setConnectTimeout (időtúllépés * 1000). setConnectionRequestTimeout (timeout * 1000). setSocketTimeout (timeout * 1000) .build (); CloseableHttpClient kliens = HttpClientBuilder.create () .setDefaultRequestConfig (config) .build (); HttpGet request = new HttpGet ("// www.google.com:81"); válasz = kliens.végrehajtás (kérés);

Észre fogja venni az újrapróbálkozási logikát DEBUG naplószinttel:

DEBUG o.a.h.i.c.HttpClientConnectionOperator - Csatlakozás a www.google.com/173.194.34.212:81 címhez. DEBUG o.a.h.i.c.HttpClientConnectionOperator - Csatlakozás a www.google.com/173.194.34.212:81 webhelyhez időtúllépett. A kapcsolatot egy másik IP-címmel, DEBUG o.a.h.i.c.HttpClientConnectionOperator - Csatlakozás a www.google.com/173.194.34.208:81 DEBUG o.a.h.i.c.HttpClientConnectionOperator - Csatlakozás a www.google.com/173.194.34.208:81 időzítéssel próbálkozzon újra. A kapcsolatot egy másik IP-címmel, DEBUG o.a.h.i.c.HttpClientConnectionOperator - Csatlakozás a www.google.com/173.194.34.209:81 DEBUG o.a.h.i.c.HttpClientConnectionOperator - Csatlakozás a www.google.com/173.194.34.209:81 időzítéssel próbálkozzon újra. A kapcsolatot egy másik IP-cím használatával próbáljuk meg újból // ...

8. Következtetés

Ez az oktatóanyag megvitatta, hogyan lehet konfigurálni a különböző típusú időtúllépéseket HttpClient. Ez egy egyszerű mechanizmust is illusztrált a folyamatos HTTP-kapcsolat nehéz időkorlátjára.

Ezen példák megvalósítása megtalálható a GitHub projektben.