ค่าที่เหมาะสมที่สุดสำหรับ Nginx worker_connections


25

Nginx worker_connections"ตั้งค่าจำนวนสูงสุดของการเชื่อมต่อพร้อมกันที่สามารถเปิดได้โดยกระบวนการของผู้ปฏิบัติงานจำนวนนี้รวมถึงการเชื่อมต่อทั้งหมด (เช่นการเชื่อมต่อกับเซิร์ฟเวอร์พร็อกซีและอื่น ๆ ) ไม่เพียง แต่การเชื่อมต่อกับไคลเอนต์ ต้องไม่เกินขีด จำกัด ปัจจุบันของจำนวนไฟล์ที่เปิดสูงสุด " ฉันมีข้อสงสัยเล็กน้อยเกี่ยวกับสิ่งนี้:

  1. สิ่งที่ควรค่าที่ดีที่สุดหรือแนะนำสำหรับนี้
  2. ข้อเสียของการใช้การเชื่อมต่อของผู้ปฏิบัติงานจำนวนมากคืออะไร

+1 คำถามที่ดี!
cnst

คำตอบ:


31

เรามาดูวิธีปฏิบัติ

ข้อ จำกัด เหล่านี้คือสิ่งที่ฮาร์ดโค้ดและออกแบบมาในศตวรรษที่ผ่านมาเมื่อฮาร์ดแวร์ช้าและมีราคาแพง ขณะนี้เราอยู่ในปี 2559 เครื่องปิ้งขนมปังวอลมาร์ตเฉลี่ยสามารถดำเนินการตามคำขอมากกว่าค่าเริ่มต้น

การตั้งค่าเริ่มต้นเป็นอันตรายจริง ๆ การมีผู้ใช้หลายร้อยคนบนเว็บไซต์ไม่มีอะไรน่าประทับใจ

worker_process

การตั้งค่าที่เกี่ยวข้องลองอธิบายในขณะที่เราอยู่ในหัวข้อ

nginx as load balancer:

  • 1 ผู้ปฏิบัติงานสำหรับการโหลดบาลานซ์ HTTP
  • 1 คนงานต่อหนึ่งคอร์สำหรับ HTTPS load balancing

nginx เป็นเว็บเซิร์ฟเวอร์:

อันนี้ช่างยุ่งยาก

แอปพลิเคชั่น / กรอบ / มิดเดิลแวร์บางตัว (เช่น php-fpm) ทำงานนอก nginx ในกรณีนั้นผู้ปฏิบัติงาน 1 nginx ก็เพียงพอแล้วเพราะโดยปกติแล้วจะเป็นแอปพลิเคชันภายนอกที่ใช้การประมวลผลจำนวนมากและกินทรัพยากร

นอกจากนี้บางแอ็พพลิเคชัน / เฟรมเวิร์ก / มิดเดิลแวร์สามารถประมวลผลคำร้องขอได้ครั้งละหนึ่งรายการเท่านั้น

โดยทั่วไปแล้วผู้ปฏิบัติงาน 1 คนเป็นเดิมพันที่ปลอดภัยเสมอ

ไม่เช่นนั้นคุณอาจนำคนงานหนึ่งคนมาทำงานต่อคอร์ถ้าคุณรู้ว่าคุณกำลังทำอะไรอยู่ ฉันคิดว่าเส้นทางนั้นเป็นการเพิ่มประสิทธิภาพและแนะนำการเปรียบเทียบและทดสอบที่เหมาะสม

worker_connections

worker_process * worker_connectionsจำนวนของการเชื่อมต่อเป็น ครึ่งหนึ่งในโหมดโหลดบาลานเซอร์

ตอนนี้เรามาถึงส่วนเครื่องปิ้งขนมปัง มีข้อ จำกัด ของระบบที่ประเมินค่าต่ำมากอย่างจริงจัง:

  • ulimits คือ 1k max open files ต่อกระบวนการบน linux (1k soft, 4k hard ในบาง distro)
  • ข้อ จำกัด ของ systemd นั้นเกี่ยวกับ ulimits
  • ค่าเริ่มต้น nginx คือ 512 การเชื่อมต่อต่อผู้ปฏิบัติงาน
  • อาจมีมากกว่านี้: SELinux, sysctl, supervisord (แต่ละรุ่น distro + แตกต่างกันเล็กน้อย)

