คำตอบนี้เป็นที่เกื้อกูลต่อคนอื่น ๆ และอธิบายว่าทำไมยูนิคอร์นต้องการ 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 ที่ดีสำหรับยูนิคอร์น