2012-02-06 13 views
5

thể trùng lặp:
'ab' program freezes after lots of requests, why?Tại sao một máy chủ Thin đơn giản dừng đáp ứng tại 16500 yêu cầu khi điểm chuẩn?

Dưới đây là một máy chủ thử nghiệm đơn giản:

require 'rubygems' 
require 'rack' 
require 'thin' 

class HelloWorld 

    def call(env) 
    [200, {"Content-Type" => "text/plain"}, "OK"] 
    end 
end 

Rack::Handler::Thin.run HelloWorld.new, :Port => 9294 
#I've tried with these added too, 'rack.multithread' => true, 'rack.multiprocess' => true 

Dưới đây là một thử nghiệm chạy:

$ ab -n 20000 http://0.0.0.0:9294/sdf 
This is ApacheBench, Version 2.3 <$Revision: 655654 $> 
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ 
Licensed to The Apache Software Foundation, http://www.apache.org/ 

Benchmarking 0.0.0.0 (be patient) 
Completed 2000 requests 
Completed 4000 requests 
Completed 6000 requests 
Completed 8000 requests 
Completed 10000 requests 
Completed 12000 requests 
Completed 14000 requests 
Completed 16000 requests 
apr_poll: The timeout specified has expired (70007) 
Total of 16347 requests completed 

Nó vỡ xuống vào khoảng năm 16500. Tại sao? Làm thế nào tôi có thể tìm hiểu những gì đang xảy ra. Là GC trong ruby ​​hay là một cái gì đó với số lượng các ổ cắm mạng có sẵn trên một máy OS X. Tôi có bộ nhớ MPB 2.5 Ghz 6G.


Sửa

Sau một số cuộc thảo luận ở đây và thử nghiệm những điều khác nhau, nó có vẻ như thay đổi net.inet.tcp.msl từ 15000 đến 1000ms làm cho vấn đề kiểm tra các máy chủ web tần số cao với ab đi.

sudo sysctl -w net.inet.tcp.msl=1000 # this is only good for local development 

Xem câu hỏi được tham chiếu với câu trả lời cho vấn đề này. 'ab' program freezes after lots of requests, why?

+1

Bạn đã tìm thấy lý do ?? Một lời giải thích tiềm năng có thể là hệ điều hành giữ một ổ cắm trong trạng thái "được sử dụng gần đây" và không sử dụng lại nó trong vài phút. Rõ ràng người ta có thể cấu hình lại lớp IP của hệ điều hành để không làm điều đó. – radiospiel

+1

Nếu nó giúp, tôi có thể tái tạo hành vi chính xác này trên MBP của tôi. Đã hoàn tất yêu cầu 16359. Không biết nguyên nhân gây ra nó. –

+1

Hmm, suy nghĩ to, con số này đáng ngờ gần với 16384 ... –

Trả lời

5

Tôi sẽ thêm giải pháp ở đây vì mục đích rõ ràng. Giải pháp chính xác để kiểm tra tần số cao với ab trên OS X là thay đổi cài đặt 'net.inet.tcp.msl' từ 15000ms thành 1000ms. Điều này chỉ nên được thực hiện trên các hộp phát triển.

sudo sysctl -w net.inet.tcp.msl=1000 # this is only good for local development 

Câu trả lời này đã được tìm thấy sau khi công việc thám tử tốt thực hiện trong các ý kiến ​​ở đây và xuất phát từ một câu trả lời cho một câu hỏi rất giống nhau, đây là câu trả lời: https://stackoverflow.com/a/6699135/155031

2

Tôi nghĩ mình đã hiểu.

Khi ab tạo kết nối đến máy chủ thử nghiệm của bạn, nó sẽ mở cổng nguồn (ví dụ: 50134) và tạo kết nối đến cổng đích (9294).

Các cổng ab mở cho cổng nguồn được xác định bởi các thiết lập sysctl net.inet.ip.portrange.first và net.inet.ip.portrange.last. Ví dụ, trên máy tính của tôi:

philippotter ~ $ sysctl -a | grep ip.portrange 
net.inet.ip.portrange.lowfirst: 1023 
net.inet.ip.portrange.lowlast: 600 
net.inet.ip.portrange.first: 49152 
net.inet.ip.portrange.last: 65535 
net.inet.ip.portrange.hifirst: 49152 
net.inet.ip.portrange.hilast: 65535 

này có nghĩa là cổng nguồn ab sẽ là trong khoảng 49.152-65.535, mà là một tổng số 16384.

HTTP là một giao thức TCP. Khi một kết nối TCP được đóng lại, nó đi vào TIME_WAIT state, trong khi nó chờ đợi cho bất kỳ gói tin chuyển tiếp còn lại nào để đến đích của họ. Điều này có nghĩa là cổng không thể sử dụng được cho bất kỳ mục đích nào khác cho đến khi hết thời gian chờ.

Vì vậy, đặt tất cả những thứ này lại với nhau, ab sử dụng hết tất cả các cổng nguồn sẵn có rất nhanh; họ đi vào trạng thái TIME_WAIT; chúng không thể được tái sử dụng; ab không thể tạo thêm bất kỳ kết nối nào.

Bạn có thể thấy điều này nếu bạn giết ab khi nó bị treo và chạy lại - nó sẽ không thể tạo ra bất kỳ kết nối nào!

+1

Âm thanh như chúng ta gần hơn cho vấn đề! Nhưng tại sao không phải là đầu ra của 'netstat -p tcp' chứa đầy TIME_WAITS và tại sao các chương trình khác vẫn có thể mở các kết nối? – sunkencity

+0

Bắt đầu một máy chủ mới và chạy ab, có vẻ như yêu cầu cuối cùng bị treo trên 'tcp4 0 0 localhost.52892 localhost.http SYN_SENT' và sau đó một thời gian yêu cầu hết thời gian. (Tôi đã thử chạy máy chủ trên cổng 80 thay vì cổng cao hơn) – sunkencity

+0

@sunkencity hmm, các câu hỏi hay. Có lẽ nó không phải là TIME_WAIT sau khi tất cả. –