2012-07-29 28 views
10

Tôi có một máy khách node.js (10.177.62.7) yêu cầu một số dữ liệu từ dịch vụ nghỉ ngơi http từ máy chủ (10.177.0.1). Máy khách chỉ đơn giản là sử dụng phương thức http.request() của node.js (agent = false). Khách hàng đang ở trên hộp Ubuntu 11.10.Máy khách gửi FIN ACK bị trễ (~ 500ms) đến máy chủ

Tại sao khách hàng gửi FIN ACK sau 475ms? Tại sao quá chậm? Anh ấy nên gửi FIN ACK ngay lập tức. Tôi có nhiều tình huống như thế này. Khoảng 1% toàn bộ lưu lượng truy cập là yêu cầu với FIN ACK bị trì hoãn.

Cpu không hoạt động trên máy khách là khoảng 99%, vì vậy không có gì thoát CPU.

Cách gỡ lỗi này? Nó có thể là gì? Có tùy chọn sysctl nào tôi cần điều chỉnh không?

Trên ảnh chụp màn hình, cột thứ hai là thời gian trôi qua giữa các gói.

Link to bigger picture.

enter image description here

+0

Tôi đã xóa câu trả lời của tôi về HTTP giữ nguyên vì nó đã được loại trừ dứt khoát. Tuy nhiên, không thể nghĩ ra bất kỳ câu trả lời nào khác. FIN nên đi ra ngay sau khi ổ cắm được đóng lại. –

+0

@AlanCurry Nhưng * FIN/ACK * sẽ chỉ đi ra ngoài khi khách hàng đã đọc FIN đến và quyết định đóng socket, có thể mất bất kỳ lượng thời gian nào. Đây là một hành vi của node.js, không phải là ngăn xếp TCP/IP. – EJP

+0

Chắc chắn, nhưng nếu nó đang ở giữa một cuộc gọi đến một thư viện khách hàng http, nó không làm sống động, và tải CPU là 1%, những gì mất nó quá lâu để đóng socket sau khi đọc EOF? –

Trả lời

4

Hành vi này là tính năng ACK trễ của RFC1122 TCP stack.

Thông thường bạn nên thêm tùy chọn TCP_QUICKACK để bạn Linux TCP socket-disable delayed ACK nhưng tôi nghĩ rằng nó không phải là rõ ràng với JavaScript Node.js API (Tôi chỉ thấy socket.setNoDelay cho TCP_NODELAY tùy chọn).

Vì vậy, ý tưởng của bạn để áp dụng system-wide change on TCP stack có vẻ tốt nhưng tôi không tìm thấy sysctl khớp với hành vi tùy chọn socket này. Dưới đây là một số khác là full list with explanation.

+0

Điều này giống như câu trả lời đúng trừ khi có thêm chi tiết OP không cung cấp –

+0

Cảm ơn câu trả lời của bạn! Tôi có thêm một số câu hỏi. Đây có phải là hợp lệ cho FIN ACK hoặc chỉ cho ACK "một mình". Bạn có thể nói lý do tại sao hạt nhân bị trì hoãn rằng FIN/ACK. Trong dữ liệu tcpflow có exacly một ACK cho mỗi gói đi từ máy chủ. Tại sao hạt nhân bị trì hoãn khách hàng FIN/ACK. Nó có thể tránh gửi ACK mỗi gói dữ liệu. Nhưng nó chọn để trì hoãn FIN/ACK? Điều này có thể không? – Tereska

+0

Vui lòng đọc phần 4.2.3.2 của RFC1122 ... nó không dành riêng cho gói FIN. Tôi đồng ý với bạn rằng không có lý do gì để trì hoãn gói FIN + ACK mà không có dữ liệu. Tôi mời các bạn liên hệ với nhóm nhân Linux của TCP trên LKML hoặc mã nguồn mở để thực thi logic ACK bị trì hoãn.Có lẽ một tối ưu hóa có thể được thực hiện và ít nhất một chuyển đổi sysctl mới để tránh hành vi đó. –

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