Điều gì giới hạn số lượng kết nối tối đa trên máy chủ Linux?


89

Tham số kernel hoặc cài đặt nào khác kiểm soát số lượng ổ cắm TCP tối đa có thể mở trên máy chủ Linux? Sự đánh đổi cho phép nhiều kết nối là gì?

Tôi nhận thấy trong khi tải thử nghiệm một máy chủ Apache với ab rằng nó khá dễ dàng để tối đa hóa các kết nối mở trên máy chủ. Nếu bạn rời khỏi tùy chọn -k của ab, cho phép tái sử dụng kết nối và yêu cầu nó gửi hơn 10.000 yêu cầu thì Apache sẽ phục vụ 11.000 yêu cầu đầu tiên hoặc sau đó tạm dừng trong 60 giây. Nhìn vào đầu ra netstat cho thấy 11.000 kết nối ở trạng thái TIME_WAIT. Rõ ràng, điều này là bình thường. Các kết nối được giữ mặc định là 60 giây ngay cả sau khi máy khách được thực hiện với chúng vì lý do độ tin cậy TCP .

Có vẻ như đây sẽ là một cách dễ dàng để DoS một máy chủ và tôi tự hỏi những điều chỉnh và biện pháp phòng ngừa thông thường cho nó là gì.

Đây là đầu ra thử nghiệm của tôi:

# ab -c 5 -n 50000 http://localhost/
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/

Benchmarking localhost (be patient)
Completed 5000 requests
Completed 10000 requests
apr_poll: The timeout specified has expired (70007)
Total of 11655 requests completed

Đây là lệnh netstat tôi chạy trong quá trình kiểm tra:

 # netstat --inet -p | grep "localhost:www" | sed -e 's/ \+/ /g' | cut -d' ' -f 1-4,6-7 | sort | uniq -c 
  11651 tcp 0 0 localhost:www TIME_WAIT -
      1 tcp 0 1 localhost:44423 SYN_SENT 7831/ab
      1 tcp 0 1 localhost:44424 SYN_SENT 7831/ab
      1 tcp 0 1 localhost:44425 SYN_SENT 7831/ab
      1 tcp 0 1 localhost:44426 SYN_SENT 7831/ab
      1 tcp 0 1 localhost:44428 SYN_SENT 7831/ab

Câu trả lời:


64

Cuối cùng tôi đã tìm thấy cài đặt thực sự giới hạn số lượng kết nối : net.ipv4.netfilter.ip_conntrack_max. Điều này đã được đặt thành 11.776 và bất cứ điều gì tôi đặt nó là số lượng yêu cầu tôi có thể phục vụ trong thử nghiệm của mình trước khi phải chờ tcp_fin_timeoutvài giây để có thêm kết nối. Các conntrackbảng là gì hạt nhân sử dụng để theo dõi trạng thái của các kết nối như vậy khi nó đã đầy đủ, hạt nhân bắt đầu bỏ các gói và in ấn này trong nhật ký:

Jun  2 20:39:14 XXXX-XXX kernel: ip_conntrack: table full, dropping packet.

Bước tiếp theo là lấy kernel để tái chế tất cả các kết nối đó trong TIME_WAITtrạng thái thay vì bỏ các gói. Tôi có thể làm điều đó xảy ra bằng cách bật tcp_tw_recyclehoặc tăng ip_conntrack_maxlên lớn hơn số lượng cổng cục bộ có sẵn cho các kết nối bằng ip_local_port_range. Tôi đoán một khi kernel ra khỏi cổng cục bộ thì nó bắt đầu tái chế các kết nối. Điều này sử dụng nhiều kết nối theo dõi bộ nhớ hơn nhưng có vẻ như là giải pháp tốt hơn so với bật tcp_tw_recyclevì các tài liệu ngụ ý rằng điều đó nguy hiểm.

Với cấu hình này, tôi có thể chạy ab cả ngày và không bao giờ hết kết nối:

net.ipv4.netfilter.ip_conntrack_max = 32768
net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_tw_reuse = 0
net.ipv4.tcp_orphan_retries = 1
net.ipv4.tcp_fin_timeout = 25
net.ipv4.tcp_max_orphans = 8192
net.ipv4.ip_local_port_range = 32768    61000

Các tcp_max_orphansthiết lập không có bất kỳ ảnh hưởng đến xét nghiệm của tôi và tôi không biết tại sao. Tôi nghĩ nó sẽ đóng các kết nối ở TIME_WAITtrạng thái một khi có 8192 trong số chúng nhưng nó không làm điều đó cho tôi.


3
Chúng ta cấu hình các thông số này ở đâu?
Codevalley

2
@Codevalley Điều đó có thể phụ thuộc vào hệ thống nhưng trên Ubuntu Server, họ truy cập vào /etc/sysctl.conf
Ben Williams

24

Bạn thực sự muốn xem những gì hệ thống tập tin / Proc cung cấp cho bạn về vấn đề này.

