Http Waktu Pelanggan habis

1. Gambaran keseluruhan

Tutorial ini akan menunjukkan cara mengkonfigurasi timeout dengan Apache HttpClient 4 .

Sekiranya anda ingin menggali lebih mendalam dan mengetahui perkara menarik lain yang boleh anda lakukan dengan HttpClient - teruskan ke tutorial HttpClient utama .

2. Mengkonfigurasi Timeout Sebelum HttpClient 4.3

2.1. Parameter Rentetan Mentah

Sebelum versi 4.3 keluar, HttpClient hadir dengan banyak parameter konfigurasi, dan semua ini dapat disusun secara umum seperti peta.

Terdapat 3 parameter timeout untuk dikonfigurasi :

DefaultHttpClient httpClient = new DefaultHttpClient(); int timeout = 5; // seconds 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

Yang lebih penting dari parameter ini - iaitu dua yang pertama - juga dapat ditetapkan melalui API yang lebih selamat dari jenis:

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

Parameter ketiga tidak mempunyai setter khusus di HttpConnectionParams , dan ia masih perlu diset secara manual melalui kaedah setParameter .

3. Konfigurasikan Waktu Henti Menggunakan 4.3 Baru. Pembina

API pembangun yang fasih yang diperkenalkan pada 4.3 menyediakan cara yang tepat untuk menetapkan batas waktu pada tahap tinggi :

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

Itulah kaedah yang disyorkan untuk mengkonfigurasi ketiga-tiga waktu tamat dengan cara yang selamat dan mudah dibaca.

4. Sifat Timeout Dijelaskan

Sekarang, mari kita jelaskan maksud pelbagai jenis timeout ini:

  • Waktu Sambungan Sambungan ( http.connection.timeout ) - masa untuk menjalin hubungan dengan host jauh
  • yang Timeout Socket ( http.socket.timeout ) - masa menunggu data - selepas mewujudkan sambungan; masa maksimum tidak aktif antara dua paket data
  • yang Connection Manager Timeout ( http.connection-manager.timeout ) - masa untuk menunggu sambungan daripada pengurus sambungan / kolam renang

Dua parameter pertama - masa tamat sambungan dan soket - adalah yang paling penting. Walau bagaimanapun, menetapkan batas waktu untuk mendapatkan sambungan pasti penting dalam senario beban tinggi, itulah sebabnya parameter ketiga tidak boleh diabaikan.

5. Menggunakan HttpClient

Setelah mengkonfigurasinya, kita sekarang dapat menggunakan klien untuk melakukan permintaan HTTP:

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

Dengan pelanggan yang telah ditentukan sebelumnya, sambungan ke hos akan habis dalam 5 saat. Juga, jika sambungan dibuat tetapi tidak ada data yang diterima, masa tamat juga akan menjadi 5 saat tambahan .

Perhatikan bahawa tamat masa sambungan akan menghasilkan org.apache.http.conn.ConnectTimeoutException dilemparkan, sementara waktu tunggu soket akan menghasilkan java.net.SocketTimeoutException .

6. Waktu Tamat Keras

Walaupun menetapkan batas waktu untuk mewujudkan sambungan HTTP dan tidak menerima data sangat berguna, kadang-kadang kita perlu menetapkan waktu tunggu yang sukar untuk keseluruhan permintaan .

Sebagai contoh, muat turun fail yang berpotensi besar sesuai dengan kategori ini. Dalam kes ini, sambungan mungkin berjaya dibuat, data dapat dilakukan secara konsisten, tetapi kami masih perlu memastikan bahawa operasi tidak melewati ambang waktu tertentu.

HttpClient tidak mempunyai konfigurasi yang membolehkan kami menetapkan batas waktu keseluruhan untuk permintaan; namun, ia menyediakan fungsi batalkan untuk permintaan , jadi kami dapat memanfaatkan mekanisme tersebut untuk menerapkan mekanisme waktu tunggu yang sederhana:

HttpGet getMethod = new HttpGet( "//localhost:8080/httpclient-simple/api/bars/1"); int hardTimeout = 5; // seconds 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( "HTTP Status of response: " + response.getStatusLine().getStatusCode());

Kami menggunakan java.util.Timer dan java.util.TimerTask untuk menyiapkan tugas tertunda sederhana yang membatalkan permintaan HTTP GET setelah habis masa 5 saat.

7. Timeout dan DNS Round Robin - Sesuatu yang Perlu Diketahui

Cukup umum bahawa beberapa domain yang lebih besar akan menggunakan konfigurasi round robin DNS - pada dasarnya mempunyai domain yang sama dipetakan ke beberapa alamat IP . Ini memperkenalkan cabaran baru untuk tamat masa terhadap domain seperti itu, hanya kerana cara HttpClient akan cuba menyambung ke domain tersebut yang habis:

  • HttpClient mendapat senarai laluan IP ke domain tersebut
  • ia mencuba yang pertama - habis masa (dengan masa tamat yang kita konfigurasikan)
  • ia mencuba yang kedua - yang juga habis
  • dan sebagainya …

Oleh itu, seperti yang anda lihat - operasi keseluruhan tidak akan habis apabila kita menjangkakannya . Sebaliknya - ia akan tamat apabila semua laluan mungkin akan tamat. Lebih-lebih lagi - ini akan berlaku sepenuhnya secara telus untuk pelanggan (kecuali jika log anda dikonfigurasi pada tahap DEBUG).

Berikut adalah contoh mudah yang boleh anda jalankan dan ulangi masalah ini:

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 request = new HttpGet("//www.google.com:81"); response = client.execute(request);

Anda akan melihat logik mencuba semula dengan tahap log DEBUG:

DEBUG o.a.h.i.c.HttpClientConnectionOperator - Connecting to www.google.com/173.194.34.212:81 DEBUG o.a.h.i.c.HttpClientConnectionOperator - Connect to www.google.com/173.194.34.212:81 timed out. Connection will be retried using another IP address DEBUG o.a.h.i.c.HttpClientConnectionOperator - Connecting to www.google.com/173.194.34.208:81 DEBUG o.a.h.i.c.HttpClientConnectionOperator - Connect to www.google.com/173.194.34.208:81 timed out. Connection will be retried using another IP address DEBUG o.a.h.i.c.HttpClientConnectionOperator - Connecting to www.google.com/173.194.34.209:81 DEBUG o.a.h.i.c.HttpClientConnectionOperator - Connect to www.google.com/173.194.34.209:81 timed out. Connection will be retried using another IP address //...

8. Kesimpulannya

Tutorial ini membincangkan cara mengkonfigurasi pelbagai jenis timeout yang tersedia untuk HttpClient . Ini juga menggambarkan mekanisme sederhana untuk penghentian sambungan HTTP yang berterusan.

Pelaksanaan contoh-contoh ini boleh didapati dalam projek GitHub.