1k worker_connections

ค่าเริ่มต้นที่ปลอดภัยคือการใส่ 1k ทุกที่

สูงพอที่จะเป็นได้มากกว่าเว็บไซต์ส่วนใหญ่ที่ไม่รู้จักและอยู่ภายใน มันต่ำพอที่จะไม่กระทบกับขีด จำกัด ของระบบอื่น ๆ

10k worker_connections

เป็นเรื่องปกติที่จะมีลูกค้าหลายพันรายโดยเฉพาะเว็บไซต์สาธารณะ ฉันหยุดนับจำนวนเว็บไซต์ที่ฉันเห็นลงไปเพราะมีค่าเริ่มต้นต่ำ

ขั้นต่ำที่ยอมรับได้สำหรับการผลิตคือ 10k ขีด จำกัด ของระบบที่เกี่ยวข้องจะต้องเพิ่มขึ้นเพื่ออนุญาต

ไม่มีสิ่งเช่นขีด จำกัด สูงเกินไป (การ จำกัด เพียงไม่มีผลหากไม่มีผู้ใช้) อย่างไรก็ตามข้อ จำกัด ต่ำเกินไปนั้นเป็นเรื่องจริงมากที่ส่งผลให้ผู้ใช้ที่ถูกปฏิเสธและไซต์ที่ไม่ทำงาน

มากกว่า 10k

10k นั้นดีและง่าย

เราสามารถตั้งค่าขีด จำกัด 1000kk โดยพลการ (เป็นเพียงขีด จำกัด หลังจากทั้งหมด) แต่นั่นไม่สมเหตุสมผลนักเราไม่เคยได้รับปริมาณข้อมูลนั้นและไม่สามารถรับได้

มาติด 10k กันเถอะ บริการที่เพิ่มมากขึ้น (และสามารถทำได้จริง ๆ ) จะต้องมีการปรับแต่งพิเศษและการเปรียบเทียบ

สถานการณ์พิเศษ: การใช้งานขั้นสูง

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

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


ฉันชอบคำตอบ แต่เพื่อคาดเดาการศึกษาอย่างแท้จริงว่าควรตั้งค่าที่สูงเพียงใดดูเหมือนว่าเราต้องรู้ว่าการเชื่อมต่อ RAM หนึ่งครั้งใช้เวลาเท่าใด (เช่นบันทึกไฟล์สแตติกปกติด้วยsendfile) เพื่อให้เราสามารถคูณ คำนวณว่าจำเป็นต้องใช้ RAM เท่าใดเพื่อรักษาจำนวนที่กำหนดworker_connectionsไว้
nh2

1
คุณสามารถทำได้มากถึง 10k โดยไม่ต้องจูนมากเกินไป บัฟเฟอร์การเชื่อมต่อถูกตั้งค่าในการsysctlตั้งค่า
user5994461

10

ulimit -a จะบอกให้คุณทราบว่าไฟล์ที่เปิดอยู่ของคุณอนุญาตให้กระบวนการใช้งานได้กี่ไฟล์

นอกจากนี้net.ipv4.ip_local_port_rangeตั้งค่าช่วงทั้งหมดของซ็อกเก็ตเพื่อเปิดใช้งานต่อ IP

ดังนั้นคุณworker_connectionsจะต้องไม่เกินกว่านั้นมิฉะนั้นการเชื่อมต่อลูกค้าของคุณจะคิวจนกว่าnet.core.netdev_max_backlog - ขนาดรวมของคิว TCP