Trên trang cuối cùng đó, bạn có thể tìm thấy những điều sau đây khiến bạn quan tâm:

  • / Proc / sys / net / ipv4 / tcp_max_orphans , điều khiển số lượng ổ cắm tối đa được giữ bởi hệ thống không được gắn vào một cái gì đó. Tăng điều này có thể tiêu thụ tới 64kbyte bộ nhớ không thể tráo đổi trên mỗi ổ cắm mồ côi .
  • / Proc / sys / net / ipv4 / tcp_orphan_retries , điều khiển số lần thử lại trước khi ổ cắm bị mồ côi và đóng. Có một lưu ý cụ thể trên trang đó về các máy chủ web được bạn quan tâm trực tiếp ...

tcp_max_orphans rất thú vị nhưng có vẻ như nó không hoạt động. Khi tôi cố gắng đo các ổ cắm mồ côi trong quá trình thử nghiệm của mình, tôi thấy 11.651 trong số chúng trong khi tcp_max_orphans là 8.092. # netstat --inet -p | grep "localhost: www" | sed -e 's / \ + / / g' | cắt -d '' -f 1-4,6-7 | sắp xếp | uniq -c 11651 tcp 0 0 localhost: www TIME_WAIT -
Ben Williams

Nhìn vào cài đặt tcp_orphan_retries - ý tưởng là, các ổ cắm được "loại bỏ" nhanh hơn ...
Avery Payne

Gợi ý của @Jauder Ho + tcp_orphan_retries nghe có vẻ như là chiến thắng tiềm năng cho tình huống của bạn.
Avery Payne

3

Tôi không nghĩ rằng có thể điều chỉnh để đặt trực tiếp. Điều này thuộc danh mục điều chỉnh TCP / IP. Để tìm hiểu những gì bạn có thể điều chỉnh, hãy thử 'man 7 tcp'. Sysctl ('man 8 sysctl') được sử dụng để đặt những thứ này. 'sysctl -a | grep tcp 'sẽ cho bạn thấy hầu hết những gì bạn có thể điều chỉnh, nhưng tôi không chắc liệu nó có hiển thị tất cả chúng hay không. Ngoài ra, trừ khi điều này thay đổi, ổ cắm TCP / IP mở ra trông giống như mô tả tệp. Vì vậy, phần này và phần tiếp theo trong liên kết đó có thể là những gì bạn đang tìm kiếm.


2

Hãy thử thiết lập các mục sau cũng như cài đặt tcp_fin_timeout. Điều này sẽ đóng TIME_WAIT nhanh hơn.

net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1

Cẩn thận đây! Trải nghiệm một cách khó khăn. "Điều này có thể gây ra các khung hình bị mất với cân bằng tải và NAT, chỉ sử dụng điều này cho một máy chủ chỉ giao tiếp qua mạng cục bộ của bạn." - wiki.archlinux.org/index.php/Sysctl
Henk

@Henk Tôi đoán nó tcp_tw_recyclecó khả năng nguy hiểm. tcp_tw_reusean toàn hơn và tôi không thấy bất kỳ lý do nào để sử dụng chúng đồng thời.
Vladislav Rastrusny 17/03/2016

2

Apache stock (1) được sử dụng để được xác định trước chỉ hỗ trợ 250 kết nối đồng thời - nếu bạn muốn nhiều hơn, có một tệp tiêu đề cần sửa đổi để cho phép nhiều phiên đồng thời hơn. Tôi không biết điều này có còn đúng với Apache 2 không.

Ngoài ra, bạn cần thêm một tùy chọn để cho phép tải nhiều mô tả tệp mở hơn cho tài khoản chạy Apache - điều mà các bình luận trước đó không thể chỉ ra.

Hãy chú ý đến các cài đặt worker của bạn và loại thời gian chờ cố định nào bạn có trong chính Apache, có bao nhiêu máy chủ dự phòng bạn đang chạy cùng một lúc và các quá trình bổ sung này sẽ bị giết nhanh như thế nào.


1

Bạn có thể giảm thời gian ở trạng thái TIME_WAIT (Đặt net.ipv4.tcp_fin_timeout). Bạn có thể thay thế Apache bằng YAWS hoặc nginx hoặc một cái gì đó tương tự.

Sự đánh đổi của nhiều kết nối thường liên quan đến việc sử dụng bộ nhớ và nếu bạn có một quá trình giả mạo, rất nhiều tiến trình con sẽ tràn vào CPU của bạn.


1
tcp_fin_timeout không phải để thiết lập hết hạn TIME-WAIT, không thể thay đổi bên ngoài việc xây dựng lại kernel, nhưng đối với FIN, như tên gọi.
Alexandr Kurilin

0

Số lượng ổ cắm tuyệt đối có thể mở trên một địa chỉ IP là 2 ^ 16 và được xác định bởi TCP / UDP, không phải kernel.


6
Không, không. Bạn có thể mở thêm, vì cổng cục bộ không cần phải là duy nhất miễn là các địa chỉ từ xa khác nhau. Hơn nữa, OP cho biết trên mỗi máy chủ và bạn có thể có> 1 địa chỉ trên mỗi máy chủ.
MarkR

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.