Tùy chọn máy chủ Ruby on Rails [đã đóng]


578

Toàn bộ vấn đề thiết lập máy chủ phát triển cho ứng dụng Ruby on Rails của tôi làm tôi bối rối. Có WEBrick, Mongrel, Hành khách, Apache, Nginx và nhiều hơn nữa tôi chắc chắn, và tôi không thực sự hiểu các vai trò khác nhau mà họ đóng.

Tôi bắt đầu sử dụng WEBrick và bây giờ tôi sử dụng Mongrel để phát triển. Các máy chủ này có độc lập không, hay chúng ngồi trước Apache?

Tôi đã đọc về Hành khách và tôi không thực sự hiểu nó là gì, trang web nói "làm cho việc triển khai các ứng dụng web Ruby trở nên dễ dàng", nó có thay thế Mongrel không? Có giống như Capistrano, cũng triển khai các ứng dụng web?

Hãy nhớ rằng tôi muốn kiểm tra SSL và tôi tin rằng không được hỗ trợ bởi mongrel, thiết lập máy chủ phát triển tốt nhất là gì?

Cảm ơn


2
Bạn đã xem screencast Phusion Hành khách? Nó mô tả khá nhiều trong 5 phút tất cả những gì cần thiết để đưa ứng dụng Rails của bạn lên mạng.
Hongli

27
Đối với một câu hỏi không có tính xây dựng, điều này chắc chắn đã nhận được rất nhiều sự ủng hộ, và vì vậy đã có câu trả lời.
Teemu Leisti

32
Tôi biết câu hỏi này phá vỡ các quy tắc của SO nhưng tôi tự hỏi nếu nhiều người dùng thấy câu hỏi này hữu ích thì có lẽ đã đến lúc sửa đổi một số quy tắc?
Hardik

Câu trả lời:


1264

Từ "triển khai" có thể có hai nghĩa tùy thuộc vào ngữ cảnh. Bạn cũng nhầm lẫn vai trò của Apache / Nginx với vai trò của các thành phần khác.

Lưu ý lịch sử: Bài viết này ban đầu được viết vào ngày 6 tháng 11 năm 2010, khi hệ sinh thái máy chủ ứng dụng Ruby bị hạn chế. Tôi đã cập nhật bài viết này vào ngày 15 tháng 3 năm 2013 với tất cả các cập nhật mới nhất trong hệ sinh thái.

Tuyên bố miễn trừ trách nhiệm : Tôi là một trong những tác giả của Phusion Pasbah, một trong những máy chủ ứng dụng.

Apache vs Nginx

Cả hai đều là máy chủ web. Chúng có thể phục vụ các tệp tĩnh nhưng - với các mô-đun phù hợp - cũng có thể phục vụ các ứng dụng web động, ví dụ như các ứng dụng được viết bằng PHP. Apache phổ biến hơn và có nhiều tính năng hơn, Nginx nhỏ hơn và nhanh hơn và có ít tính năng hơn.

Cả Apache và Nginx đều không thể phục vụ các ứng dụng web Ruby ngoài luồng, để làm điều đó bạn cần sử dụng Apache / Nginx kết hợp với một số loại tiện ích bổ sung, được mô tả sau.

Apache và Nginx cũng có thể hoạt động như các proxy ngược, nghĩa là họ có thể nhận một yêu cầu HTTP đến và chuyển tiếp nó đến một máy chủ khác, cũng nói HTTP. Khi máy chủ đó phản hồi với phản hồi HTTP, Apache / Nginx sẽ chuyển tiếp phản hồi trở lại máy khách; Bạn sẽ tìm hiểu sau tại sao điều này có liên quan.

Mongrel và các máy chủ ứng dụng sản xuất khác vs WEBrick

Mongrel là một "máy chủ ứng dụng" của Ruby: Nói một cách cụ thể, điều này có nghĩa là Mongrel là một ứng dụng:

  1. Tải ứng dụng Ruby của bạn trong không gian xử lý của chính nó.
  2. Thiết lập ổ cắm TCP, cho phép nó giao tiếp với thế giới bên ngoài (ví dụ: Internet). Mongrel lắng nghe các yêu cầu HTTP trên ổ cắm này và chuyển dữ liệu yêu cầu đến ứng dụng web Ruby.
  3. Sau đó, ứng dụng web Ruby trả về một đối tượng, mô tả phản hồi HTTP sẽ trông như thế nào và Mongrel đảm nhiệm việc chuyển đổi nó thành phản hồi HTTP thực (các byte thực tế) và gửi lại qua ổ cắm.