โปรดทราบว่าหากคุณใช้ nginx เป็น reverse-proxy นั่นจะใช้ซ็อกเก็ตสองตัวต่อการเชื่อมต่อ คุณอาจต้องการเล่นนิดหน่อยด้วยnet.ipv4.tcp_fin_timeoutและหมดเวลาที่เกี่ยวข้องกับเคอร์เนล tcp เพื่อลองเปลี่ยนสถานะของซ็อกเก็ตอย่างรวดเร็ว สิ่งหนึ่งที่ควรทราบก็คือแต่ละซ็อกเก็ตจัดสรรหน่วยความจำของสแต็คหน่วยความจำ TCP คุณยังสามารถตั้งค่าขีด จำกัด บางส่วนของสแต็คหน่วยความจำ TCP โดยใช้sysctlคุณสามารถเพิ่มแรงกดดันใน RAM ตราบเท่าที่คุณมี CPU และตัวจัดการไฟล์เพียงพอ

FYI มีความเป็นไปได้ที่จะได้รับทรัพยากรการประมวลผลที่เพียงพอโดยมีเซิร์ฟเวอร์หนึ่งตัวที่มีขนาด 32GB RAM และอินเทอร์เฟซเครือข่ายเสมือนบางส่วนเพื่อจัดการการเชื่อมต่อพร้อมกัน 1 มม. พร้อมการปรับแต่งเคอร์เนลโดยใช้ sysctl ในระหว่างการทดสอบของฉันเมื่อจัดการกับมากกว่า 1 มม. และส่งเพย์โหลดประมาณ 700Bytes เซิร์ฟเวอร์ใช้เวลาประมาณ 10 วินาทีเพื่ออัปเดตไคลเอนต์พร้อมกันประมาณ 1.2 มม. ถัดไปคือการเพิ่มแบนด์วิดท์ของเครือข่ายโดยเชื่อมโยง NIC พิเศษและการเชื่อมโยงเสมือน nics เป็นไปได้ที่จะบรรลุผลหลอกใกล้กับการสื่อสารแบบเรียลไทม์กับไคลเอนต์มากกว่า 1.2 มม. กำหนดน้ำหนักบรรทุกแบนด์วิดท์และเวลาที่เหมาะสมในการอัพเดทลูกค้าทั้งหมด

มีความสุขในการจูน!


โปรดแก้ไขคำสั่งเพื่อ ulimit ไม่ใช่ ulimits
Ali.MD

หมายเหตุnet.ipv4.ip_local_port_rangeเกี่ยวข้องเฉพาะสำหรับการเชื่อมต่อขาออกไม่ใช่สำหรับการเชื่อมต่อขาเข้า (ตามปกติกับ nginx บนเช่นพอร์ต 80 และ 443) ดูที่นี่
nh2

@ nh2 แต่ถ้าใช้ nginx เป็น reverse proxy จะมีซ็อกเก็ตเปิดอย่างน้อย 2 ซ็อกเก็ตต่อการเชื่อมต่อไคลเอนต์แล้วมันจะสำคัญว่าโลคอลพอร์ตจำนวนเท่าใดที่เคอร์เนลสามารถอนุญาตให้ซ็อกเก็ตเชื่อมได้
Marcel

ใช่ที่ถูกต้อง.
nh2

0

ขนาดที่เหมาะสมสามารถค้นพบได้ผ่านการทดสอบเนื่องจากเป็นตัวแปรที่ขึ้นอยู่กับประเภทของการรับส่งข้อมูลที่ Nginx จัดการอยู่

ในทางทฤษฎี nginx สามารถจัดการได้: max clients = worker_processes * worker_connections (* = ทวีคูณ) และ worker_processes = จำนวนโปรเซสเซอร์

ในการค้นหาโปรเซสเซอร์ให้ใช้: grep processor / proc / cpuinfo | ห้องสุขา -l


ที่จริงแล้วมี reverse proxy: max_clients = (worker_processes * worker_connections) / (X * 2) โดยที่ X เป็นการเชื่อมต่อพร้อมกันจำนวนมากที่ไคลเอ็นต์เหล่านี้ทำกับคุณ นอกจากนี้โครงสร้างการเชื่อมต่อจะใช้สำหรับซ็อกเก็ตฟังซ็อกเก็ตการควบคุมภายในระหว่างกระบวนการ nginx และสำหรับการเชื่อมต่ออัปสตรีม ดังนั้นไคลเอนต์สูงสุดนี้ = worker_processes * worker_connections จะไม่ทำงานเนื่องจากเราไม่ทราบว่ามีการใช้การเชื่อมต่อจำนวนมากในซ็อกเก็ตการควบคุมภายใน
Aarti

