Ruby on Rails - Apache - Mongrel
Zrobiłeś właśnie swoją super-hiper-wybajerzoną aplikację w Ruby on Rails i chcesz ją udostępnić szerokiemu światu. Problemem jest wąskie gardło w postaci serwera Webrick będącego częścią Railsów. Można temu zaradzić trzyetapowo:
- Należy zastąpić Webrick czymś wydajniejszym.
- Należy zdjąć obowiązek serwowania plików statycznych (np statycznych obrazków, styli) z serwera Railsowego.
- Należy rozłożyć obciążenie na kilka serwerów Railsowych
W dalszym tekście zakładam, że masz zainstalowane i działające Ruby on Rails i apache2.
[edytuj] Serwer mongrel
Na początek trzeba zastąpić Webricka silniejszym narzędziem. Polecam serwer Mongrel ze względu na fakt, że jest częściowo w kodzie natywnym (moduły w C), przez co jest całkiem wydajny.
Instalujemy go tak (Gem mongrel_cluster pozwala zarządzać kilkoma serwerami naraz):
~ # gem install mongrel mongrel_cluster -y Need to update 14 gems from http://gems.rubyforge.org .............. complete Select which gem to install for your platform (x86_64-linux) 1. mongrel 1.0.1 (mswin32) 2. mongrel 1.0.1 (ruby) 3. mongrel 1.0 (mswin32) 4. mongrel 1.0 (ruby) .... > 2 [wybierasz najwyższą wersję "(ruby)"] Building native extensions. This could take a while... ruby extconf.rb install mongrel mongrel_cluster rails -y checking for main() in -lc... yes creating Makefile ... Successfully installed mongrel-1.0.1 Installing ri documentation for mongrel-1.0.1... Installing RDoc documentation for mongrel-1.0.1... Successfully installed mongrel_cluster-1.0.2 ~ # mkdir /etc/mongrel_cluster
Czasami mongrel chce doinstalować jeszcze kilka gemów, wybieraj zawsze wersję najwyższą typu "ruby".
Teraz należy przygotować odpowiedniego użytkownika i uprawnienia dla niego:
~ # addgroup --system rails Dodawanie grupy `rails' (GID 129)... Gotowe. ~ # adduser --system --home /var/www/rails --shell /bin/bash \ --disabled-password --ingroup rails rails Dodawanie użytkownika systemowego `rails' (UID 120)... Dodawanie nowego użytkownika `rails' (UID 120) w grupie `rails'... Tworzenie katalogu domowego `/var/www/rails'... ~ # id rails uid=120(rails) gid=129(rails) grupy=129(rails)
Mamy teraz użytkownika rails w grupie rails, na którego nie można się zalogować bezpośrednio (względy bezpieczeństwa), ale z konta administratora można przelogować się tak:
~ # su - rails ~ $ whoami rails ~ $ pwd /var/www/rails
Możemy teraz wygenerować (ciągle jako użytkownik rails) prosty szkielet testowy:
~ $ mkdir static
~ $ rails test
create
create app/controllers
create app/helpers
create app/models
create app/views/layouts
...
create log/development.log
create log/test.log
~ $ ls
static test
Teraz uruchamiamy to pod serwerem (zwróć uwagę, że uruchamia się już pod kontrolą mongrela! Magia rubiego działa!):
~ $ cd test ~/test $ script/server => Booting Mongrel (use 'script/server webrick' to force WEBrick) => Rails application starting on http://0.0.0.0:3000 => Call with -d to detach => Ctrl-C to shutdown server ** Starting Mongrel listening at 0.0.0.0:3000 ** Starting Rails with development environment... ** Rails loaded. ** Loading any Rails specific GemPlugins ** Signals ready. TERM => stop. USR2 => restart. INT => stop (no restart). ** Rails signals registered. HUP => reload (without restart). It might not work well. ** Mongrel available at 0.0.0.0:3000 ** Use CTRL-C to stop.
W tej chwili możesz sprawdzić działanie aplikacji wysyłając swoją przeglądarkę WWW na adres http://localhost:3000 (czy inny wskazany na zgłoszeniu mongrela - pamiętając, żeby zamienić adres 0.0.0.0 na localhost). Po sprawdzeniu (powinna pokazać się strona powitalna serwera railsowego) naciśnij Ctrl-C aby wyłączyć serwer.
[edytuj] Loadalancing
[edytuj] Klaster mongrela
Problemem mongrela jest to, że nie jest wielowątkowy i nie przyjmuje nowego zapytania przed ukończeniem poprzedniego. Przy małych obciążeniach (kilka zapytań na sekundę) jest to akceptowalne, natomiast przy dużych już nie. Rozwiązaniem jest klaster kilku serwerów (nawet fizycznie na tym samym komputerze) dzielących się zadaniami.
Na początek trzeba przygotować serwery mongrela (polecenia należy wykonywać dalej z poziomu użytkownika rails):
~/test $ mongrel_rails cluster::configure -e production \ -p 4000 -a 127.0.0.1 -N 3 -c `pwd` --user rails --group rails Writing configuration file to config/mongrel_cluster.yml.
Powyższy zapis oznacza tyle:
- Klaster będzie chodził z ustawieniami 'production' (możesz na wstępie dać zamiast tego 'development')
- Będzie słuchał na adresie 127.0.0.1 (localhost)
- Będą uruchomione 3 serwery od portu 4000 w górę
- Serwer będzie uruchomiony jako użytkownik 'rails' w grupie 'rails'.
Czysto i bezpiecznie
Teraz trzeba wrócić do trybu administratora i podlinkować nowy plik konfiguracyjny do katalogu konfiguracyjnego klastra:
~/test $ naciścnij CTRL-D ~ # ln -s /var/www/rails/test/config/mongrel_cluster.yml /etc/mongrel_cluster/test.yml ~ # ls /etc/mongrel_cluster test.yml
Testujemy wszystko wydając następujące polecenia:
# mongrel_cluster_ctl start Starting all mongrel_clusters... # mongrel_cluster_ctl status Checking all mongrel_clusters... mongrel_rails cluster::status -C test.yml found pid_file: tmp/pids/mongrel.4000.pid found mongrel_rails: port 4000, pid 20708 found pid_file: tmp/pids/mongrel.4001.pid found mongrel_rails: port 4001, pid 20711 found pid_file: tmp/pids/mongrel.4002.pid found mongrel_rails: port 4002, pid 20714
Można sprawdzić poprawność łącząc się z którymkolwiek z serwerów: http://localhost:4000, http://localhost:4001 bądź http://localhost:4002
po sprawdzeniu możesz wyłączyć klaster komendą
# mongrel_cluster_ctl stop Stopping all mongrel_clusters... # mongrel_cluster_ctl status Checking all mongrel_clusters... mongrel_rails cluster::status -C test.yml missing pid_file: tmp/pids/mongrel.4000.pid missing mongrel_rails: port 4000 missing pid_file: tmp/pids/mongrel.4001.pid missing mongrel_rails: port 4001 missing pid_file: tmp/pids/mongrel.4002.pid missing mongrel_rails: port 4002
[edytuj] Serwer apache
Teraz klaster trzeba pokazać jako jeden serwer za pomocą Apache2. Wszystkie potrzebne moduły masz już zainstalowane, przy okazji instalacji samego serwera. Trzeba je tylko włączyć:
# for mod in rewrite proxy proxy_http proxy_balancer; do a2enmod $mod ; done Module rewrite installed; run /etc/init.d/apache2 force-reload to enable. Module proxy installed; run /etc/init.d/apache2 force-reload to enable. Module proxy_http installed; run /etc/init.d/apache2 force-reload to enable. Module proxy_balancer installed; run /etc/init.d/apache2 force-reload to enable.
Teraz musisz napisać stosowny plik konfiguracyjny do apache'a w katalogu /etc/apache2/sites-available. Nazwij go rails:
# Adres IP, ilość i porty zgodne z naszym klastrem mongrela. <Proxy balancer://mongrel_cluster> BalancerMember http://127.0.0.1:4000 BalancerMember http://127.0.0.1:4001 BalancerMember http://127.0.0.1:4002 </Proxy> # Robimy wirtualny host <VirtualHost *> # Będziemy się odwoływać do niego przez http://rails ServerName rails # Ścieżka do naszej aplikacji railsowej, do jej podkatalogu public DocumentRoot /var/www/rails/test/public # Robimy osobne pliki logów ErrorLog /var/log/apache2/error_rails.log CustomLog /var/log/apache2/access_rails.log common # Dajemy odpowiednie ustawnienia - wyłączając między innymi # domyślny railsowy .htaccess, teraz już niepotrzebny <Directory "/var/www/rails/test/public"> Options FollowSymLinks AllowOverride None Order allow,deny Allow from all </Directory> # Włączamy przepisywajkę adresów RewriteEngine On # Jak wyłączasz mongrela, daj info w pliku /system/maintenance.html. # Apache wyświetli tą stronę jako info zamiast dowolnego adresu z serwisu # (taki sprytny catch-all) RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f RewriteCond %{SCRIPT_FILENAME} !maintenance.html RewriteRule ^.*$ /system/maintenance.html [L] # Zabawy z keszami RewriteRule ^/$ /index.html [QSA] RewriteRule ^([^.]+)$ $1.html [QSA] # No i najważniejsze - pliki które są FIZYCZNIE na dysku są serwowane # przez apacza z pominięciem Railsów. Railsy obsługują tylko wywołania # do ścieżek nie istniejących fizycznie na dysku RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f RewriteRule ^/(.*)$ balancer://mongrel_cluster%{REQUEST_URI} [P,QSA,L] </virtualHost>
Jeszcze tylko trzeba włączyć naszego site'a w apaczu i dodać wpis w /etc/hosts:
~ # a2ensite rails Site rails installed; run /etc/init.d/apache2 reload to enable. ~ # echo 127.0.0.1 rails >> /etc/hosts
[edytuj] Test
Nadszedł czas uruchomienia wszystkiego razem:
~ # mongrel_cluster_ctl start Starting all mongrel_clusters... ~ # /etc/init.d/apache2 restart * Forcing reload of web server (apache2)... [ OK ]
Teraz wklep w przeglądarce http://rails i powinien pojawić się ekran powitalny railsów serwowanych przez indianina z kilku kociołków naraz.
Pozdrawiam!
- Wersja do wydruku
- Odpowiedz
- 618 odsłon
- Wersja PDF


Ostatnie odpowiedzi
5 dni 15 godzin temu
5 dni 20 godzin temu
1 tydzień 2 dni temu
8 tygodni 5 godzin temu
8 tygodni 1 dzień temu