HTTP client là gì các bạn? Nói nôm na ví dụ bạn muốn truy cập vào một website nào đó thì bạn chính là một client (khách). Bạn đánh URL của website vào trình duyệt, và bạn nhận được nội dung của website đó trên trình duyệt. Đa phần các website đều sử dụng giao thức HTTP, và khi bạn truy cập vào những website đó, chúng ta có thể gọi bạn là một HTTP client.
Vậy connection pool thì sao? Ví dụ bạn đang viết một chương trình truy cập vào một website nào đó nhiều lần trong một khoảng thời gian nhất định. Bạn lặp đi lặp lại việc mở kết nối tới website đó, nhận nội dung rồi lại ngắt kết nối. Sẽ tốt hơn nếu chúng ta có một nơi chứa kết nối của chúng ta tới website đó, sau đó chúng ta chỉ cần lấy nội dung của website mà không cần quan tâm đến kết nối tới website đó nữa. Và nơi mà chứa kết nối của chúng ta đến website, chúng ta gọi là pool. Chúng ta chỉ cần lấy kết nối từ pool đó ra mà sử dụng thôi. (tiếng Anh từ pool có nghĩa là hồ bơi, chúng ta có thể hình dung tại sao gọi nơi chứa các kết nối là pool rồi phải không các bạn?)
Trong bài viết này mình sẽ hướng dẫn các bạn làm thế nào để tạo ra một HTTP client connection pool sử dụng thư viện HTTP Client của tổ chức Apache và cách sử dụng connection pool đó như thế nào?
OK, bắt đầu nhé các bạn!
Giờ chúng ta sẽ thêm dependency của thư viện HTTP client vào nhé.
1 2 3 4 5 |
<dependency> <groupId>org.apache.httpcomponents</groupId> <artifactId>httpclient</artifactId> <version>4.5.2</version> </dependency> |
Để thấy rõ sự khác biệt giữa sử dụng connection pool và không sử dụng connection pool, đầu tiên mình sẽ viết code để tạo ra một HTTP client bình thường, không sử dụng connection pool để xem kết quả như thế nào? Tất nhiên mình vẫn sử dụng thư viện HTTP client.
Nội dung như sau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
public class HttpClientExample { public static void main(String[] args) throws ClientProtocolException, IOException, InterruptedException { final String url = "http://localhost:8080/"; final CloseableHttpClient httpclient = HttpClients.createSystem(); for (int i = 0; i < 10; i++) { new Thread(new Runnable() { public void run() { try { HttpGet httpGet = new HttpGet(url); CloseableHttpResponse response = httpclient.execute(httpGet); HttpEntity entity = response.getEntity(); EntityUtils.consume(entity); response.close(); } catch (Exception e) { e.printStackTrace(); } } }).start(); } Thread.sleep(100000); } } |
Mình đang sử dụng đối tượng CloseableHttpClient đóng vai trò như một HTTP client, có nghĩa nó là đối tượng sẽ gửi request tới một website nào đó. Trong ví dụ này, mình chạy một website ở máy tính của mình và sẽ gửi cùng lúc 10 request tới website này.
Để kiểm chứng có bao nhiêu request tới website trong ví dụ của mình, mình sẽ chạy câu lệnh sau bằng command line:
1 |
netstat -an | grep "8080" |
Kết quả
Đây là số kết nối tới cổng 8080 trên máy tính của mình trước khi mình chạy đoạn code trên. Hiện tại là có 2 kết nối, bây giờ mình sẽ chạy đoạn code ví dụ để xem số kết nối sẽ tăng như thế nào nhé các bạn.
Và đây là kết quả:
Như các bạn thấy, đã có thêm 10 kết nối tới cổng 8080 trên máy tính của mình.
Bây giờ mình sẽ viết code chuyển sang sử dụng connection pool thử xem sao nhé!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
public class HttpClientExample { public static void main(String[] args) throws ClientProtocolException, IOException, InterruptedException { PoolingHttpClientConnectionManager pool = new PoolingHttpClientConnectionManager(); pool.setDefaultMaxPerRoute(1); pool.setMaxTotal(1); final CloseableHttpClient httpclient = HttpClients.custom().setConnectionManager(pool).build(); final String url = "http://localhost:8080/"; for (int i = 0; i < 10; i++) { new Thread(new Runnable() { public void run() { try { HttpGet httpGet = new HttpGet(url); CloseableHttpResponse response = httpclient.execute(httpGet); HttpEntity entity = response.getEntity(); EntityUtils.consume(entity); response.close(); } catch (Exception e) { e.printStackTrace(); } } }).start(); } Thread.sleep(100000); } } |
Thư viện HttpClient cung cấp cho chúng ta một đối tượng tên là PoolingHttpClientConnectionManager giúp chúng ta có thể quản lý được số connection tới một website nhất định. Chúng ta có thể cấu hình số connection tối đa tới một website nào đó, hoặc tổng số kết nối mà ứng dụng của chúng ta có thể mở để kết nối đến các website khác nhau.
Để đưa đối tượng PoolingHttpClientConnectionManager vào đối tượng HttpClient chúng ta dùng phương thức setConnectionManager().
Và bên dưới là kết quả khi chúng ta dùng connection pool!
Các bạn thấy đó, chỉ có duy nhất một connection được mở giữa ứng dụng của chúng ta và website mà chúng ta kết nối tới.