0

การตั้งค่าขีด จำกัด ล่างอาจมีประโยชน์เมื่อคุณอาจถูก จำกัด ทรัพยากร ตัวอย่างเช่นการเชื่อมต่อแบบ keep-alive (ไม่เพียง แต่กับไคลเอนต์เท่านั้น แต่ใช้กับเซิร์ฟเวอร์ upstreamเช่นกัน) กำลังสูญเสียทรัพยากรของคุณอย่างมีประสิทธิภาพ (แม้ว่า nginx จะมีประสิทธิภาพมากซึ่งเป็น) และไม่จำเป็นสำหรับ การดำเนินการที่ถูกต้องของเซิร์ฟเวอร์วัตถุประสงค์ทั่วไปหมายความว่าสามารถทิ้งอย่างปลอดภัยเพื่อให้ทรัพยากรเพิ่มเติมพร้อมใช้งานสำหรับส่วนที่เหลือของการดำเนินการ

การมีขีด จำกัด ทรัพยากรต่ำกว่าจะบ่งบอกถึง nginx ว่าคุณอาจมีทรัพยากรทางกายภาพต่ำและควรจัดสรรทรัพยากรที่มีอยู่ให้กับการเชื่อมต่อใหม่แทนที่จะให้บริการการเชื่อมต่อแบบ keep-alive ที่ไม่ทำงานด้วยค่าใช้จ่ายของการเชื่อมต่อใหม่ ตอบสนองความต้องการเร่งด่วนมากขึ้น

ค่าที่แนะนำคืออะไร มันเป็นค่าเริ่มต้น

ค่าเริ่มต้นจะได้รับการบันทึกไว้ในเอกสารทั้งหมด:

เริ่มต้น: worker_connections 512;

และสามารถยืนยันได้ในระดับซอร์สโค้ดevent/ngx_event.cด้วยเช่นกัน

13 # define DEFAULT_CONNECTIONS 512


0

คำตอบของ Marcel จำเป็นต้องได้รับการสนับสนุนจริงๆ! หากมีการตั้งค่า ulimits เป็นค่าเริ่มต้นประมาณ 1k, max_connections ควรตั้งค่าไว้ที่ค่าเดียวกันมิฉะนั้นจะไม่มีประโยชน์ในการตั้งค่า max_connections เป็น 10k

คุณจะได้รับคำขอที่ถูกจัดคิวและซ็อกเก็ตปิดใน nginx หาก "ผู้ปฏิบัติงานของคุณไม่สามารถมากกว่าสิ่งใด ๆ หรือการเชื่อมต่อไคลเอนต์ของคุณจะเข้าคิวจนกว่า net.core.netdev_max_backlog

กระบวนการเดียวสามารถเปิดได้ตามการเชื่อมต่อตามที่ ulimits อนุญาต num_workers * max_connections เป็นสูตร แต่อยู่นอกการเชื่อมต่อ loadbalancer / proxy max และ ulimits จำเป็นต้องนำมาพิจารณาสำหรับค่าที่สมเหตุสมผล การตั้งค่า max_connection เป็นค่าที่สูงมากอาจย้อนกลับมาเป็นแผลจะเป็นปัจจัย จำกัด


1
นั่นเป็นความจริงที่ผิด ขีด จำกัด ซอฟต์บนเดสก์ท็อปลินุกซ์คือ 1k แต่มันไม่ได้ป้องกันกระบวนการจากการใช้มากไปกว่านั้นหากพวกเขาร้องขอถึงขีด จำกัด สูงสุด (32k หรือมากกว่า) nginx จะเพิ่ม ulimit โดยอัตโนมัติหากmax_connectionsสูงกว่าขีด จำกัด ซอฟต์เริ่มต้น
user5994461
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.