2009-08-15 26 views
78

Trong một thời gian, tôi đã sử dụng HttpClient trong môi trường đa luồng. Đối với mỗi luồng, khi nó khởi tạo một kết nối, nó sẽ tạo ra một cá thể HttpClient hoàn toàn mới.Thực hành tốt nhất để sử dụng HttpClient trong môi trường đa luồng

Gần đây, tôi đã phát hiện ra rằng, bằng cách sử dụng phương pháp này, nó có thể khiến người dùng có quá nhiều cổng đang được mở và hầu hết các kết nối đều ở trạng thái TIME_WAIT.

http://www.opensubscriber.com/message/[email protected]/86045.html

Do đó, thay vì mỗi thread thực hiện:

HttpClient c = new HttpClient(); 
try { 
    c.executeMethod(method); 
} 
catch(...) { 
} 
finally { 
    method.releaseConnection(); 
} 

Chúng tôi dự định có:

[PHƯƠNG PHÁP A]

// global_c is initialized once through 
// HttpClient global_c = new HttpClient(new MultiThreadedHttpConnectionManager()); 

try { 
    global_c.executeMethod(method); 
} 
catch(...) { 
} 
finally { 
    method.releaseConnection(); 
} 

Trong một tình huống bình thường, global_c sẽ được truy cập bởi 50 ++ chủ đề đồng thời. Tôi đã tự hỏi, điều này sẽ tạo ra bất kỳ vấn đề hiệu suất? MultiThreadedHttpConnectionManager có sử dụng cơ chế không khóa để thực thi chính sách an toàn của luồng không?

Nếu 10 chủ đề đang sử dụng global_c, 40 chủ đề khác có bị khóa không?

Hoặc sẽ tốt hơn nếu, trong mỗi chủ đề, tôi tạo một thể hiện của HttpClient, nhưng phát hành trình quản lý kết nối một cách rõ ràng?

[PHƯƠNG PHÁP B]

MultiThreadedHttpConnectionManager connman = new MultiThreadedHttpConnectionManager(); 
HttpClient c = new HttpClient(connman); 
try { 
     c.executeMethod(method); 
} 
catch(...) { 
} 
finally { 
    method.releaseConnection(); 
    connman.shutdown(); 
} 

sẽ connman.shutdown() bị các vấn đề hiệu suất?

Tôi có thể biết phương pháp nào (A hoặc B) tốt hơn, đối với ứng dụng sử dụng chuỗi 50 ++ không?

Trả lời

16

Phương pháp A được cộng đồng nhà phát triển httpclient khuyến nghị.

Vui lòng tham khảo http://www.mail-archive.com/[email protected]/msg02455.html để biết thêm chi tiết.

+1

Khi nào một người gọi "tắt máy" trên trình quản lý kết nối nếu máy khách được tạo ra toàn cầu. –

+1

Những công cụ/lệnh linux nào hữu ích để gỡ rối hoặc "hình dung" hành vi của ConnectionManager dưới mui xe? Tôi hỏi vì chúng tôi hiện đang gặp rắc rối với các kết nối trong CLOSE_WAIT và các hiệu ứng khác và chúng tôi đang tìm kiếm một cách tốt để xem chính xác những gì đang diễn ra. – Christoph

+0

@WandMaker Tôi khá chắc chắn bạn sẽ chỉ cần tắt máy khi một trong hai chương trình thoát hoặc khi bạn kết thúc với một số công việc mà bạn sẽ không cần bất kỳ kết nối nào trong một thời gian. –

12

Việc đọc tài liệu của tôi là chính HttpConnection không được coi là chuỗi an toàn, và do đó MultiThreadedHttpConnectionManager cung cấp một nhóm dùng lại HttpConnections, bạn có một MultiThreadedHttpConnectionManager được chia sẻ bởi tất cả các luồng và khởi tạo chính xác một lần. Vì vậy, bạn cần có một vài cải tiến nhỏ để lựa chọn A.

