Câu trả lời này là bổ sung cho những người khác và giải thích tại sao Unicorn cần nginx trước nó .
TL; DR Lý do mà Unicorn thường được triển khai cùng với một proxy ngược như nginx là vì những người tạo ra nó đã cố tình thiết kế nó như vậy, tạo ra sự đánh đổi cho đơn giản.
Trước hết, không có gì ngăn bạn triển khai Unicorn mà không cần proxy ngược. Tuy nhiên, đó sẽ không phải là một ý tưởng rất tốt; Hãy xem tại sao.
Unicorn tuân theo triết lý Unix là làm một việc và làm tốt , và đó là phục vụ các khách hàng nhanh, độ trễ thấp (chúng ta sẽ thấy điều này có nghĩa là gì sau này). Thực tế là Unicorn được thiết kế cho các khách hàng nhanh, độ trễ thấp cũng ngụ ý rằng nó không tốt lắm với các khách hàng chậm, độ trễ cao , điều đó thực sự đúng. Đây là một trong những điểm yếu của Unicorn và đó là nơi một proxy ngược phát huy tác dụng: nó ngồi trước Unicorn và chăm sóc những khách hàng chậm chạp đó (chúng ta sẽ thấy sau này như thế nào ).
May mắn thay, một proxy ngược như vậy đã tồn tại và được gọi là nginx .
Quyết định chỉ xử lý các máy khách nhanh, đơn giản hóa rất nhiều thiết kế của Unicorn và cho phép một cơ sở mã đơn giản và nhỏ hơn nhiều, với chi phí tăng thêm một số phức tạp trên bộ phận triển khai (ví dụ: bạn phải triển khai nginx ngoài Unicorn).
Một quyết định thay thế có thể là thiết kế Unicorn theo cách mà nó sẽ không cần proxy ngược. Tuy nhiên, điều này có nghĩa là nó sẽ phải thực hiện chức năng bổ sung để thực hiện tất cả những điều mà nginx hiện đang làm, dẫn đến một cơ sở mã phức tạp hơn và nhiều nỗ lực kỹ thuật hơn.
Thay vào đó, những người tạo ra nó đã đưa ra quyết định tận dụng phần mềm hiện có được thử nghiệm chiến đấu và được thiết kế rất tốt và để tránh lãng phí thời gian và năng lượng cho các vấn đề đã được giải quyết bởi phần mềm khác.
Nhưng hãy để kỹ thuật và trả lời câu hỏi của bạn:
Tại sao Unicorn cần được triển khai cùng với nginx?
Dưới đây là một số lý do chính:
Unicorn sử dụng chặn I / O cho khách hàng
Dựa vào proxy ngược có nghĩa là Unicorn không cần sử dụng I / O không chặn. Thay vào đó, nó có thể sử dụng chặn I / O vốn đã đơn giản hơn và dễ dàng hơn cho người lập trình theo dõi.
Cũng như tài liệu THIẾT KẾ nêu rõ:
[Sử dụng chặn I / O] cho phép theo dõi một đường dẫn mã đơn giản hơn trong trình thông dịch Ruby và ít tòa nhà hơn.
Tuy nhiên, điều này cũng có một số hậu quả:
Điểm mấu chốt số 1: Unicorn không hiệu quả với các máy khách chậm
(Để đơn giản, chúng tôi giả sử thiết lập với 1 nhân viên Unicorn)
Vì việc chặn I / O được sử dụng, một nhân viên Unicorn chỉ có thể phục vụ một khách hàng tại một thời điểm , do đó, một khách hàng chậm (nghĩa là một khách hàng có kết nối chậm) sẽ khiến công nhân bận rộn trong thời gian dài hơn (so với một khách hàng nhanh sẽ làm ). Trong khi đó, các khách hàng khác sẽ đợi cho đến khi nhân viên rảnh rỗi trở lại (nghĩa là các yêu cầu sẽ chồng chất trong hàng đợi).
Để giải quyết vấn đề này, một proxy ngược được triển khai trước Unicorn, giúp đệm đầy đủ các yêu cầu đến và phản hồi của ứng dụng, sau đó gửi từng cái một lúc (còn gọi là cho chúng ăn) cho Unicorn và các máy khách. Về vấn đề đó, bạn có thể nói rằng proxy ngược "che chắn" Unicorn khỏi các máy khách mạng chậm.
May mắn thay, Nginx là một ứng cử viên tuyệt vời cho vai trò này, vì nó được thiết kế để xử lý hàng ngàn hàng trăm khách hàng đồng thời một cách hiệu quả.
Điều quan trọng quan trọng là proxy ngược phải nằm trong cùng một mạng cục bộ với Unicorn (thường trong cùng một máy vật lý giao tiếp với w / Unicorn thông qua ổ cắm tên miền Unix), do đó độ trễ của mạng được giữ ở mức tối thiểu.
Vì vậy, một proxy như vậy thực sự đóng vai trò của một khách hàng nhanh mà Unicorn được thiết kế để phục vụ ngay từ đầu, vì nó ủy quyền cho Unicorn nhanh chóng và khiến công nhân bận rộn trong khoảng thời gian ngắn nhất (so với thời gian của một khách hàng với một kết nối chậm sẽ làm).
Điểm mấu chốt # 2: Unicorn không hỗ trợ HTTP / 1.1 tiếp tục tồn tại
Do Unicorn sử dụng chặn I / O, điều đó cũng có nghĩa là nó không thể hỗ trợ tính năng duy trì HTTP / 1.1, vì các kết nối liên tục của các máy khách chậm sẽ nhanh chóng chiếm giữ tất cả các nhân viên Unicorn có sẵn.
Do đó, để tận dụng HTTP, hãy đoán xem: proxy ngược được sử dụng.
Mặt khác, nginx có thể xử lý hàng ngàn kết nối đồng thời chỉ bằng một vài luồng. Do đó, nó không có giới hạn đồng thời mà một máy chủ như Unicorn có (về cơ bản giới hạn số lượng quy trình công nhân), có nghĩa là nó có thể xử lý các kết nối liên tục tốt. Nhiều hơn về cách thức này thực sự hoạt động có thể được tìm thấy ở đây .
Đó là lý do tại sao nginx chấp nhận các kết nối liên tục từ các máy khách và ủy quyền cho Unicorn đến các kết nối đơn giản thông qua một ổ cắm Unix.
Điểm # 3: Unicorn không giỏi trong việc phục vụ các tệp tĩnh
Một lần nữa, phục vụ các tệp tĩnh là điều mà Unicorn có thể làm nhưng không được thiết kế để làm hiệu quả.
Mặt khác, các proxy ngược như nginx mặc dù tốt hơn nhiều về nó (tức là sendfile(2)
& bộ nhớ đệm).
Hơn
Có những điểm khác được nêu trong tài liệu PHILOSOPHY (xem "Cải thiện hiệu suất thông qua ủy quyền ngược" ).
Xem thêm một số tính năng cơ bản của nginx .
Chúng tôi thấy rằng bằng cách tận dụng phần mềm hiện có (ví dụ: nginx) và tuân theo triết lý Unix "làm một việc và làm tốt", Unicorn có thể làm theo thiết kế và triển khai đơn giản hơn trong khi vẫn duy trì hiệu quả trong việc phục vụ các ứng dụng Rack (ví dụ. ứng dụng Rails của bạn).
Để biết thêm thông tin, hãy tham khảo triết lý và tài liệu thiết kế của Unicorn , giải thích chi tiết hơn về các lựa chọn đằng sau thiết kế của Unicorn và tại sao nginx được coi là một proxy ngược tốt cho Unicorn.