อะไร จำกัด จำนวนการเชื่อมต่อสูงสุดบนเซิร์ฟเวอร์ Linux


89

พารามิเตอร์เคอร์เนลหรือการตั้งค่าอื่นใดควบคุมจำนวนสูงสุดของซ็อกเก็ต TCP ที่สามารถเปิดได้บนเซิร์ฟเวอร์ Linux อะไรคือข้อดีของการอนุญาตให้มีการเชื่อมต่อมากขึ้น?

ฉันสังเกตในขณะที่โหลดทดสอบเซิร์ฟเวอร์ Apache ด้วยabว่ามันค่อนข้างง่ายที่จะเปิดการเชื่อมต่อสูงสุดบนเซิร์ฟเวอร์ หากคุณไม่ใช้ตัวเลือก ab's -k ซึ่งอนุญาตให้นำการเชื่อมต่อกลับมาใช้ใหม่และให้ส่งคำขอมากกว่า 10,000 คำขอจากนั้น Apache จะให้บริการคำขอ 11,000 รายการแรกแล้วหยุดพักเป็นเวลา 60 วินาที ดูที่เอาต์พุต netstat แสดงการเชื่อมต่อ 11,000 การเชื่อมต่อในสถานะ TIME_WAIT เห็นได้ชัดว่านี่เป็นเรื่องปกติ การเชื่อมต่อจะถูกเก็บไว้เปิดเริ่มต้นของ 60 วินาทีแม้หลังจากที่ลูกค้าจะทำกับพวกเขาสำหรับเหตุผล TCP ความน่าเชื่อถือ

ดูเหมือนว่านี่จะเป็นวิธีที่ง่ายในการใช้เซิร์ฟเวอร์ DoS และฉันสงสัยว่าการปรับจูนและการป้องกันตามปกติเป็นอย่างไร

นี่คือผลการทดสอบของฉัน:

# 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

นี่คือคำสั่ง netstat ที่ฉันรันในระหว่างการทดสอบ:

 # 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

คำตอบ:


64

ในที่สุดฉันก็พบการตั้งค่าที่ จำกัด จำนวนการเชื่อมต่อnet.ipv4.netfilter.ip_conntrack_maxจริง ๆ: นี่ถูกตั้งไว้ที่ 11,776 และสิ่งที่ฉันตั้งไว้คือจำนวนคำขอที่ฉันสามารถให้บริการในการทดสอบของฉันก่อนที่จะต้องรอtcp_fin_timeoutวินาทีเพื่อให้การเชื่อมต่อมีมากขึ้น conntrackตารางคือสิ่งที่เคอร์เนลใช้ในการติดตามสถานะของการเชื่อมต่อดังนั้นเมื่อมันเต็มเมล็ดจะเริ่มลดลงแพ็คเก็ตและการพิมพ์ในบันทึก:

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

ขั้นตอนต่อไปคือการทำให้เคอร์เนลรีไซเคิลการเชื่อมต่อเหล่านั้นทั้งหมดในTIME_WAITสถานะแทนที่จะปล่อยแพ็กเก็ต ฉันจะได้รับที่จะเกิดขึ้นอย่างใดอย่างหนึ่งโดยการเปิดtcp_tw_recycleหรือเพิ่มขึ้นจะมีขนาดใหญ่กว่าจำนวนของพอร์ตท้องถิ่นทำให้พร้อมสำหรับการเชื่อมต่อโดยip_conntrack_max ip_local_port_rangeฉันเดาว่าเมื่อเคอร์เนลออกจากพอร์ตในเครื่องแล้วมันก็เริ่มรีไซเคิลการเชื่อมต่อ วิธีนี้ใช้การเชื่อมต่อการติดตามหน่วยความจำมากกว่า แต่ดูเหมือนว่าจะเป็นการแก้ปัญหาที่ดีกว่าการเปิดใช้งานtcp_tw_recycleเนื่องจากเอกสารระบุว่าเป็นอันตราย

