2011-12-22 9 views
14

Tôi có hai máy chủ Tomcat cần duy trì kết nối liên tục để cắt giảm việc bắt tay SSL. Một máy chủ (proxy) nằm trong DMZ trong khi máy chủ khác an toàn sau tường lửa khác. Proxy về cơ bản chỉ chạy một servlet đơn giản thực hiện kiểm tra tính hợp lệ trước khi chuyển tiếp các yêu cầu tới máy an toàn. Trên một yêu cầu intial các máy trao đổi chứng chỉ trước khi thực hiện công việc thực tế. Vì vậy, tôi muốn duy trì kết nối liên tục với thời gian chờ vài phút.Tomcat, HTTP Keep-Alive và HttpsUrlConnection của Java

Để nói chuyện với máy chủ bảo mật, servlet trên proxy sử dụng HttpsUrlConnection. Tôi đã thiết lập WireShark và tôi đã nhận thấy rằng bất kể giá trị keepAliveTimeout tôi đặt cho đầu nối trên máy bảo mật, kết nối TCP sẽ bị đóng sau khoảng 5 hoặc 10 giây. Con số này dường như phù hợp với những gì tôi đã đọc là thời gian chờ mặc định và cách Java xử lý HTTP Keep-Alive. Điều này link giải thích rằng Java vinh danh thời gian chờ Keep-Alive nếu nó được gửi bởi máy chủ, nếu không nó sẽ sử dụng 5 giây (kết nối trực tiếp) hoặc 10 giây (kết nối proxy) trước khi đóng kết nối.

Điều tôi đang cố gắng tìm ra là làm cách nào để buộc Tomcat gửi tiêu đề Keep-Alive. Không, Connection: Keep-Alive, nhưng Keep-Alive: timeout=x.

Tôi đã thử nghiệm với máy chủ Apache HTTP và sửa đổi keepAliveTimeout trong httpd.conf không làm cho tiêu đề Keep-Alive thay đổi giá trị thời gian chờ của nó. Hơn nữa Java không tôn trọng thời gian chờ này.

CẬP NHẬT (12/23/11): Sau khi chạy thêm một vài thử nghiệm, tôi đã thử thêm một số mã nhanh chóng và bẩn bằng cách sử dụng HttpClient (3.1) của Apache thay vì HttpsUrlConnection. Có vẻ như HttpClient, khi được đặt để sử dụng Keep-Alive, chỉ cần đợi máy chủ đóng kết nối. Tôi không biết nó sẽ đợi bao lâu. Tôi đang quay để duy trì kết nối HTTP trong 3 đến 5 phút.

+0

"Kết nối TCP bị đóng sau khoảng 5 hoặc 10 giây". Cuối cùng thì sao? Máy khách hoặc máy chủ? – EJP

+0

Ứng dụng đã đóng ứng dụng khách. –

+0

Bạn biết đấy, kịch bản bạn mô tả; Máy chủ Web trong các yêu cầu chuyển tiếp DMZ tới Trình quản lý ứng dụng phía sau một số tường lửa, thường được xử lý bằng Apache HTTPD trong DMZ thực hiện công cụ https và chuyển tiếp các yêu cầu tới Máy chủ ứng dụng Tomcat bằng trình kết nối AJP (http://tomcat.apache.org/tomcat-4.0 -doc/config/ajp.html). Đây là một cách thay thế để tránh chi phí SSL. –

Trả lời

6

Tôi đã có thể sử dụng HttpClient 3.1 để giữ kết nối HTTP mở trong 5 phút bằng cách đặt keepAliveTimeout trong đầu nối Tomcat thành 300000. Tôi đã xác minh bằng cách sử dụng WireShark rằng máy chủ sẽ chấm dứt kết nối trong khi HttpClient sẽ đợi. Các yêu cầu tiếp theo thông qua HttpClient sẽ sử dụng lại kết nối TCP hiện có (tránh bất kỳ sự bắt tay SSL nào). Chìa khóa ở đó mặc dù là có một cá thể HttpClient đơn (tức là không tạo ra một lần mỗi lần). Điều này có thể là hiển nhiên đối với hầu hết nhưng tôi không chắc cơ chế API cho HTTPClient là gì. Trong ngắn hạn, tạo một thể hiện HttpClient và cho mỗi yêu cầu (POST, GET, vv) tạo một PostMethod mới, GetMethod, vv Điều này sẽ làm cho kết nối TCP được tái sử dụng.

1

Java API Http(s)UrlConnection danh dự liền mạch thông tin Keep-Alive và quản lý một nhóm kết nối cho mỗi máy chủ lưu trữ theo số following detailed explanation (đọc kỹ - mỗi chi tiết đều quan trọng).

Trong trường hợp đó, mã của bạn phải đọc hoàn toàn bộ đệm, đóng luồng và đọc lỗi trong trường hợp IOException.

Tất nhiên HttpClient có ít ràng buộc hơn nhưng cách tốt nhất để xử lý tình huống của bạn là sử dụng MultiThreadedHttpConnectionManager nhờ vào following guidelines.

4

Trong Tomcat tôi quản lý để thiết lập các tiêu đề trong HttpServelet tôi sử dụng HttpServletResponse.addHeader() như thế này:

response.addHeader("Connection", "Keep-Alive"); 
    response.addHeader("Keep-Alive", "timeout=60000"); 

Tôi khẳng định với Wireshark rằng điều này không làm việc với HttpUrlConnection về phía khách hàng. Nó không hoạt động nếu bạn không đặt tiêu đề "Kết nối", vì vậy bạn cần phải đặt cả hai.

+0

Tiêu đề kết nối nên được đặt tự động bởi tomcat nếu cấu hình Keep-Alive được thêm vào. Bạn đang sao chép Keep-Alive từ tệp server.xml của tomcat và cũng là mã của bạn đang trả về một tiêu đề Keep-Alive tùy chỉnh. Có một cơ hội rất tốt của cả hai đi ra khỏi đồng bộ và trong trường hợp xấu nhất nếu thời gian chờ ứng dụng bằng cách nào đó dài hơn tomcat hoặc tomcat chính nó quyết định đóng, sau đó khách hàng sẽ thất bại. – kisna