Tuy nhiên Mongrel khá cũ, ngày nay nó không còn được duy trì. Các máy chủ ứng dụng thay thế mới hơn là:

  • Hành khách lừa đảo
  • con kỳ lân
  • Gầy
  • Puma
  • Trinidad (chỉ có ở JRuby)
  • TorqueBox (chỉ dành cho JRuby)

Tôi sẽ trình bày chúng sau và mô tả chúng khác nhau như thế nào và với Mongrel.

WEBrick làm điều tương tự như Mongrel, nhưng sự khác biệt là:

  • WEBrick không phù hợp cho sản xuất, không giống như mọi thứ khác mà tôi đã đề cập trước đó. WEBrick được viết hoàn toàn bằng Ruby. Mongrel (và hầu hết các máy chủ ứng dụng Ruby khác) là một phần của Ruby và phần C (Chủ yếu là Ruby), nhưng trình phân tích cú pháp HTTP của nó được viết bằng C để thực hiện.
  • WEBrick chậm hơn và kém mạnh mẽ hơn. Nó có một số rò rỉ bộ nhớ đã biết và một số vấn đề phân tích cú pháp HTTP đã biết.
  • WEBrick thường chỉ được sử dụng làm máy chủ mặc định trong quá trình phát triển vì WEBrick được bao gồm trong Ruby theo mặc định. Mongrel và các máy chủ ứng dụng khác cần được cài đặt riêng. Không nên sử dụng WEBrick trong môi trường sản xuất, mặc dù vì một số lý do, Heroku đã chọn WEBrick làm máy chủ mặc định. Họ đã sử dụng Thin trước đây, vì vậy tôi không biết tại sao họ lại chuyển sang WEBrick.

Máy chủ ứng dụng và thế giới

Tất cả các máy chủ ứng dụng Ruby hiện tại đều nói HTTP, tuy nhiên một số máy chủ ứng dụng có thể được tiếp xúc trực tiếp với Internet trên cổng 80, trong khi những máy chủ khác thì không.

  • Các máy chủ ứng dụng có thể tiếp xúc trực tiếp với Internet: Hành khách lừa đảo, Cầu vồng
  • Các máy chủ ứng dụng có thể không được tiếp xúc trực tiếp với Internet: Mongrel, Unicorn, Thin, Puma. Các máy chủ ứng dụng này phải được đặt phía sau một máy chủ web proxy ngược như Apache và Nginx.
  • Tôi không biết đủ về Trinidad và TorqueBox, vì vậy tôi đã bỏ qua chúng.

Tại sao một số máy chủ ứng dụng phải được đặt phía sau một proxy ngược?

  • Một số máy chủ ứng dụng chỉ có thể xử lý đồng thời 1 yêu cầu, trên mỗi quy trình. Nếu bạn muốn xử lý đồng thời 2 yêu cầu, bạn cần chạy nhiều phiên bản máy chủ ứng dụng, mỗi trường hợp phục vụ cùng một ứng dụng Ruby. Tập hợp các quy trình máy chủ ứng dụng này được gọi là cụm máy chủ ứng dụng (do đó có tên Mongrel Cluster, Thin Cluster, v.v.). Sau đó, bạn phải thiết lập Apache hoặc Nginx để đảo ngược proxy vào cụm này. Apache / Nginx sẽ đảm nhiệm việc phân phối các yêu cầu giữa các cá thể trong cụm (Thêm về điều này trong phần "Các mô hình đồng thời I / O").
  • Máy chủ web có thể đệm các yêu cầu và phản hồi, bảo vệ máy chủ ứng dụng khỏi "máy khách chậm" - máy khách HTTP không gửi hoặc chấp nhận dữ liệu rất nhanh. Bạn không muốn máy chủ ứng dụng của mình không làm gì trong khi chờ khách hàng gửi yêu cầu đầy đủ hoặc nhận được phản hồi đầy đủ, vì trong thời gian đó, máy chủ ứng dụng có thể không thể làm gì khác. Apache và Nginx rất giỏi làm nhiều việc cùng một lúc vì chúng là đa luồng hoặc là sự kiện.
  • Hầu hết các máy chủ ứng dụng có thể phục vụ các tệp tĩnh, nhưng không đặc biệt tốt về nó. Apache và Nginx có thể làm điều đó nhanh hơn.
  • Mọi người thường thiết lập Apache / Nginx để phục vụ trực tiếp các tệp tĩnh, nhưng chuyển tiếp các yêu cầu không tương ứng với các tệp tĩnh đến máy chủ ứng dụng, đó là cách thực hành bảo mật tốt. Apache và Nginx rất trưởng thành và có thể bảo vệ máy chủ ứng dụng khỏi các yêu cầu bị hỏng (có lẽ là độc hại).

