Các lựa chọn khi deploy Ruby on Rails app

Deploy app lên server là công đoạn cuối cùng để đưa sản phẩm web của bạn đến với người dùng. Nếu là một web developer thì sớm hay muộn bạn cũng cần phải biết về công đoạn deploy này. Những bài viết hướng dẫn việc deploy Ruby on Rails app có rất nhiều trên mạng. Tuy nhiên chỉ lướt qua một lượt chắc hẳn bạn sẽ nhanh chóng nhận ra rằng có cả tấn các lựa chọn khác nhau để có thể deploy một app RoR. Từ việc dùng Paas hay IaaS, Apache hay Nginx, Passenger, Unicorn, Puma hay Thin... Khi bắt tay vào tìm hiểu thì hàng loạt các lựa chọn ấy như một cái mê cung với mình vậy. Tất nhiên mỗi một lựa chọn sinh ra đều có những ưu nhược điểm của nó và công việc của chúng là đảm bảo rằng mình sẽ tìm ra được lựa chọn phù hợp nhất đối với mình. Và hôm nay sau khi đã tìm được những lựa chọn cho mình, mình xin chia sẻ lại những thông tin cơ bản nhất để có thể giúp các bạn mới bắt đầu có thể nắm bắt nhanh chóng hơn về deploy.

1. IaaS vs Paas

Câu hỏi đầu tiên bạn cần trả lời cho chính mình đó là sẽ lựa chọn công nghệ nào giữa PaaS (platform as a service) và IaaS(Infrastructure as a service).

Với PaaS bạn sẽ có một hệ điều hành và một môi trường đầy đủ các thành phần cần thiết để chạy ứng dụng Ruby on Rails. Với môi trường đầy đủ như vậy công việc của bạn sẽ đơn giản hơn rất nhiều, phần lớn mọi thứ sẽ tự động và bạn chỉ việc đẩy code của mình lên và thêm một vài config mà thôi. Tuy nhiên với PaaS bạn sẽ khó mà biết được cái gì đang thực sự xảy ra bên dưới, và cả quyền hạn của bạn trên một hệ thống PaaS là rất hạn chế nên có những config bạn sẽ không thể tự mình thực hiện được. Một số giải pháp PaaS phổ biến cho RoR hiện có là: Heroku, EngineYard, DotCloud.

Với IaaS bạn sẽ có một server với hệ điều hành được cài sẵn và đó là tất cả. Bạn sẽ có toàn quyền với hệ thống đó để cài đặt các thành phần cần thiết thêm vào. Xây dựng mọi thành phần từ dưới lên sẽ giúp bạn sẽ nắm rõ hơn cách mà các thành phần kết hợp với nhau và vận hành. Để deploy RoR app chúng ta có khá nhiều lựa chọn nhà cung cấp IaaS và 2 cái tên được sử dụng nhiều nhất là Amazon EC2 và DigitalOcean.

Ở đây mình sẽ nói về các lựa chọn xây dựng hệ thống dựa trên nền tảng IaaS để bắt đầu.

2. Nginx và Apache

Câu hỏi tiếp theo mà bạn cần trả lời đó là chọn web server nào. Rất may là với web server chúng ta không có quá nhiều lựa chọn để cân nhắc. Hiện nay 2 web server phổ biến nhất là Nginx và Apache và phần lớn các website ngày nay sử dụng 1 trong 2 web server này.

feature_image.jpg

Sau đây là vài điểm quan trọng bạn cần nắm được để đưa ra lựa chọn cho mình:

  • Web server là phần mềm nhận request được gửi đến website của bạn và thực hiện một vài sử lí trước khi gửi những request ấy đến Rails app của bạn.
  • Apache là web server phổ biến hơn với nhiều tính năng hơn. Nginx ra đời sau, nhỏ gọn, ít tính năng hơn Apache nhưng nhanh hơn nhiều so với Apache.
  • Cả Apache và Nginx đều sử lí rất tốt các file static. Còn đối với các file dinamic, Apache có thể tự mình sử lí còn Nginx sẽ phải thông qua các bên thứ ba sử lí các file đó và nhận kết quả trả về.
  • “Apache is like Microsoft Word. It has a million options but you only need six. NGINX does those six things, and it does five of them 50 times faster than Apache.” — Chris Lea. Đây là một nhận xét khá thú vị về Nginx và Apache.
  • Cả Apache và Nginx đều có thể hoạt động như một reverse proxices. Khi đó chúng có thể nhận các request gửi đến và chuyển cho một web server khác mà cùng sử dụng HTTP. Khi server đó phản hồi với một HTTP response, Apache/Nginx sẽ chuyển response đó về phía client. Đây cũng là lí mà chúng ta không nhất thiết phải chọn hoặc Apache hoặc Nginx mà có thể sử dụng kết hợp cả 2 để tận dụng những ưu điểm của cả Apache và Nginx. Bạn có thể tham khảo thêm về việc dùng Nginx như một reverse proxices cho Apache tại đây.

3. App server

Tiếp đến có lẽ sẽ là lựa chọn quan trọng và cũng là nhức đầu nhất cho bạn. Đó là dùng app server nào và dùng với mô hình như thế nào?

