กระบวนการขวดเดียวได้รับคำขอพร้อมกันจำนวนเท่าใด


138

ฉันกำลังสร้างแอพด้วย Flask แต่ฉันไม่รู้เกี่ยวกับ WSGI มากนักและเป็นฐาน HTTP, Werkzeug เมื่อฉันเริ่มแสดงแอปพลิเคชัน Flask ด้วย gunicorn และกระบวนการของผู้ปฏิบัติงาน 4 รายหมายความว่าฉันสามารถจัดการคำขอที่เกิดขึ้นพร้อมกัน 4 คำขอได้หรือไม่

ฉันหมายถึงคำขอที่เกิดขึ้นพร้อมกันไม่ใช่คำขอต่อวินาทีหรืออย่างอื่น

คำตอบ:


183

เมื่อรันเซิร์ฟเวอร์การพัฒนา - ซึ่งเป็นสิ่งที่คุณได้รับจากการรันapp.run()คุณจะได้รับกระบวนการซิงโครนัสเดียวซึ่งหมายความว่ามีการประมวลผลคำขอครั้งละไม่เกิน 1 ครั้ง

ด้วยการผสาน Gunicorn ไว้ข้างหน้ามันในการกำหนดค่าเริ่มต้นและเพียงเพิ่มจำนวน--workersสิ่งที่คุณได้รับก็คือกระบวนการจำนวนมาก (จัดการโดย Gunicorn) ที่แต่ละคนทำงานเหมือนapp.run()เซิร์ฟเวอร์การพัฒนา 4 คน == 4 คำขอพร้อมกัน นี่เป็นเพราะ Gunicorn ใช้syncประเภทของผู้ปฏิบัติงานรวมตามค่าเริ่มต้น