Tại sao một số máy chủ ứng dụng có thể tiếp xúc trực tiếp với Internet?

  • Phusion Pasbah là một quái thú rất khác với tất cả các máy chủ ứng dụng khác. Một trong những tính năng độc đáo của nó là tích hợp vào máy chủ web.
  • Tác giả của Rainbows tuyên bố rằng việc tiếp xúc trực tiếp với Internet là an toàn. Tác giả khá chắc chắn rằng không có lỗ hổng trong trình phân tích cú pháp HTTP (và tương tự). Tuy nhiên, tác giả không cung cấp bảo hành và nói rằng việc sử dụng có nguy cơ riêng.

Máy chủ ứng dụng so sánh

Trong phần này, tôi sẽ so sánh hầu hết các máy chủ ứng dụng mà tôi đã đề cập, nhưng không phải là Phusion Pasbah. Phusion Pasbah là một con thú khác với phần còn lại mà tôi đã dành cho nó một phần dành riêng. Tôi cũng đã bỏ qua Trinidad và TorqueBox vì tôi không biết rõ về chúng, nhưng dù sao chúng cũng chỉ liên quan nếu bạn sử dụng JRuby.

  • Mongrel là xương trần đẹp. Như đã đề cập trước đó, Mongrel hoàn toàn là một quy trình đa luồng, vì vậy nó chỉ hữu ích trong một cụm. Không có giám sát quá trình: nếu một quá trình trong cụm gặp sự cố (ví dụ do lỗi trong ứng dụng) thì nó cần phải được khởi động lại thủ công. Mọi người có xu hướng sử dụng các công cụ giám sát quá trình bên ngoài như Monit và God.
  • Kỳ lân là một ngã ba của Mongrel. Nó hỗ trợ giám sát quá trình hạn chế: nếu một quy trình gặp sự cố, nó sẽ tự động được khởi động lại bởi quy trình chính. Nó có thể làm cho tất cả các quy trình lắng nghe trên một ổ cắm chung, thay vì một ổ cắm riêng cho từng quy trình. Điều này đơn giản hóa cấu hình proxy ngược. Giống như Mongrel, nó hoàn toàn là một quy trình đa luồng.
  • Thin sử dụng mô hình I / O có sự kiện bằng cách sử dụng thư viện EventMachine. Khác với việc sử dụng trình phân tích cú pháp Mongrel HTTP, nó không dựa trên Mongrel dưới bất kỳ hình thức nào. Chế độ cụm của nó không có giám sát quá trình, do đó bạn cần theo dõi sự cố, v.v. Không có ổ cắm chung giống như Unicorn, vì vậy mỗi quy trình lắng nghe trên ổ cắm riêng của nó. Về lý thuyết, mô hình I / O của Thin cho phép đồng thời cao, nhưng trong hầu hết các tình huống thực tế mà Thin được sử dụng, một quy trình Thin chỉ có thể xử lý 1 yêu cầu đồng thời, do đó bạn vẫn cần một cụm. Thông tin thêm về thuộc tính đặc biệt này trong phần "Mô hình đồng thời I / O".
  • Puma cũng được chia rẽ từ Mongrel, nhưng không giống như Unicorn, Puma được thiết kế hoàn toàn đa luồng. Do đó hiện không có hỗ trợ cụm dựng sẵn. Bạn cần đặc biệt cẩn thận để đảm bảo rằng bạn có thể sử dụng nhiều lõi (Thông tin thêm về điều này trong phần "Mô hình đồng thời I / O").
  • 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.

Hành khách lừa đảo

