เหตุใดยูนิคอร์นจึงจำเป็นต้องปรับใช้พร้อมกับ Nginx


138

ฉันต้องการทราบความแตกต่างระหว่าง Nginx และ Unicorn เท่าที่ฉันเข้าใจ Nginx เป็นเว็บเซิร์ฟเวอร์ในขณะที่ Unicorn เป็นเซิร์ฟเวอร์ Ruby HTTP

เนื่องจากทั้ง Nginx และ Unicorn สามารถจัดการการร้องขอ HTTP จำเป็นต้องใช้การรวมกันของ Nginx และ Unicorn สำหรับแอปพลิเคชัน RoR อย่างไร


3
คำถามที่ดี ! ฉันคิดว่าชื่อของคำถามนี้ควรจะเป็น "ทำไมเราต้องมีการรวมกันของ nginx และยูนิคอร์น;) คำตอบที่เป็นประโยชน์มากสำหรับฉัน
servatj

1
@servatj ฉันได้เพิ่มคำตอบที่อธิบายในรายละเอียดมากขึ้นว่าทำไม Unicorn จึงต้องการ reverse proxy เช่น Nginx ที่อยู่ข้างหน้า คุณอาจต้องการตรวจสอบออก;)
Agis

คำตอบ:


62

Nginx
ป้อนคำอธิบายรูปภาพที่นี่
Unicorn
ป้อนคำอธิบายรูปภาพที่นี่
อ้างถึงยูนิคอร์นบน githubสำหรับข้อมูลเพิ่มเติม


1
Pratik, คำถามของฉันคือเซิร์ฟเวอร์ยูนิคอร์นสามารถตอบสนองทั้งกระบวนการแบบคงที่และแบบไดนามิกแล้วทำไมเราจึงใช้ NGinx หรือ Apache ผู้ที่สามารถประมวลผลเนื้อหาคงที่เพียงอย่างเดียวรวมกับผู้โดยสารหรือยูนิคอร์นหรือ mod_php?
loganathan

17
@loganathan ทั้ง Apache และ Nginx นั้นเร็วกว่าในการให้บริการเนื้อหาคงที่มากกว่า ruby ​​หรือแอ็พพลิเคชันเซิร์ฟเวอร์ใด ๆ พวกเขายังรู้วิธีจัดการกับการแคชและอนุญาตให้ดาวน์โหลดไฟล์พร้อมกันในขณะที่ยังรับส่งข้อมูลและส่งผ่านไปยังแอพพลิเคชันเซิร์ฟเวอร์
Pratik

4
นอกจากนี้หากคุณมีข้อมูลจำนวนมากที่มา + ไป nginx จะบัฟเฟอร์ข้อมูลจาก (และที่ป้อนด้วยช้อน) ลูกค้า หากไม่มี nginx หนึ่งในยูนิคอร์นของคุณจะถูกเชื่อมโยงระหว่างการอัพโหลด / ดาวน์โหลด
BraveNewCurrency

10
นี่ไม่ได้ตอบคำถามที่ว่าทำไมจึงจำเป็นต้องมี nginx มันใส่ไว้ในรูปภาพทั้งคู่โดยไม่มีความคิดเห็นใด ๆ คำตอบของนิคนั้นดีกว่ามาก
สาบาน

1
ฉันเห็นด้วยกับ @gorn ยกตัวอย่างเช่น
BalinKingOfMoria คืนสถานะให้กับ CM

94

Nginx เป็นเว็บเซิร์ฟเวอร์ล้วนที่ให้บริการเนื้อหาคงที่และ / หรือเปลี่ยนเส้นทางคำขอไปยังซ็อกเก็ตอื่นเพื่อจัดการคำขอ

Unicorn เป็นเว็บเซิร์ฟเวอร์ของ Rack และมีวัตถุประสงค์เพื่อโฮสต์ 'Rack App' ซึ่งโดยปกติจะสร้างเนื้อหาแบบไดนามิก แอพชั้นวางยังสามารถแสดงเนื้อหาแบบคงที่ได้ แต่ก็มีประสิทธิภาพน้อยกว่าเว็บเซิร์ฟเวอร์ทั่วไปส่วนใหญ่

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


73

คำตอบนี้เป็นที่เกื้อกูลต่อคนอื่น ๆ และอธิบายว่าทำไมยูนิคอร์นต้องการ Nginx ในด้านหน้าของมัน

TL; DR เหตุผลที่ยูนิคอร์นมักใช้งานร่วมกับพร็อกซีย้อนกลับอย่าง nginx นั้นเป็นเพราะผู้สร้างออกแบบอย่างจงใจเพื่อให้เกิดความเรียบง่าย

ก่อนอื่นไม่มีอะไรขัดขวางคุณไม่ให้ปรับใช้ Unicorn โดยไม่มี reverse proxy อย่างไรก็ตามนั่นไม่ใช่ความคิดที่ดีมาก มาดูกันว่าทำไม

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

โชคดีเช่นพร็อกซี่กลับมีอยู่แล้วและถูกเรียกว่าNginx

การตัดสินใจที่จะจัดการกับไคลเอนต์ที่รวดเร็วเท่านั้นทำให้การออกแบบของ Unicorn ง่ายขึ้นและอนุญาตให้ใช้ codebase ที่เล็กลงและง่ายขึ้นด้วยต้นทุนของความซับซ้อนที่เพิ่มเข้ามาในแผนกการปรับใช้ (เช่นคุณต้องปรับใช้ nginx นอกเหนือจาก Unicorn)

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

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

