ทำไมฉันถึงต้องการ Nginx และบางอย่างเช่น Gunicorn


219

ฉันกำลังมองหาคำตอบที่ง่ายเกินไปสำหรับคำถามต่อไปนี้ ฉันพยายามสร้างความเข้าใจพื้นฐานว่า Nginx ทำงานร่วมกับบางสิ่งเช่น Gunicorn ได้อย่างไร

ฉันต้องมีทั้ง Nginx และบางอย่างเช่น Gunicorn เพื่อปรับใช้แอพ Django บน Nginx หรือไม่?

ถ้าเป็นเช่นนั้นสิ่งที่จัดการกับคำขอ HTTP จริง ๆ ?

ps ฉันไม่ต้องการใช้ Apache และ mod_wsgi!


Apache และ mod_wsgi เป็นวิธีที่ง่ายที่สุดในการติดตั้งบริดจ์ระหว่างแอปพลิเคชัน django ของคุณและการร้องขอ HTTP ที่มีความสามารถมากในสภาพแวดล้อมการผลิต สำหรับนักพัฒนาหลายคนนี่หมายความว่า 'Apache ดีกว่า nginx' หากพวกเขาทำ แต่รู้ แต่ในขณะที่ 'betamax ดีกว่า VHS' อนิจจากฎ Dogma
MagicLAMP

คำตอบ:


314

ลดความซับซ้อนลงมากเกินไป: คุณต้องการสิ่งที่ดำเนินการ Python แต่ Python ไม่ได้ดีที่สุดในการจัดการคำขอทุกประเภท

[ข้อจำกัดความรับผิดชอบ: ฉันเป็นนักพัฒนาของ Gunicorn]

ลดความซับซ้อนลง: ไม่ว่าคุณจะใช้แอพเซิร์ฟเวอร์ใด (Gunicorn, mod_wsgi, mod_uwsgi, cherrypy) การปรับใช้ที่ไม่ยุ่งยากใด ๆ จะมีสิ่งที่อัปสตรีมที่จะจัดการกับคำขอที่แอป Django ของคุณไม่ควรจัดการ ตัวอย่างเล็กน้อยของคำขอดังกล่าวกำลังแสดงสินทรัพย์แบบคงที่ (images / css / js)

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

การพูดในอดีตแต่ละชั้นเหล่านี้จะถูกโฮสต์บนเครื่องที่แยกต่างหาก (และมีแนวโน้มว่าจะมีหลายเครื่องในสองชั้นแรกเช่น: 5 เว็บเซิร์ฟเวอร์ส่งคำขอไปยังเซิร์ฟเวอร์แอปสองตัวซึ่งจะสอบถามฐานข้อมูลเดียว)

ในยุคปัจจุบันเรามีรูปทรงและขนาดที่แตกต่างกัน ไม่ใช่ทุกโครงการในวันหยุดสุดสัปดาห์หรือไซต์ธุรกิจขนาดเล็กที่ต้องการแรงม้าจำนวนมากและจะทำงานได้อย่างมีความสุขบนกล่องเดียว สิ่งนี้ทำให้เกิดรายการใหม่ในอาร์เรย์ของโซลูชันการโฮสต์ โซลูชันบางอย่างจะแต่งงานกับเซิร์ฟเวอร์แอปไปยังเว็บเซิร์ฟเวอร์ (Apache httpd + mod_wsgi, Nginx + mod_uwsgi, ฯลฯ ) และไม่ใช่เรื่องแปลกอะไรเลยที่จะโฮสต์ฐานข้อมูลบนเครื่องเดียวกันกับหนึ่งในเว็บ / แอพเซิร์ฟเวอร์รวมกันเหล่านี้

ตอนนี้ในกรณีของ Gunicorn เราได้ทำการตัดสินใจโดยเฉพาะ (คัดลอกจาก Ruby Unicorn) เพื่อแยกสิ่งต่าง ๆ ออกจาก Nginx ในขณะที่พึ่งพาพฤติกรรมการใช้ความสามารถของ Nginx โดยเฉพาะถ้าเราสามารถสันนิษฐานได้ว่า Gunicorn จะไม่อ่านการเชื่อมต่อโดยตรงจากอินเทอร์เน็ตเราไม่ต้องกังวลเกี่ยวกับลูกค้าที่ทำงานช้า ซึ่งหมายความว่ารูปแบบการประมวลผลสำหรับ Gunicorn นั้นง่ายน่าอาย

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

สำหรับคำถามที่สองของคุณเกี่ยวกับสิ่งที่จัดการกับคำขอ HTTP คำตอบง่ายๆคือ Gunicorn คำตอบที่สมบูรณ์คือ Nginx และ Gunicorn จัดการกับคำร้องขอ โดยทั่วไปแล้ว Nginx จะได้รับการร้องขอและหากเป็นการร้องขอแบบไดนามิก (โดยทั่วไปจะขึ้นอยู่กับรูปแบบ URL) จากนั้นจะให้คำขอนั้นแก่ Gunicorn ซึ่งจะดำเนินการตามคำขอจากนั้นส่งคืนการตอบกลับไปยัง Nginx ซึ่งจะส่งต่อการตอบกลับ ลูกค้า