Phusion Hành khách hoạt động rất khác với tất cả những người khác. Phusion Pasbah tích hợp trực tiếp vào Apache hoặc Nginx và do đó có thể so sánh với mod_php cho Apache. Giống như mod_php cho phép Apache phục vụ các ứng dụng PHP, gần như kỳ diệu, Phusion Pasbah cho phép Apache (và cả Nginx!) Phục vụ các ứng dụng Ruby, gần như là kỳ diệu. Mục tiêu của Phusion Pasbah là làm cho mọi thứ chỉ hoạt động (tm) với ít rắc rối nhất có thể.

Thay vì bắt đầu một quy trình hoặc cụm cho ứng dụng của bạn và định cấu hình Apache / Nginx để cung cấp các tệp tĩnh và / hoặc đảo ngược các yêu cầu ủy quyền cho quy trình / cụm với Phusion Pasbah, bạn chỉ cần:

  1. Bạn chỉnh sửa tệp cấu hình máy chủ web và chỉ định vị trí thư mục 'công khai' của ứng dụng Ruby.
  2. Không có bước 2.

Tất cả các cấu hình được thực hiện trong tập tin cấu hình máy chủ web. Phusion Hành khách tự động hóa khá nhiều thứ. Không cần phải bắt đầu một cụm và quản lý các quy trình. Bắt đầu / dừng quá trình, khởi động lại chúng khi chúng gặp sự cố, v.v. - tất cả đều tự động. So với các máy chủ ứng dụng khác, Phusion Pasbah có bộ phận chuyển động ít hơn nhiều. Sự dễ sử dụng này là một trong những lý do chính khiến mọi người sử dụng Phusion Pasbah.

Cũng không giống như các máy chủ ứng dụng khác, Phusion Pasbah chủ yếu được viết bằng C ++, làm cho nó rất nhanh.

Ngoài ra còn có một phiên bản Enterprise của Phusion Pasbah với nhiều tính năng hơn, chẳng hạn như khởi động lại tự động, hỗ trợ đa luồng, chống lỗi triển khai, v.v.

Vì những lý do trên, Phusion Pasbah hiện là máy chủ ứng dụng Ruby phổ biến nhất, cung cấp sức mạnh cho hơn 150.000 trang web, bao gồm các trang web lớn như New York Times, Pixar, Airbnb, v.v.

Phusion Pasbah vs các máy chủ ứng dụng khác

Phusion Pasbah cung cấp nhiều tính năng hơn và cung cấp nhiều lợi thế hơn các máy chủ ứng dụng khác, chẳng hạn như:

  • Tự động điều chỉnh số lượng quy trình dựa trên lưu lượng. Chúng tôi chạy rất nhiều ứng dụng Rails trên máy chủ bị hạn chế tài nguyên mà không phải đối mặt với công chúng và mọi người trong tổ chức của chúng tôi chỉ sử dụng nhiều nhất một vài lần một ngày. Những thứ như Gitlab, Redmine, v.v ... Phusion Pasbah có thể quay vòng các quy trình đó khi chúng không được sử dụng và quay chúng khi chúng được sử dụng, cho phép có nhiều tài nguyên hơn cho các ứng dụng quan trọng hơn. Với các máy chủ ứng dụng khác, tất cả các quy trình của bạn được bật mọi lúc.
  • Một số máy chủ ứng dụng không tốt ở khối lượng công việc nhất định, theo thiết kế. Ví dụ: Unicorn được thiết kế cho các yêu cầu chạy nhanh: Xem phần trang web Unicorn "Chỉ tệ hơn trong một số trường hợp".

Khối lượng công việc mà Unicorn không giỏi là:

  • Truyền tải khối lượng công việc (ví dụ Rails 4 streaming trực tiếp hoặc Rails 4 streaming streaming template).
  • Khối lượng công việc trong đó ứng dụng thực hiện các cuộc gọi API HTTP.