ด้วยการกำหนดค่านี้ฉันสามารถเรียกใช้ ab ได้ทั้งวันและไม่เคยขาดการเชื่อมต่อ:

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

การtcp_max_orphansตั้งค่าไม่มีผลต่อการทดสอบของฉันและฉันไม่รู้ว่าทำไม ฉันคิดว่ามันจะปิดการเชื่อมต่อในTIME_WAITรัฐเมื่อมี 8192 ของพวกเขา แต่มันไม่ได้ทำเพื่อฉัน


3
เราจะกำหนดค่าพารามิเตอร์เหล่านี้ได้ที่ไหน
Codevalley

2
@Codevalley ที่อาจจะขึ้นอยู่กับระบบ แต่บน Ubuntu Server ของพวกเขาไปใน /etc/sysctl.conf
เบนวิลเลียมส์

24

คุณต้องการดูว่าระบบไฟล์ / proc มีอะไรให้คุณในเรื่องนี้

ในหน้าสุดท้ายนั้นคุณอาจพบสิ่งต่อไปนี้ที่คุณสนใจ:

  • / proc / sys / net / ipv4 / tcp_max_orphansซึ่งควบคุมจำนวนซ็อกเก็ตสูงสุดที่ถือโดยระบบไม่ได้เชื่อมต่อกับบางสิ่ง เพิ่มนี้สามารถใช้มากที่สุดเท่าที่ 64kbyte ของหน่วยความจำที่ไม่ใช่ชนิดถอดเปลี่ยนได้ต่อซ็อกเก็เด็กกำพร้า
  • / proc / sys / net / ipv4 / tcp_orphan_retriesซึ่งควบคุมปริมาณของการลองก่อนที่ซ็อกเก็ตจะถูก orphaned และปิด มีหมายเหตุเฉพาะในหน้านั้นเกี่ยวกับเว็บเซิร์ฟเวอร์ที่คุณสนใจโดยตรง ...

tcp_max_orphans น่าสนใจ แต่ดูเหมือนว่ามันจะไม่ทำงาน เมื่อฉันพยายามที่จะวัดซ็อกเก็ตเด็กกำพร้าในระหว่างการทดสอบของฉันฉันเห็น 11,651 ของพวกเขาในขณะที่ tcp_max_orphans เป็น 8,092 # netstat --inet -p | grep "localhost: www" | sed -e 's / \ + / / g' | ตัด -d '' -f 1-4,6-7 | จัดเรียง | uniq -c 11651 tcp 0 0 localhost: www TIME_WAIT -
Ben Williams

ดู tcp_orphan_retries การตั้งค่า - เป็นความคิดที่ซ็อกเก็ตที่มีการ "คัด" เร็ว ...
เอเวอรี่เพน

ข้อเสนอแนะของ @Jauder Ho + tcp_orphan_retries เสียงเหมือนชนะที่เป็นไปได้สำหรับสถานการณ์ของคุณ
Avery Payne

3

ฉันไม่คิดว่าจะมีการปรับตั้งค่าโดยตรง สิ่งนี้อยู่ภายใต้หมวดหมู่ของการปรับแต่ง TCP / IP หากต้องการค้นหาสิ่งที่คุณสามารถปรับแต่งได้ให้ลอง 'man 7 tcp' sysctl ('man 8 sysctl') ใช้เพื่อตั้งค่าเหล่านี้ 'sysctl -a | grep tcp 'จะแสดงสิ่งที่คุณสามารถปรับได้ แต่ฉันไม่แน่ใจว่ามันจะแสดงทั้งหมดหรือไม่ นอกจากนี้หากมีการเปลี่ยนแปลงซ็อกเก็ต TCP / IP จะเปิดขึ้นเหมือนตัวอธิบายไฟล์ ดังนั้นนี่และส่วนถัดไปในลิงค์นั้นอาจเป็นสิ่งที่คุณกำลังมองหา


2

ลองตั้งค่าต่อไปนี้และตั้งค่า tcp_fin_timeout ด้วย สิ่งนี้ควรปิด TIME_WAIT เร็วขึ้น

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