3.1 App server là gì?

  • Một app server là thành phần chạy bên trong Rails app của bạn. Nó sẽ load và giữ code của bạn trong bộ nhớ. Khi một request được gửi đến từ web server, app server sẽ nói với Rails app về request đó và Rails app thực hiện xử lí. Sau khi Rails app thực hiện xong công việc xử lí request, app server sẽ gửi response lại cho phía web server để trả về cho client.
  • Một app server cũng có thể chạy độc lập mà không cần có web server trước nó. Đây chính là việc ta vẫn làm ở môi trường development. Chỉ chạy app server (mặc định là WEBrick) mà không cần đến web server. Tuy nhiên ở môi trường Product thì thường chúng ta sẽ cần đến web server.

3.2 Các app server cho Rails

  • Với Rails chúng ta có rất nhiều lựa chọn cho app server như Mongrel, WEBrick, Phusion Passenger, Unicorn, Puma, Thin, Rainbows.
  • Mongrel đã ra đời từ lâu và không còn được tiếp tục phát triển. Nó không hỗ trợ giám sát tiến trình (process monitoring từ này dịch ra thấy ngu ngu, nhưng thôi dùng tạm ^^). Nếu một tiến trình bị lỗi, chúng ta sẽ cần restart lại tiến trình ấy bằng tay. Mongrel hoạt động theo cơ chế single-threaded multi-process
  • WEBrick được viết bằng Ruby và được tích hợp sẵn vào Ruby. Đó là lí do vì sao khi bạn chạy một Rails app ở môi trường develop thì sẽ mặc định sử dụng WEBrick. Tuy nhiên WEBrick chậm và không thực sự mạnh, ngoài ra nó còn có một số vấn đề khác nữa nên không được khuyến cáo để sử dụng trên môi trường production. Ưu điểm lớn nhất của nó là được tích hợp sẵn vào ruby và bạn không phải tự tay cài như các app server khác.
  • Phusion Passenger sẽ được đề cập ở dưới vì nó hơi khác một chút.
  • Unicorn được fork từ Mongrel. Với Unicorn, nếu một tiến trình bị lỗi, nó sẽ tự động restart bởi tiến trình chủ. Khi dùng Unicorn tất cả các tiến trình có thể lắng nghe trên một shared socket thay vì mỗi socket cho một tiến trình. Cũng như Mongrel, Unicorn hoạt động theo cơ chế single-threaded multi-process.
  • Thin sử dụng mô hình I/O bằng cách sử dụng thư viện EventMachine. Mô hình cluster của Thin không hỗ trợ giám sát tiến trình vì vậy bạn sẽ cần giám sát các tiến trình lỗi. Ngoài ra Thin cũng không có shared socket giống như Unicorn do đó mỗi tiến trình sẽ lắng nghe trên một socket riêng biệt của nó.
  • Puma cũng được fork từ Mongrel nhưng không giống Unicorn, nó được thiết kế để hoạt động đa luồng. Do đó hiện nay nó không được xây dựng để hỗ trợ cluster. Khi dùng Puma bạn sẽ cần đảm bảo để có thể sử dụng nhiều lõi.
  • Rainbows hỗ trợ nhiều mô hình đồng thời thông qua việc sử dụng các thư viện khác nhau.
  • Các app server có thể kết nối trực tiếp với internet gồm có Passenger và Rainbows
  • Các app server không thể kết nối trực tiếp với internet và cần được đặt sau reverse proxy, web server: Mongrel, Unicorn, Thin, Puma
  • Hầu hết các app server có thể sử lí các file static nhưng không hiệu quả bằng Apache hay Nginx. Do đó thông thường Apache/Nginx sẽ được set up để sử lí các file static còn các request khác sẽ được gửi qua app server sử lí. Cách làm này sẽ giúp website của bạn được bảo mật hơn bởi các Apache và Nginx đều được phát triển từ rất lâu và chúng có thể giúp website của bạn chống đỡ với những request nguy hiểm.

3.3 Phusion Passenger

Phusion Passenger là app server có nhiều điểm khách biệt so với các app server còn lại.

  • Phusion Passenger được tích hợp trực tiếp vào Apache hoặc Nginx
  • Mục tiêu của Phusion Passenger là nhằm giảm tối đa những rắc rồi dành cho nhà phát triển. Do vậy thay vì phải bắt đầu một tiến trình hay cluster cho app của bạn và config cho Apache/Nginx xử lí các file tĩnh và chuyển các request khác đến app server thì bạn chỉ cần sửa web server config file và khai báo location của app. Đây là bước thứ nhất và bạn hoàn toàn không phải làm thêm bước thứ 2 nào nữa.
  • Với Passenger rất nhiều công việc sẽ được tự động hoá thay vì bạn phải tự tay làm. Bạn sẽ không cần phải start cluster và quản lí các tiến trình, không cần restart các tiến trình khi chúng bị lỗi, tất cả đều được passenger thực hiện tự động.

Trên đây mình đã giới thiệu những lựa chọn, khái niệm thường gặp khi bạn băt đầu deploy một ứng dụng Rails. Chúc bạn thành công!

Nguồn

http://stackoverflow.com/questions/4113299/ruby-on-rails-server-options http://www.justinweiss.com/articles/a-web-server-vs-an-app-server/