Mô hình I / O lai trong Phusion Pas Pas Enterprise 4 trở lên làm cho nó trở thành một lựa chọn tuyệt vời cho các loại khối lượng công việc này.

  • Các máy chủ ứng dụng khác yêu cầu người dùng chạy ít nhất một phiên bản cho mỗi ứng dụng. Ngược lại, Phusion Pasbah hỗ trợ nhiều ứng dụng trong một trường hợp. Điều này làm giảm đáng kể chi phí quản lý.
  • Tự động chuyển đổi người dùng, một tính năng bảo mật thuận tiện.
  • Phusion Pasbah hỗ trợ nhiều MRI Ruby, JRuby và Rubinius. Mongrel, Unicorn và Thin chỉ hỗ trợ MRI. Puma cũng hỗ trợ cả 3.
  • Phusion Pasbah thực sự hỗ trợ nhiều hơn là Ruby! Nó cũng hỗ trợ Python WSGI, vì vậy, ví dụ, nó cũng có thể chạy các ứng dụng Django và Flask. Trong thực tế, Phusion Pasbah đang chuyển sang hướng trở thành một máy chủ polyglot. Hỗ trợ Node.js trong danh sách việc cần làm.
  • Thu gom rác ngoài băng. Phusion Pasbah có thể chạy trình thu gom rác Ruby ngoài chu kỳ yêu cầu / phản hồi thông thường, có khả năng giảm thời gian yêu cầu hàng trăm mili giây. Unicorn cũng có một tính năng tương tự, nhưng phiên bản của Phusion Pasbah linh hoạt hơn vì 1) nó không giới hạn ở GC và có thể được sử dụng cho công việc tùy ý. 2) Phiên bản của Phusion Pasbah hoạt động tốt với các ứng dụng đa luồng, trong khi phiên bản của Unicorn thì không.
  • Tự động khởi động lại. Khởi động lại trên Unicorn và các máy chủ khác yêu cầu một số công việc viết kịch bản. Phusion Pas Pas Enterprise hoàn toàn tự động theo cách này cho bạn.

Có nhiều tính năng và lợi thế hơn, nhưng danh sách thực sự dài. Bạn nên tham khảo hướng dẫn sử dụng Phusion Hành khách toàn diện ( phiên bản Apache , phiên bản Nginx ) hoặc trang web Hành khách Phusion để biết thông tin.

Mô hình đồng thời I / O

  • Đa luồng đơn xử lý. Theo truyền thống, đây là mô hình I / O phổ biến nhất cho các máy chủ ứng dụng Ruby, một phần vì hỗ trợ đa luồng trong hệ sinh thái Ruby rất tệ. Mỗi quy trình có thể xử lý chính xác 1 yêu cầu tại một thời điểm. Tải máy chủ web cân bằng giữa các quy trình. Mô hình này rất mạnh mẽ và có rất ít cơ hội để lập trình viên giới thiệu các lỗi đồng thời. Tuy nhiên, đồng thời I / O của nó cực kỳ hạn chế (bị giới hạn bởi số lượng quy trình). Mô hình này rất phù hợp với khối lượng công việc nhanh, ngắn. Rất không phù hợp với khối lượng công việc I / O chặn chậm, chạy lâu, ví dụ như khối lượng công việc liên quan đến việc gọi API HTTP.
  • Hoàn toàn đa luồng. Ngày nay, hệ sinh thái Ruby có hỗ trợ đa luồng tuyệt vời, do đó mô hình I / O này đã trở nên rất khả thi. Đa luồng cho phép đồng thời I / O cao, làm cho nó phù hợp cho cả khối lượng công việc I / O chặn ngắn và chạy dài. Lập trình viên có nhiều khả năng giới thiệu các lỗi đồng thời, nhưng may mắn là hầu hết các khung web được thiết kế theo cách mà điều này vẫn rất khó xảy ra. Tuy nhiên, một điều cần lưu ý là trình thông dịch MRI Ruby không thể tận dụng nhiều lõi CPU ngay cả khi có nhiều luồng, do sử dụng Khóa phiên dịch toàn cầu (GIL). Bạn có thể giải quyết vấn đề này bằng cách sử dụng nhiều quy trình đa luồng, vì mỗi quy trình có thể tận dụng lõi CPU. JRuby và Rubinius không có GIL, vì vậy họ hoàn toàn có thể tận dụng nhiều lõi trong một quy trình.
  • Lai đa luồng đa tiến trình. Chủ yếu được thực hiện bởi Phusion Pas Pas Enterprise 4 và sau đó. Bạn có thể dễ dàng chuyển đổi giữa nhiều tiến trình đơn luồng, hoàn toàn đa luồng hoặc thậm chí nhiều tiến trình mỗi luồng với nhiều luồng. Mô hình này cung cấp tốt nhất của cả hai thế giới.
  • Sự kiện. Mô hình này hoàn toàn khác với mô hình đã đề cập trước đó. Nó cho phép đồng thời I / O rất cao và do đó rất tuyệt vời cho khối lượng công việc I / O chặn lâu dài. Để sử dụng nó, cần có sự hỗ trợ rõ ràng từ ứng dụng và khung. Tuy nhiên, tất cả các khung chính như Rails và Sinatra không hỗ trợ mã sự kiện. Đây là lý do tại sao trong thực tế, một quy trình Thin vẫn không thể xử lý nhiều hơn 1 yêu cầu cùng một lúc, làm cho nó hoạt động hiệu quả giống như mô hình đa quy trình đơn luồng. Có các khung chuyên biệt có thể tận dụng lợi thế của I / O được tạo ra, chẳng hạn như Cramp.