แต่มารับทางเทคนิคและตอบคำถามของคุณ:

เหตุใดยูนิคอร์นจึงจำเป็นต้องปรับใช้พร้อมกับ nginx

นี่คือเหตุผลสำคัญบางประการ:

ยูนิคอร์นใช้การบล็อก I / O สำหรับลูกค้า

การใช้ reverse proxy หมายความว่า Unicorn ไม่จำเป็นต้องใช้ I / O ที่ไม่มีการบล็อก แต่สามารถใช้การบล็อก I / O ซึ่งเป็นเรื่องง่ายกว่าและง่ายกว่าสำหรับโปรแกรมเมอร์ที่จะติดตาม

เช่นเดียวกับสถานะเอกสารการออกแบบ :

[การใช้การบล็อก I / O] ช่วยให้สามารถติดตามเส้นทางที่ง่ายกว่าภายในล่าม Ruby และ syscalls น้อยลง

อย่างไรก็ตามสิ่งนี้ยังมีผลที่ตามมา:

จุดสำคัญ # 1: ยูนิคอร์นไม่ได้มีประสิทธิภาพกับลูกค้าที่ช้า

(เพื่อความเรียบง่ายเราจะทำการติดตั้งกับ 1 Unicorn workers)

เนื่องจากมีการใช้การบล็อก I / O ผู้ปฏิบัติงานยูนิคอร์นสามารถให้บริการลูกค้าได้ครั้งละหนึ่งรายเท่านั้นดังนั้นไคลเอ็นต์ที่ช้า (เช่นที่มีการเชื่อมต่อที่ช้า) จะทำให้คนงานไม่ว่างเป็นเวลานาน (มากกว่าไคลเอนต์ที่รวดเร็ว) ) ในระหว่างนี้ลูกค้ารายอื่นจะรอจนกว่าผู้ปฏิบัติงานจะว่างอีกครั้ง (เช่นคำขอจะพะเนินในคิว)

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

โชคดีที่ Nginx เป็นผู้สมัครที่ยอดเยี่ยมสำหรับบทบาทนี้เนื่องจากได้รับการออกแบบมาเพื่อจัดการกับลูกค้าหลายพันคนพร้อมกันได้อย่างมีประสิทธิภาพ

มีความสำคัญอย่างยิ่งที่พร็อกซีย้อนกลับควรอยู่ในเครือข่ายท้องถิ่นเดียวกันกับยูนิคอร์น (โดยทั่วไปจะอยู่ในเครื่องเดียวกันที่สื่อสารด้วย w / ยูนิคอร์นผ่านซ็อกเก็ตโดเมน Unix) เพื่อให้เวลาในการตอบสนองเครือข่ายต่ำที่สุด

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

จุดสำคัญ # 2: ยูนิคอร์นไม่สนับสนุน HTTP / 1.1 แบบ keep-alive

เนื่องจากยูนิคอร์นใช้การบล็อก I / O ก็หมายความว่ามันไม่สามารถรองรับฟีเจอร์ HTTP / 1.1 แบบ keep-alive เนื่องจากการเชื่อมต่อแบบต่อเนื่องของไคลเอนต์ที่ช้าจะเข้าครอบครองคนงานยูนิคอร์นที่มีอยู่ทั้งหมดได้อย่างรวดเร็ว

ดังนั้นในการใช้ประโยชน์ HTTP แบบคงที่ให้ลองเดาดูว่ามีการใช้ reverse proxy อย่างไร

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

นั่นเป็นเหตุผลที่ nginx ยอมรับการเชื่อมต่อแบบ keep-alive จากลูกค้าและผู้รับมอบฉันทะไปยัง Unicorn ผ่านการเชื่อมต่อธรรมดาผ่านซ็อกเก็ต Unix

จุดที่ 3: ยูนิคอร์นไม่ค่อยดีในการให้บริการไฟล์คงที่

อีกครั้งการให้บริการไฟล์คงที่เป็นสิ่งที่ยูนิคอร์นสามารถทำได้ แต่ไม่ได้ออกแบบมาเพื่อทำอย่างมีประสิทธิภาพ

ตรงกันข้ามผู้รับมอบฉันทะกลับเช่น nginx แม้ว่าจะดีกว่ามากที่มัน (เช่นsendfile(2)& แคช)

มากกว่า

มีประเด็นอื่น ๆ ที่ระบุไว้ในเอกสารPHILOSOPHY (ดูที่"การปรับปรุงประสิทธิภาพด้วยการใช้พร็อกซีย้อนกลับ" )

ดูเพิ่มเติมบางส่วนของคุณสมบัติพื้นฐานของ Nginx

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

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


แต่ทำไมไม่ใช้ Nginx ฉันคิดว่าเขาถามไม่ใช่ 'ทำไมยูนิคอร์นถึงต้องการ nginx' ยูนิคอร์นให้อะไรที่ Nginx ทำไม่ได้?
ทุก

3
@oMiKeY หากเป็นเช่นนั้นฉันเชื่อว่าคำตอบอื่น ๆ อยู่ในคำถามนี้ค่อนข้างดี ฉันยังคิดว่าคำตอบของฉันให้ข้อมูลที่เป็นประโยชน์สำหรับทุกคนที่พยายามเข้าใจการรวมกันของ nginx & unicorn
Agis

2
นี่คือทองคำบริสุทธิ์ ขอบคุณ!
Magne

14

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

ดูhttp://unicorn.bogomips.org/

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