Jawaban ini melengkapi jawaban lainnya dan menjelaskan mengapa Unicorn membutuhkan nginx di depannya .
TL; DR Alasan Unicorn biasanya digunakan bersama dengan reverse proxy seperti nginx adalah karena penciptanya sengaja merancangnya, membuat kompromi untuk kesederhanaan.
Pertama-tama, tidak ada yang menghalangi Anda untuk menyebarkan Unicorn tanpa proxy terbalik. Namun, itu bukanlah ide yang bagus; mari kita lihat kenapa.
Unicorn mengikuti filosofi Unix yaitu melakukan satu hal dan melakukannya dengan baik , yaitu melayani klien dengan latensi rendah dan cepat (kita akan lihat apa artinya nanti). Fakta bahwa Unicorn dirancang untuk klien cepat dan latensi rendah juga menyiratkan bahwa itu tidak terlalu bagus dengan klien latensi tinggi yang lambat , yang memang benar. Ini adalah salah satu kelemahan Unicorn dan di sinilah reverse proxy berperan: ia berada di depan Unicorn dan menangani klien yang lambat (kita akan lihat caranya nanti).
Untungnya, reverse proxy sudah ada dan disebut nginx .
Keputusan untuk hanya menangani klien yang cepat, sangat menyederhanakan desain Unicorn dan memungkinkan basis kode yang jauh lebih sederhana dan lebih kecil, dengan biaya beberapa kerumitan tambahan pada departemen penerapan (misalnya, Anda juga harus menerapkan nginx selain Unicorn).
Keputusan alternatif dapat merancang Unicorn sedemikian rupa sehingga tidak memerlukan proxy terbalik. Namun, ini berarti ia harus menerapkan fungsionalitas ekstra untuk melakukan semua hal yang sekarang dilakukan nginx, menghasilkan basis kode yang lebih kompleks dan upaya rekayasa yang lebih banyak.
Sebaliknya penciptanya membuat keputusan untuk memanfaatkan perangkat lunak yang ada yang telah teruji pertempuran dan dirancang dengan sangat baik dan untuk menghindari pemborosan waktu dan energi untuk masalah yang sudah dipecahkan oleh perangkat lunak lain.
Tapi mari kita secara teknis dan menjawab pertanyaan Anda:
Mengapa Unicorn perlu diterapkan bersama dengan nginx?
Berikut beberapa alasan utamanya:
Unicorn menggunakan pemblokiran I / O untuk klien
Mengandalkan proxy terbalik berarti Unicorn tidak perlu menggunakan I / O non-pemblokiran. Sebagai gantinya dapat menggunakan pemblokiran I / O yang secara inheren lebih sederhana dan lebih mudah untuk diikuti oleh programmer.
Juga sebagai dokumen DESIGN menyatakan:
[Menggunakan I / O pemblokiran] memungkinkan jalur kode yang lebih sederhana untuk diikuti dalam interpreter Ruby dan lebih sedikit syscall.
Namun, ini juga memiliki beberapa konsekuensi:
Poin utama # 1: Unicorn tidak efisien dengan klien yang lambat
(Demi kesederhanaan, kami menganggap penyiapan dengan 1 pekerja Unicorn)
Karena pemblokiran I / O digunakan, pekerja Unicorn hanya dapat melayani satu klien dalam satu waktu , jadi klien yang lambat (yaitu klien dengan koneksi lambat) akan secara efektif membuat pekerja sibuk untuk waktu yang lebih lama (daripada yang dilakukan klien cepat ). Sementara itu, klien lain hanya akan menunggu sampai pekerja bebas lagi (mis. Permintaan akan menumpuk di antrian).
Untuk mengatasi masalah ini, proxy terbalik diterapkan di depan Unicorn, yang sepenuhnya mendukung permintaan masuk dan respons aplikasi, lalu mengirimkan masing-masing sekaligus (alias menyendokkan mereka) ke Unicorn dan klien. Dalam hal ini, Anda dapat mengatakan bahwa reverse proxy "melindungi" Unicorn dari klien jaringan yang lambat.
Untungnya Nginx adalah kandidat yang bagus untuk peran ini, karena dirancang untuk menangani ribuan klien bersamaan secara efisien.
Sangat penting bahwa reverse proxy harus berada dalam jaringan lokal yang sama dengan Unicorn (biasanya dalam mesin fisik yang sama yang berkomunikasi dengan Unicorn melalui soket domain Unix), sehingga latensi jaringan dijaga seminimal mungkin.
Jadi proxy seperti itu secara efektif memainkan peran sebagai klien cepat yang dirancang untuk dilayani oleh Unicorn sejak awal, karena proxy ini mem-proxy permintaan ke Unicorn dengan cepat dan membuat pekerja sibuk untuk waktu sesingkat mungkin (dibandingkan dengan berapa banyak waktu klien dengan koneksi yang lambat akan dilakukan).
Poin utama # 2: Unicorn tidak mendukung HTTP / 1.1 tetap hidup
Karena Unicorn menggunakan pemblokiran I / O, itu juga berarti bahwa ia tidak dapat mendukung fitur tetap-hidup HTTP / 1.1, karena koneksi persisten dari klien yang lambat akan dengan cepat menempati semua pekerja Unicorn yang tersedia.
Oleh karena itu untuk memanfaatkan HTTP tetap hidup, coba tebak: proxy terbalik digunakan.
nginx di sisi lain, dapat menangani ribuan koneksi bersamaan hanya dengan menggunakan beberapa utas. Oleh karena itu, ia tidak memiliki batas konkurensi yang dimiliki server seperti yang dimiliki Unicorn (yang pada dasarnya terbatas pada jumlah proses pekerja), yang berarti ia dapat menangani koneksi persisten dengan baik. Lebih lanjut tentang cara kerjanya dapat ditemukan di sini .
Itulah mengapa nginx menerima koneksi keep-hidup dari klien dan memproksinya ke Unicorn melalui koneksi biasa melalui soket Unix.
Poin # 3: Unicorn tidak pandai menyajikan file statis
Sekali lagi, melayani file statis adalah hal yang dapat dilakukan Unicorn tetapi tidak dirancang untuk dilakukan secara efisien.
Sebaliknya, reverse proxy seperti nginx jauh lebih baik dalam hal itu (mis. sendfile(2)
& Caching).
Lebih
Ada poin-poin lain yang dijelaskan dalam dokumen FILOSOFI (lihat "Peningkatan Kinerja Melalui Proksi Terbalik" ).
Lihat juga beberapa fitur dasar nginx .
Kami melihat bahwa dengan memanfaatkan perangkat lunak yang ada (mis. Nginx) dan mengikuti filosofi Unix "melakukan satu hal dan melakukannya dengan baik", Unicorn dapat mengikuti desain dan implementasi yang lebih sederhana sambil mempertahankan agar efisien dalam melayani aplikasi Rack (mis. aplikasi Rails Anda).
Untuk informasi lebih lanjut, lihat filosofi dan dokumen desain Unicorn yang menjelaskan lebih detail pilihan di balik desain Unicorn dan mengapa nginx dianggap sebagai proxy balik yang baik untuk Unicorn.