MultiThreadedHttpConnectionManager connman = new MultiThreadedHttpConnectionManag 

Sau đó, mỗi chủ đề nên sử dụng trình tự cho mọi yêu cầu, nhận được một conection từ hồ bơi và đưa nó trở lại khi hoàn thành công việc của mình - sử dụng một cuối cùng khối có thể tốt. Bạn cũng nên mã cho khả năng rằng các hồ bơi không có kết nối có sẵn và xử lý các ngoại lệ thời gian chờ.

HttpConnection connection = null 
try { 
    connection = connman.getConnectionWithTimeout(
         HostConfiguration hostConfiguration, long timeout) 
    // work 
} catch (/*etc*/) {/*etc*/} finally{ 
    if (connection != null) 
     connman.releaseConnection(connection); 
} 

Vì bạn đang sử dụng một nhóm kết nối bạn sẽ không thực sự đóng kết nối và vì vậy điều này sẽ không xảy ra sự cố TIME_WAIT. Cách tiếp cận này giả định rằng mỗi luồng không treo vào kết nối lâu. Lưu ý rằng conman chính nó là trái mở.

+0

Không thực sự trả lời cho câu hỏi của tôi, phương pháp (A hoặc B) nào tốt hơn. –

+4

Câu trả lời là không đúng. Tôi sẽ đánh vần nó. – djna

5

Tôi nghĩ bạn sẽ muốn sử dụng ThreadSafeClientConnManager.

Bạn có thể xem làm thế nào nó hoạt động ở đây: http://foo.jasonhudgins.com/2009/08/http-connection-reuse-in-android.html

Hoặc trong AndroidHttpClient trong đó sử dụng nó trong nội bộ.

+1

Opps. Không có kế hoạch để di chuyển từ HttpClient 3.x đến 4.x, như 3.x đã được chạy hoàn hảo trong ứng dụng của tôi trong gần 2 năm :) –

+9

Chắc chắn, chỉ khi ai đó đến đây Googling cho một câu trả lời :) –

41

Chắc chắn phương pháp A vì được gộp chung và chuỗi an toàn.

Nếu bạn đang sử dụng httpclient 4.x, trình quản lý kết nối được gọi là ThreadSafeClientConnManager. Xem chi tiết link để biết thêm chi tiết (cuộn xuống "Quản lý kết nối gộp"). Ví dụ:

HttpParams params = new BasicHttpParams(); 
    SchemeRegistry registry = new SchemeRegistry(); 
    registry.register(new Scheme("http", PlainSocketFactory.getSocketFactory(), 80)); 
    ClientConnectionManager cm = new ThreadSafeClientConnManager(params, registry); 
    HttpClient client = new DefaultHttpClient(cm, params); 
+44

[ThreadSafeClientConnManager ] (http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/impl/conn/tsccm/ThreadSafeClientConnManager.html) đã không được hỗ trợ cho [PoolingClientConnManager] (http: //hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/impl/conn/PoolingClientConnectionManager.html) trong 4.2 –

+0

Xin chào, httpclient có thể được tạo bằng phương pháp này được sử dụng để duy trì phiên làm được mô tả ở đây http://stackoverflow.com/questions/5960832/maintaining-session-in-android-application-stay-authenticated-on-the-server-si ...? Bởi vì khi tôi cố gắng, tôi đã không thể duy trì phiên qua các yêu cầu khác nhau ... – sakthig

+11

4.3.1 tại đây: PoolingClientConnManager đã không được hỗ trợ cho PoolingHttpClientConnectionManager. – Matthias

0

Với HttpClient 4.5 bạn có thể làm điều này:

CloseableHttpClient httpClient = HttpClients.custom().setConnectionManager(new PoolingHttpClientConnectionManager()).build(); 

Lưu ý rằng điều này thực hiện có thể đóng (ví tắt của người quản lý kết nối).

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