ระวังที่นี่! ประสบการณ์ที่ยากลำบาก "สิ่งนี้อาจทำให้เฟรมที่ตกหล่นพร้อมโหลดบาลานซ์และ NATs ใช้สำหรับเซิร์ฟเวอร์ที่สื่อสารผ่านเครือข่ายท้องถิ่นของคุณเท่านั้น" - wiki.archlinux.org/index.php/Sysctl
Henk

@Henk ฉันคิดว่ามันtcp_tw_recycleอาจเป็นอันตรายได้ tcp_tw_reuseปลอดภัยกว่าและฉันไม่เห็นเหตุผลใด ๆ ที่จะใช้พร้อมกัน
Vladislav Rastrusny

2

Apache apache (1) ใช้เพื่อกำหนดไว้ล่วงหน้าเพื่อรองรับการเชื่อมต่อพร้อมกัน 250 รายการเท่านั้นหากคุณต้องการมากขึ้นมีไฟล์ส่วนหัวหนึ่งไฟล์ที่จะแก้ไขเพื่อให้เซสชันพร้อมกันมากขึ้น ฉันไม่รู้ว่านี่จะเป็นจริงกับ Apache 2 หรือไม่

นอกจากนี้คุณต้องเพิ่มตัวเลือกเพื่อให้สามารถโหลดตัวอธิบายไฟล์ที่เปิดได้มากขึ้นสำหรับบัญชีที่รัน Apache ซึ่งเป็นสิ่งที่ความคิดเห็นก่อนหน้านี้ไม่สามารถชี้ได้

ให้ความสนใจกับการตั้งค่าของผู้ปฏิบัติงานของคุณและการหมดเวลาเชิงรุกที่คุณมีภายใน Apache ตัวเองจำนวนเซิร์ฟเวอร์ว่างที่คุณใช้งานพร้อมกันและการเพิ่มความเร็วของกระบวนการพิเศษเหล่านี้จะถูกฆ่า


1

คุณสามารถลดเวลาที่ใช้ในสถานะ TIME_WAIT (ตั้งค่า net.ipv4.tcp_fin_timeout) คุณสามารถแทนที่ Apache ด้วย YAWS หรือ nginx หรืออะไรที่คล้ายกัน

โดยทั่วไปแล้วการแลกเปลี่ยนการเชื่อมต่อที่มากขึ้นนั้นเกี่ยวข้องกับการใช้หน่วยความจำและหากคุณมีกระบวนการฟอร์กกิ้งกระบวนการลูกจำนวนมากที่ล้นซีพียูของคุณ


1
tcp_fin_timeout ไม่ได้มีไว้สำหรับการตั้งค่าการหมดอายุ TIME-WAIT ซึ่งไม่สามารถเปลี่ยนแปลงได้นอกการสร้างเคอร์เนลใหม่ แต่สำหรับ FIN ตามที่ชื่อระบุไว้
Alexandr Kurilin

0

จำนวนซ็อกเก็ตที่แน่นอนที่สามารถเปิดได้ในที่อยู่ IP เดียวคือ 2 ^ 16 และกำหนดโดย TCP / UDP ไม่ใช่เคอร์เนล


6
ไม่มันไม่ใช่ คุณสามารถเปิดเพิ่มเติมได้เนื่องจากพอร์ตโลคัลไม่จำเป็นต้องไม่ซ้ำกันตราบใดที่รีโมตแอดเดรสแตกต่างกัน ยิ่งกว่านั้น OP กล่าวต่อเซิร์ฟเวอร์และคุณสามารถมี 1 ที่อยู่ต่อเซิร์ฟเวอร์
MarkR

0

เครื่องมือเซิร์ฟเวอร์เปรียบเทียบ Apache HTTP, AB , ในรุ่น 2.4 มีหมดเวลา -sตัวเลือก ดูเพิ่มเติมAB (Apache Bench) ข้อผิดพลาด: apr_poll: หมดเวลาที่ระบุหมดอายุ (70007) บน Windows

ตัวเลือกนี้แก้ปัญหาของคุณ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.