Một bài viết gần đây đã được đăng trên blog Phusion về việc điều chỉnh tối ưu số lượng quy trình và chủ đề cho khối lượng công việc của bạn. Xem Cài đặt đồng thời của Điều chỉnh Phusion Hành khách .

Capistrano

Capistrano là một cái gì đó hoàn toàn khác nhau. Trong tất cả các phần trước, "triển khai" đề cập đến hành động khởi động ứng dụng Ruby của bạn trong máy chủ ứng dụng, để khách truy cập có thể truy cập được, nhưng trước khi điều đó có thể xảy ra, người ta thường cần thực hiện một số công việc chuẩn bị, chẳng hạn như:

  • Tải mã và tệp của ứng dụng Ruby lên máy chủ.
  • Cài đặt thư viện mà ứng dụng của bạn phụ thuộc vào.
  • Thiết lập hoặc di chuyển cơ sở dữ liệu.
  • Bắt đầu và dừng bất kỳ trình tiện ích nào mà ứng dụng của bạn có thể dựa vào, chẳng hạn như nhân viên Sidekiq / Resque hoặc bất cứ điều gì.
  • Bất kỳ điều gì khác cần phải được thực hiện khi bạn thiết lập ứng dụng của mình.

Trong ngữ cảnh của Capistrano, "triển khai" đề cập đến việc thực hiện tất cả công việc chuẩn bị này. Capistrano không phải là một máy chủ ứng dụng. Thay vào đó, nó là một công cụ để tự động hóa tất cả các công việc chuẩn bị. Bạn cho Capistrano biết máy chủ của bạn đang ở đâu và cần chạy lệnh nào mỗi khi bạn triển khai phiên bản mới của ứng dụng và Capistrano sẽ đảm nhiệm việc tải ứng dụng Rails lên máy chủ cho bạn và chạy các lệnh bạn đã chỉ định.

Capistrano luôn được sử dụng kết hợp với máy chủ ứng dụng. Nó không thay thế các máy chủ ứng dụng. Ngược lại, các máy chủ ứng dụng không thay thế Capistrano, chúng có thể được sử dụng kết hợp với Capistrano.

Tất nhiên bạn không phải sử dụng Capistrano. Nếu bạn muốn tải lên ứng dụng Ruby của mình bằng FTP và chạy thủ công các bước lệnh giống nhau mỗi lần, thì bạn có thể làm điều đó. Những người khác đã mệt mỏi với nó, vì vậy họ tự động hóa các bước đó trong Capistrano.


74
Bạn nên xuất bản này ở đâu đó. Bây giờ tất cả đều dễ dàng nhưng khi tôi mới bắt đầu với đường ray, thật khó để có được bất kỳ thông tin hữu ích nào.
spegoraro

9
Bài đăng tuyệt vời! Dọn dẹp rất nhiều cho tôi quá. Bạn nên thêm một số yếu tố khác như bundler và rvm và làm cho nó trở thành một bài đăng blog nặng nề! :)
Damien Roche

37
Điều này cần phải có trong hướng dẫn Rails.
Dorian

4
"Không ai sử dụng WEBrick trong môi trường sản xuất." Điều này là không đúng sự thật cả. Máy chủ ứng dụng mặc định khi đẩy các ứng dụng ruby ​​lên heroku là webrick.
John Downey

37
@Hongli Bài này rất thuận lợi cho Phusion Pas Pas. Có lẽ sẽ là khôn ngoan khi thêm liên kết của bạn vào dự án (CTO, phusion.nl/about ) vì mục đích khách quan?
Bert Goethals 18/03/13 lúc
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.