มันเป็นสิ่งสำคัญที่จะต้องทราบว่า Gunicorn ยังรวมถึงคนงานแบบอะซิงโครนัสเช่นกันeventletและgevent(และเช่นtornadoกัน ด้วยการระบุหนึ่งในพนักงาน async เหล่านี้ด้วยการ--worker-classตั้งค่าสถานะสิ่งที่คุณได้รับคือ Gunicorn จัดการกระบวนการ async จำนวนหนึ่งซึ่งแต่ละกระบวนการจัดการการทำงานพร้อมกันของตนเอง กระบวนการเหล่านี้ไม่ได้ใช้เธรด แต่เป็น Coroutines แทน โดยทั่วไปภายในแต่ละกระบวนการยังมีเพียง 1 สิ่งเท่านั้นที่สามารถเกิดขึ้นได้ในแต่ละครั้ง (1 เธรด) แต่วัตถุสามารถ 'หยุดชั่วคราว' เมื่อพวกเขารอกระบวนการภายนอกให้เสร็จ (คิดว่าคิวรีฐานข้อมูลหรือรออยู่บนเครือข่าย I / O)

ซึ่งหมายความว่าหากคุณกำลังใช้หนึ่งในพนักงาน async ของ Gunicorn คนงานแต่ละคนสามารถจัดการมากกว่าคำขอเดียวในแต่ละครั้ง จำนวนพนักงานที่ดีที่สุดขึ้นอยู่กับลักษณะของแอปสภาพแวดล้อมฮาร์ดแวร์ที่ทำงาน ฯลฯ รายละเอียดเพิ่มเติมสามารถดูได้ที่หน้าการออกแบบของGunicornและหมายเหตุเกี่ยวกับวิธีการทำงานของ geventในหน้าอินโทร


4
Gunicorn ขณะนี้สนับสนุนหัวข้อ "ของจริง" ตั้งแต่รุ่น 19 ดูนี้และนี้
Filipe Correia

2
มีวิธีการติดตามว่าทรัพยากรใดได้รับการแบ่งปัน (และวิธี) และแยกกันอย่างสมบูรณ์ระหว่างเธรด / กระบวนการ ตัวอย่างเช่นฉันจะจัดการสถานการณ์ที่ฉันต้องการแบ่งปันโครงสร้างข้อมูลขนาดใหญ่ระหว่างกระบวนการต่าง ๆ ที่จัดการโดย Gunicorn และใช้ในตัวจัดการขวดได้อย่างไร
โยฮันน์เพทรักร์

สิ่งที่คุณถาม @Johsm เป็นเหมือนการถามวิธีการแบ่งปันข้อมูลระหว่างกระบวนการต่าง ๆ ภายในระบบปฏิบัติการ คำตอบที่สามารถตอบคำถามของคุณคุณต้องใช้ที่เก็บข้อมูลภายนอกเนื่องจากกระบวนการไม่แชร์หน่วยความจำกับกระบวนการอื่น Gunicorn อยู่ที่นี่เพียงเพื่อใช้สถาปัตยกรรม CPU หลายตัวประมวลผล แต่ไม่สามารถจัดการกับปัญหาเหล่านั้นได้
adkl

แล้วอีฟล่ะ สิ่งนี้มีไว้สำหรับอีฟด้วยหรือไม่?
Eswar

2
เซิร์ฟเวอร์การพัฒนาขวดใช้เธรดเป็นค่าเริ่มต้นตั้งแต่ v1.0 ( github.com/pallets/flask/pull/2529 )
hychou

40

ขณะนี้มีวิธีแก้ปัญหาที่ง่ายกว่าวิธีที่ได้จัดเตรียมไว้ให้แล้ว เมื่อเรียกใช้แอปพลิเคชันของคุณคุณต้องผ่านthreaded=Trueพารามิเตอร์ไปยังการapp.run()โทรเช่น:

app.run(host="your.host", port=4321, threaded=True)

ตัวเลือกอื่นตามที่เราเห็นในเอกสาร werkzeugคือการใช้processesพารามิเตอร์ซึ่งรับตัวเลข> 1 ระบุจำนวนสูงสุดของกระบวนการที่เกิดขึ้นพร้อมกันในการจัดการ:

  • เธรด - กระบวนการควรจัดการแต่ละคำร้องขอในเธรดแยกกันหรือไม่?
  • กระบวนการ - ถ้ามากกว่า 1 ให้จัดการแต่ละคำขอในกระบวนการใหม่จนถึงจำนวนสูงสุดของกระบวนการที่เกิดขึ้นพร้อมกันนี้

สิ่งที่ต้องการ:

app.run(host="your.host", port=4321, processes=3) #up to 3 processes

ข้อมูลเพิ่มเติมเกี่ยวกับrun()วิธีการที่นี่และบล็อกโพสต์ที่นำฉันไปหาวิธีแก้ปัญหาและการอ้างอิง API


หมายเหตุ:ใน Flask docs เกี่ยวกับrun()วิธีการที่ระบุว่าการใช้งานในสภาพแวดล้อมการผลิตนั้นไม่ได้รับการสนับสนุนเพราะ ( อ้างถึง ): "ในขณะที่มีน้ำหนักเบาและใช้งานง่ายเซิร์ฟเวอร์ในตัวของ Flask ไม่เหมาะสำหรับการผลิต ."

อย่างไรก็ตามพวกเขาจะชี้ไปที่หน้าตัวเลือกการปรับใช้ของพวกเขาสำหรับวิธีที่แนะนำให้ทำเมื่อไปผลิต


5
ขอบคุณสำหรับข้อมูล. สิ่งสำคัญคือให้สังเกตว่า doc สำหรับการทำงานระบุว่าไม่ควรใช้ในสภาพแวดล้อมการผลิตที่ระบุว่าไม่ตรงตามข้อกำหนดด้านความปลอดภัยหรือประสิทธิภาพ
Coffee_fan

1
@Coffee_fan คุณพูดถูก แม้กระทั่งบน 1.1.x ล่าสุดพวกเขาไม่สนับสนุนสิ่งนั้นและแนะนำให้ตรวจสอบหน้าตัวเลือกการปรับใช้เมื่อไปผลิต รวมถึงการสังเกตที่มีค่าของคุณในคำตอบ :)
DarkCygnus

33

ขวดจะดำเนินการหนึ่งคำขอต่อเธรดในเวลาเดียวกัน หากคุณมี 2 กระบวนการที่มี 4 เธรดแต่ละรายการนั่นคือ 8 คำขอพร้อมกัน

กระติกน้ำจะไม่วางไข่หรือจัดการเธรดหรือกระบวนการ นั่นเป็นความรับผิดชอบของเกตเวย์ WSGI (เช่น gunicorn)


9

ไม่ - คุณสามารถจัดการได้มากกว่านั้นอย่างแน่นอน

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

