2012-03-26 27 views
24

Tôi cần đặt thời gian cho yêu cầu Http chúng tôi thực hiện cho dịch vụ (không phải dịch vụ web). Chúng tôi đang sử dụng Apache HTTP Client. Tôi đã thêm 2 dòng mã này để đặt thời gian ra theo yêu cầu và phản hồi dịch vụ.Sử dụng Apache HttpClient cách đặt TIMEOUT theo yêu cầu và phản hồi

HttpConnectionParams.setConnectionTimeout(params, 10000); 
HttpConnectionParams.setSoTimeout(params, 10000); 

1) Hiện tại tôi đã đặt 10 giây làm thời gian chờ vì tôi thấy phản hồi đến từ dịch vụ gần như ngay lập tức. Tôi có nên tăng hoặc giảm thời gian không?

2) Điều gì sẽ xảy ra khi phản hồi mất hơn 10 giây? Nó sẽ ném ngoại lệ và nó sẽ là ngoại lệ nào? Có điều gì khác tôi cần phải thêm để đặt thời gian ra trong mã dưới đây.

public HashMap<String, Object> getJSONData(String url) throw Exception{ 
    DefaultHttpClient httpClient = new DefaultHttpClient(); 
    HttpParams params = httpClient.getParams(); 
    HttpConnectionParams.setConnectionTimeout(params, 10000); 
    HttpConnectionParams.setSoTimeout(params, 10000); 
    HttpHost proxy = new HttpHost(getProxy(), getProxyPort()); 
    ConnRouteParams.setDefaultProxy(params, proxy); 
    URI uri; 
    InputStream data = null; 
    try { 
     uri = new URI(url); 
     HttpGet method = new HttpGet(uri); 
     HttpResponse response = httpClient.execute(method); 
     data = response.getEntity().getContent(); 
    } 
    catch (Exception e) { 
     e.printStackTrace(); 
    } 
    Reader r = new InputStreamReader(data); 
    HashMap<String, Object> jsonObj = (HashMap<String, Object>) GenericJSONUtil.fromJson(r); 
    return jsonObj; 
} 

Trả lời

31

Ngoại lệ bạn sẽ thấy sẽ là ConnectTimeoutExceptionSocketTimeoutException. Các giá trị thời gian chờ thực tế bạn sử dụng phải là thời gian tối đa mà ứng dụng của bạn sẵn sàng chờ đợi. Một lưu ý quan trọng về thời gian chờ đọc là nó tương ứng với thời gian chờ trên một socket đọc. Vì vậy, nó không phải là thời gian cho phép cho các phản ứng đầy đủ để đến nơi, mà là thời gian cho một ổ cắm duy nhất đọc. Vì vậy, nếu có 4 lần đọc socket, mỗi lần lấy 9 giây, tổng thời gian đọc của bạn là 9 * 4 = 36 giây.

Nếu bạn muốn chỉ định tổng thời gian cho phản hồi đến (bao gồm kết nối và tổng thời gian đọc), bạn có thể kết thúc cuộc gọi trong chuỗi và sử dụng hết thời gian chờ của chủ đề đó. Ví dụ, tôi thường làm một cái gì đó như thế này:

Future<T> future = null; 
future = pool.submit(new Callable<T>() { 
    public T call() { 
     return executeImpl(url); 
    } 
}); 

try { 
    return future.get(10, TimeUnit.SECONDS); 
} 
catch (InterruptedException e) { 
    log.warn("task interrupted", name); 
} 
catch (ExecutionException e) { 
    log.error(name + " execution exception", e); 
} 
catch (TimeoutException e) { 
    log.debug("future timed out", name); 
} 

Một số giả thiết đưa ra trong đoạn code trên là: 1) đây là trong một hàm với một tham số url, 2) đó là trong một lớp học với một biến tên, 3) log là một thể hiện log4j, và 4) pool là một trình thực thi pool nào đó. Lưu ý rằng ngay cả khi bạn sử dụng thời gian chờ của luồng, bạn cũng nên chỉ định thời gian chờ kết nối và ổ cắm trên HttpClient, do đó yêu cầu chậm không ăn hết tài nguyên trong nhóm luồng. Cũng lưu ý rằng tôi sử dụng một hồ bơi thread bởi vì thường tôi sử dụng điều này trong một dịch vụ web để hồ bơi thread được chia sẻ trên một loạt các chủ đề tomcat. Bạn là môi trường có thể khác nhau, và bạn có thể chỉ đơn giản là sinh ra một chủ đề mới cho mỗi cuộc gọi.

Ngoài ra, tôi đã thường thấy timeouts thiết lập thông qua chức năng thành viên của params, như thế này:

params.setConnectionTimeout(10000); 
params.setSoTimeout(10000); 

Nhưng có lẽ cú pháp của bạn hoạt động cũng như (không chắc chắn).

+0

Tôi cần phải thiết lập/thêm gì nếu tôi phải cho phép Thời gian đáp ứng đầy đủ đến – pushya

+0

Bạn có thể giải thích ý nghĩa của 4 socket đọc không? Nếu chúng được đọc 4 socket thì sẽ có 4 yêu cầu khác nhau liên quan đến việc đọc đó. – pushya

+2

không, phản hồi có thể có nhiều phần.Nếu bạn nhìn vào bất kỳ mã socket mức thấp nào bạn sẽ thấy rằng 'read()' xảy ra trong một vòng lặp while, và giá trị trả về của 'read()' là số byte được đọc. Không có yêu cầu rằng toàn bộ phản ứng đến trong một ổ cắm duy nhất đọc. Tôi sẽ cập nhật câu trả lời của mình để bao gồm thêm chi tiết. – Kevin

47

Tôi đoán nhiều người đến đây vì tên sách và vì API HttpConnectionParams không còn được dùng nữa.

Sử dụng một phiên bản mới của Apache HTTP Client, bạn có thể thiết lập các timeouts sử dụng params yêu cầu:

HttpPost request = new HttpPost(url); 

RequestConfig requestConfig = RequestConfig.custom() 
    .setSocketTimeout(TIMEOUT_MILLIS) 
    .setConnectTimeout(TIMEOUT_MILLIS) 
    .setConnectionRequestTimeout(TIMEOUT_MILLIS) 
    .build(); 

request.setConfig(requestConfig); 

Ngoài ra, bạn cũng có thể thiết lập này khi bạn tạo khách hàng HTTP của bạn, bằng cách sử dụng API xây dựng cho HTTP client, nhưng bạn cũng sẽ cần phải xây dựng một trình quản lý kết nối tùy chỉnh với một cấu hình socket tùy chỉnh.

configuration example file là một tài nguyên tuyệt vời để tìm hiểu về cách định cấu hình Ứng dụng khách HTTP HTTP.

Các vấn đề liên quan