ดังนั้นในการปิดใช่ คุณต้องการทั้ง Nginx และ Gunicorn (หรือบางอย่างที่คล้ายกัน) สำหรับการปรับใช้ Django ที่เหมาะสม หากคุณต้องการโฮสต์ Django กับ Nginx โดยเฉพาะฉันจะตรวจสอบ Gunicorn, mod_uwsgi และบางที CherryPy ในฐานะผู้สมัครด้าน Django


14
ขอบคุณที่สละเวลาเขียนคำตอบอย่างละเอียด! มีข้อแนะนำสำหรับการอ่านเกี่ยวกับ "สถาปัตยกรรม 3 ชั้น" นี้ไหม
am

5
คำตอบที่ดี แต่ฉันไม่เข้าใจปัญหากับลูกค้าที่ช้า
Mads Skjern

3
@MadsSkjern ฉันคาดเดาที่นี่ แต่ถ้าคุณคิดว่าลูกค้าทุกคนเร็วคุณก็สามารถใช้กลุ่มกระบวนการทำงานของผู้ใช้คงที่และไม่ต้องใช้รหัสสำหรับกรณีที่พวกเขาจำนวนมากหรือทั้งหมดถูกบล็อกรอลูกค้า
Jonathan Hartley


7
แอพ django ของฉันให้บริการ json เท่านั้นไม่มีเนื้อหาแบบคงที่ฉันสามารถไปกับ gunicorn และไม่มี nginx
Sar009

27

ฉันชอบคำอธิบายนี้ในความเรียบง่าย:

Nginx จะเผชิญกับโลกภายนอก มันจะให้บริการไฟล์สื่อ (ภาพ, CSS, ฯลฯ ) โดยตรงจากระบบไฟล์ อย่างไรก็ตามมันไม่สามารถคุยกับแอพพลิเคชั่น Django ได้โดยตรง ต้องการบางสิ่งที่จะเรียกใช้แอปพลิเคชันฟีดคำขอจากเว็บและตอบกลับ

นั่นคืองานของ Gunicorn Gunicorn จะสร้างซ็อกเก็ต Unix และตอบสนองต่อ nginx ผ่านโปรโตคอล wsgi ซ็อกเก็ตจะส่งผ่านข้อมูลในทั้งสองทิศทาง:

The outside world <-> Nginx <-> The socket <-> Gunicorn

https://gist.github.com/Atem18/4696071


มันไม่จำเป็นต้องเป็นซ็อกเก็ตในกรณีที่คนอื่นกำลังสงสัย
akshay

0

ฉันกำลังมองหาคำตอบที่ง่ายเกินไป ...

ฉันต้องมีทั้ง Nginx และบางอย่างเช่น Gunicorn เพื่อปรับใช้แอพ Django บน Nginx หรือไม่?

ถ้าเป็นเช่นนั้นสิ่งที่จัดการกับคำขอ HTTP จริง ๆ ?

คำตอบที่ง่ายเกินไป:

ใช่.

ทั้ง Nginx และ Gunicorn

เนื่องจากคุณกำลังปรับใช้กับ Nginx แน่นอนคุณต้องมี Nginx

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

เอกสารนี้และคำตอบของ Paul จะช่วยให้คุณเรียนรู้ได้ดีขึ้น


0

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

โดยทั่วไปแล้ว nginx จะทำการร้องขอทั้งหมดและจัดการการร้องขอไฟล์แบบสแตติกด้วยตัวเอง และพร็อกซี่เนื้อหาแบบไดนามิกทั้งหมดไปยังเซิร์ฟเวอร์อื่น (gunicorn / django)

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

ฉันได้ทำการเปรียบเทียบและพบสิ่งนี้ - ด้วย gunicorn: 22k req / s โดยไม่มี gunicorn: 34k req / s

ไซต์ของคุณจะต้องการการร้องขอเพิ่มเติมในการโหลดจำนวนมาก


1
คุณกำลังพูดถึงการใช้เซิร์ฟเวอร์การพัฒนาในการผลิต?!
Michael Hampton

เซิร์ฟเวอร์การพัฒนาสามารถรันหลังเซิร์ฟเวอร์ที่ใช้งานจริง (เช่น nginx) เพราะมันจะได้รับการร้องขอในสถานที่ที่ถูกต้องและความปลอดภัยและประสิทธิภาพจะถูกจัดการโดยเซิร์ฟเวอร์การผลิต มันเหมือนกับการใช้แค่ WSGI + กระติกน้ำ แต่คุณสามารถใช้เพียง nginx + django (โดยไม่ต้องใช้มิดเดิลแวร์การเดินป่าเช่น gunicorn) กรุณาทดสอบการตั้งค่าในการโหลดหนักและคุณจะเข้าใจ
ShadowDoom

1
github.com/django/channels/issues/142 (TLDR: มันเป็นความคิดที่ไม่ดี)
igor
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.