กล่าวคือ CPU สามารถดำเนินการชุดคำสั่งที่ จำกัด ได้อย่างมากเท่านั้นและไม่สามารถดำเนินการคำสั่งมากกว่าหนึ่งคำสั่งต่อนาฬิกาติ๊ก (คำแนะนำจำนวนมากใช้เวลามากกว่า 1 ขีด)

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

"สิ่งต่าง ๆ " เหล่านี้สามารถเป็นกระบวนการซึ่งเป็นหน่วยของรหัสที่ทำงานพร้อมกันในแง่ที่ว่าแต่ละกระบวนการคิดว่าการทำงานในโลกของตัวเองกับหน่วยความจำที่ไม่ได้ใช้ร่วมกัน

อีกตัวอย่างคือเธรดซึ่งเป็นหน่วยของโค้ดภายในกระบวนการที่อนุญาตการทำงานพร้อมกันเช่นกัน

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

ขีด จำกัด คำขอจริงขึ้นอยู่กับเซิร์ฟเวอร์ HTTP ที่เลือก, I / O, OS, ฮาร์ดแวร์, การเชื่อมต่อเครือข่ายเป็นต้น

โชคดี!

* คำสั่งเป็นคำสั่งพื้นฐานที่ CPU สามารถใช้งานได้ ตัวอย่าง - เพิ่มตัวเลขสองตัวกระโดดจากคำสั่งหนึ่งไปยังอีกคำสั่งหนึ่ง


1
มันคือ gunicorn วางไข่เธรดหรือขวด? ฉันไม่พบหลักฐานที่สนับสนุนความเป็นไปได้อย่างใดอย่างหนึ่ง
jd

1
แน่นอนฉันเข้าใจว่าเกี่ยวกับกระบวนการ แต่คำตอบบอกว่ามีเธรดจำนวนมากเกิดขึ้นตามความจำเป็น นั่นคือสิ่งที่ฉันต้องการได้รับการยืนยัน
jd

4
"ลึกลงไปสมมติว่าคุณกำลังใช้งานเครื่องหลักเพียงตัวเดียวซีพียูจะรันคำสั่งเพียงครั้งเดียว * ในเวลาเดียว"นี่ไม่ถูกต้องสำหรับเครื่องที่ทันสมัย ซีพียูที่ทันสมัยส่วนใหญ่นั้นมีpipelinedและsuperscalarซึ่งแม้แต่แกนเดียวก็มีหน่วยประมวลผลหลายตัวและตัวถอดรหัสคำสั่งที่แปลง "รหัสเครื่อง" ที่เห็นจากด้านซอฟต์แวร์ให้เป็นหน่วยประมวลผลกลางฮาร์ดแวร์จริงที่ส่งไปยังหน่วยปฏิบัติการแต่ละตัว
Michael Geary

1
ในการชี้แจงให้ชัดเจนย้อนกลับไปในวันนั้นซีพียูได้ดำเนินการตามคำสั่งเชิงตัวเลขโดยตรงในปฏิบัติการ - รหัสเครื่อง การอ้างอิงซีพียูทุกตัวมีแผนภูมิกำหนดเวลาการสอนที่แสดงจำนวนรอบของแต่ละคำสั่งรวมถึงการอ้างอิงหน่วยความจำใด ๆ ดังนั้นคุณสามารถเพิ่มเวลาเพื่อให้ทราบว่าจะใช้เวลานานเท่าใด ซีพียูสมัยใหม่นั้นไม่เหมือนกันเลย ข้อยกเว้นที่น่าสนใจอย่างหนึ่งคือBeagleBoneซึ่งมีโปรเซสเซอร์ superscalar ARM ที่ทันสมัยและโปรเซสเซอร์"PRU" สมัยเก่าสองตัวพร้อมกำหนดเวลาการสอนที่แน่นอน
Michael Geary

1
และเพื่อชี้แจงว่าเมื่อฉันพูดว่า "ทันสมัย" ฉันใช้มันเป็นชวเลขแบบหลวม ๆ สำหรับโปรเซสเซอร์เช่นชิป ARM / Intel / AMD - pipelined, superscalar ฯลฯ แน่นอนว่ายังมีโปรเซสเซอร์สมัยใหม่ที่ทำงานแบบเก่าด้วยเวลาที่แน่นอน ต่อคำแนะนำเช่น BeagleBone PRUs ที่ฉันพูดถึงและไมโครคอนโทรลเลอร์ใหม่ ๆ (และตอนนี้กลับสู่ Gunicorn!)
Michael Geary
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.