<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Jaros&#322;aw Zabie&#322;&#322;o - BLOG: Szybszy, asynchroniczny Mongrel z EventMachine lub Swiftiply</title>
    <link>http://blog.zabiello.com/articles/2007/12/24/event-mongrel</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>moje notatki, linki, komentarze</description>
    <item>
      <title>Szybszy, asynchroniczny Mongrel z EventMachine lub Swiftiply</title>
      <description>&lt;p&gt;Du&#380;o si&#281; zmieni&#322;o od czasu zalecania u&#380;ywania Rails&#243;w w trybie FastCGI. To si&#281; nie sprawdzi&#322;o i miejsce zestawu Lighttpd + FastCGI zaj&#261;&#322; Apache2/Nginx + proxy do Mongrel clustera. Z Mongrel clusterem jest jednak problem, &#380;e nie dzia&#322;a poza systemami uniksowymi. Poza tym uda&#322;o mi si&#281; zaobserwowa&#263; kilka razy pewn&#261; niestabilno&#347;&#263; dla mongrel clustera: czasami pojedynczy Mongrel si&#281; zawiesi i trzeba restartowa&#263; ca&#322;y ich klaster. Wi&#281;ksz&#261; stabilno&#347;&#263; i du&#380;o wi&#281;ksz&#261; wydajno&#347;&#263; (szczeg&#243;lnie przy wielu r&#243;wnoleg&#322;ych &#380;&#261;daniach) zapewnia&#263; Mongrel dzia&#322;aj&#261;cy z &lt;a href="http://swiftiply.swiftcore.org/"&gt;Swiftiply&lt;/a&gt; lub z &lt;a href="http://rubyeventmachine.com/"&gt;EventMachine&lt;/a&gt;.&lt;/p&gt;


	&lt;h3&gt;Swiftiply&lt;/h3&gt;


	&lt;p&gt;&lt;a href="http://swiftiply.swiftcore.org/"&gt;Swiftiply&lt;/a&gt; jest reklamowany jako klasterowy proxy dla aplikacji internetowych. Korzysta z trwa&#322;ych po&#322;&#261;cze&#324; z klientami i mo&#380;na go skalowa&#263; bez zmian w konfiguracji i restart&#243;w. Po prostu podpina si&#281; kolejny Mongrel z kolejnego komputera do tego samego adresu IP i zostaje automatycznie w&#322;&#261;czony do p&#281;tli obs&#322;ugi zdarze&#324;. Dzi&#281;ki Ezrze Zygmuntowiczowi, gem Swiftiply udost&#281;pnia te&#380; gotowy, przerobiony Mongrel dzia&#322;aj&#261;cy zar&#243;wno z Swiftiply jak i EventMachine. Sam serwer Swiftiply mo&#380;e dzia&#322;a&#263; w og&#243;le bez zewn&#281;trznego serwera &lt;span class="caps"&gt;HTTP&lt;/span&gt;, ale ci co ceni&#261; sobie max. wydajno&#347;&#263; pewnie i tak b&#281;d&#261; chcieli na froncie postawi&#263; szybkiego &lt;a href="http://nginx.net"&gt;Nginxa&lt;/a&gt;. Wystarczy spi&#261;&#263; go przez mod_proxy do jednego (sic!) Mongrela odpalonego w trybie Swiftiply.&lt;/p&gt;


	&lt;h3&gt;EventMachine&lt;/h3&gt;


	&lt;p&gt;&lt;a href="http://rubyeventmachine.com/"&gt;EventMachine&lt;/a&gt; to biblioteka napisana w C dla program&#243;w Rubiego, Javy i C++.  S&#322;u&#380;y do obs&#322;ugi zdarze&#324; w spos&#243;b &lt;strong&gt;asynchroniczny&lt;/strong&gt; zamiast wielow&#261;tkowy (podobnie jak to robi pythonowy &lt;a href="http://twistedmatrix.com"&gt;Twisted&lt;/a&gt;). EventMachine jest bibliotek&#261; bardzo szybk&#261;. Serwer pracuj&#261;cy asynchronicznie nie wpada w blokady i jest cz&#281;sto szybszy od serwer&#243;w pracuj&#261;cych wielow&#261;tkowo.&lt;/p&gt;


	&lt;p&gt;Zamiast tworzy&#263; wiele proces&#243;w Mongrela aby zapewni&#263; r&#243;wnoleg&#322;&#261; prac&#281; dla Rails, wystarczy odpali&#263; &lt;strong&gt;jeden&lt;/strong&gt; (sic!) proces Mongrela asynchronicznego. Asynchroniczny Mongrel dzia&#322;a zar&#243;wno z Railsami jaki &lt;a href="http://merbivore.com/"&gt;Merbem&lt;/a&gt;. Nie musz&#281; m&#243;wi&#263;, jakie s&#261; oszcz&#281;dno&#347;ci na pami&#281;ci w por&#243;wnaniu do klastra proces&#243;w Mongrela kt&#243;ry zwykle zaleca si&#281; u&#380;ywa&#263; dla Rails&#243;w! Z prostych test&#243;w por&#243;wnawczych wysz&#322;o mi &#380;e Mongrel asynchroniczny jest jakie&#347; dwa razy szybszy od Mongrela wielow&#261;tkowego. (Zobacz te&#380; &lt;a href="http://journal.andrewloe.com/2007/5/22/mongrel-vs-evented-mongrel"&gt;Mongrel vs Evented Mongrel&lt;/a&gt;)&lt;/p&gt;


	&lt;h3&gt;Jak to skonfigurowa&#263;?&lt;/h3&gt;


	&lt;p&gt;Po zainstalowaniu gemu Swiftiply stary skrypt &lt;code&gt;mongrel_rails&lt;/code&gt; zostaje zast&#261;piony nowszym (ale tak, &#380;e jest zgodny ze starym mongrelem wielow&#261;tkowym). Sterowanie trybem pracy dokonywane jest przez ustawienie stosownej &lt;em&gt;zmiennej &#347;rodowiskowej&lt;/em&gt;. Np. aby odpali&#263; Mongrela w trybie asynchronicznym wystarczy napisa&#263;&lt;/p&gt;


&lt;script:typo lang="bash"&gt;
&lt;span class="caps"&gt;EVENT&lt;/span&gt;=1 mongrel_rails start
&lt;/script:typo&gt;

	&lt;p&gt;Poni&#380;ej prosty skrypt startuj&#261;cy jaki napisa&#322;em dla Ubuntu (wszystkie opcje wy&#347;wietli polecenie &lt;code&gt;mongrel_rails&lt;/code&gt; start -h@)&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="comment"&gt;#!/usr/bin/ruby&lt;/span&gt;

&lt;span class="constant"&gt;ADDR&lt;/span&gt;&lt;span class="punct"&gt;='&lt;/span&gt;&lt;span class="string"&gt;127.0.0.1&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt; 
&lt;span class="constant"&gt;PORT&lt;/span&gt;&lt;span class="punct"&gt;=&lt;/span&gt;&lt;span class="number"&gt;7100&lt;/span&gt;
&lt;span class="comment"&gt;# &#346;cie&#380;ka do projektu RoR:&lt;/span&gt;
&lt;span class="constant"&gt;ROOT&lt;/span&gt;&lt;span class="punct"&gt;='&lt;/span&gt;&lt;span class="string"&gt;/home/app/rails/homepage/current&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;

&lt;span class="constant"&gt;PID&lt;/span&gt;&lt;span class="punct"&gt;=&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&lt;span class="expr"&gt;#{ROOT}&lt;/span&gt;/log/blog.pid&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="constant"&gt;USER&lt;/span&gt;&lt;span class="punct"&gt;='&lt;/span&gt;&lt;span class="string"&gt;www-data&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="constant"&gt;GROUP&lt;/span&gt;&lt;span class="punct"&gt;='&lt;/span&gt;&lt;span class="string"&gt;www-data&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="constant"&gt;APPL&lt;/span&gt;&lt;span class="punct"&gt;='&lt;/span&gt;&lt;span class="string"&gt;/usr/bin/mongrel_rails&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
&lt;span class="ident"&gt;cmd_start&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;env EVENT=1 &lt;span class="expr"&gt;#{APPL}&lt;/span&gt; start -a &lt;span class="expr"&gt;#{ADDR}&lt;/span&gt; -p &lt;span class="expr"&gt;#{PORT}&lt;/span&gt; --user &lt;span class="expr"&gt;#{USER}&lt;/span&gt; --group &lt;span class="expr"&gt;#{GROUP}&lt;/span&gt; -P &lt;span class="expr"&gt;#{PID}&lt;/span&gt; -e production -d&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt; 
&lt;span class="ident"&gt;cmd_stop&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;&lt;span class="expr"&gt;#{APPL}&lt;/span&gt; stop -P &lt;span class="expr"&gt;#{PID}&lt;/span&gt;&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;

&lt;span class="ident"&gt;curdir&lt;/span&gt; &lt;span class="punct"&gt;=&lt;/span&gt; &lt;span class="constant"&gt;Dir&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;pwd&lt;/span&gt;
&lt;span class="constant"&gt;Dir&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;chdir&lt;/span&gt; &lt;span class="constant"&gt;ROOT&lt;/span&gt;

&lt;span class="keyword"&gt;case&lt;/span&gt; &lt;span class="constant"&gt;ARGV&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;first&lt;/span&gt;
&lt;span class="keyword"&gt;when&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;start&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
  &lt;span class="ident"&gt;system&lt;/span&gt; &lt;span class="ident"&gt;cmd_start&lt;/span&gt;
&lt;span class="keyword"&gt;when&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;stop&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
  &lt;span class="ident"&gt;system&lt;/span&gt; &lt;span class="ident"&gt;cmd_stop&lt;/span&gt; &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="constant"&gt;File&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;exists?&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;PID&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
&lt;span class="keyword"&gt;when&lt;/span&gt; &lt;span class="punct"&gt;'&lt;/span&gt;&lt;span class="string"&gt;restart&lt;/span&gt;&lt;span class="punct"&gt;'&lt;/span&gt;
  &lt;span class="ident"&gt;system&lt;/span&gt; &lt;span class="ident"&gt;cmd_stop&lt;/span&gt; &lt;span class="keyword"&gt;if&lt;/span&gt; &lt;span class="constant"&gt;File&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;exists?&lt;/span&gt;&lt;span class="punct"&gt;(&lt;/span&gt;&lt;span class="constant"&gt;PID&lt;/span&gt;&lt;span class="punct"&gt;)&lt;/span&gt;
  &lt;span class="ident"&gt;system&lt;/span&gt; &lt;span class="ident"&gt;cmd_start&lt;/span&gt;
&lt;span class="keyword"&gt;else&lt;/span&gt;
  &lt;span class="ident"&gt;puts&lt;/span&gt; &lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;&lt;span class="string"&gt;Usage: sudo &lt;span class="expr"&gt;#{__FILE__}&lt;/span&gt; {start|stop|restart}&lt;/span&gt;&lt;span class="punct"&gt;&amp;quot;&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="constant"&gt;Dir&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;chdir&lt;/span&gt; &lt;span class="ident"&gt;curdir&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Jeszcze tylko komenda&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_bash "&gt;cd /etc/init.d
update-rc.d -f mogrel_home.rb defaults&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;i Ubuntu b&#281;dzie automatycznie ten skrypt uruchamia&#322; podczas restartu maszyny.&lt;/p&gt;


	&lt;p&gt;Odno&#347;nie Nginxa to nie trzeba wiele zmienia&#263; poza tym, aby skierowa&#263; proxy na jeden port (w tym wypadku 7100)&lt;/p&gt;


&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_nginx "&gt;upstream mongrel_blog {
  server 127.0.0.1:7100;
}

server {
  # ... inne opcje
  location / {
    proxy_set_header  X-Real-IP  $remote_addr;
    proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_redirect false;
    # ... reszta opcji
    if (!-f $request_filename) {
      proxy_pass http://mongrel_blog;
      break;
    }
  }
}&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;Stary &lt;code&gt;mongrel_cluster&lt;/code&gt; doczeka&#322; si&#281; konkurencji w postaci gema &lt;a href="http://rubyforge.org/projects/mongrel-cow/"&gt;mongrel_cow_cluster&lt;/a&gt; kt&#243;ry r&#243;wnie&#380; powinien szybciej dzia&#322;a&#263; od mongrel_cluster&amp;#8217;a. Nawet zwolennicy Webricka mog&#261; sobie doinstalowa&#263; co&#347; szybszego od domy&#347;lnego Webricka &amp;#8211; forkowy &lt;code&gt;webrick-high-performance&lt;/code&gt; (tylko systemy uniksowe). Ale wydaje mi si&#281;, &#380;e najlepszym rozwi&#261;zaniem jest Mongrel asynchroniczny.&lt;/p&gt;


	&lt;p&gt;Zobacz te&#380; entuzjastyczn&#261; opini&#281; &lt;a href="http://brainspl.at/articles/2007/05/12/event-driven-mongrel-and-swiftiply-proxy"&gt;Ezry Zygmuntowicza o event Mongrelu i o  Swiftiply&lt;/a&gt;.&lt;/p&gt;</description>
      <pubDate>Mon, 24 Dec 2007 14:21:00 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:86233fa6-a48d-492a-b8a2-4240d144349b</guid>
      <author>Jaros&#322;aw Zabie&#322;&#322;o</author>
      <link>http://blog.zabiello.com/articles/2007/12/24/event-mongrel</link>
      <category>switiply</category>
      <category>mongrel</category>
      <category>eventmachine</category>
      <category>asynchronic</category>
      <category>rails</category>
      <category>ruby</category>
    </item>
    <item>
      <title>"Szybszy, asynchroniczny Mongrel z EventMachine lub Swiftiply" by Jaros&#322;aw Zabie&#322;&#322;o</title>
      <description>&lt;p&gt;@exor: Mia&#322;em co&#347; podobnego, nie wiem czy to samo. Pojedy&#324;cze mongrele czasem pada&#322;y w clusterze, znika&#322;y procesy. W efekcie, przy zastosowanym load balancingu, na kilka request&#243;w niekt&#243;re wywala&#322;y b&#322;&#261;d.&lt;/p&gt;</description>
      <pubDate>Fri, 11 Apr 2008 01:37:53 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:d3de9894-7024-4438-9ecb-7b408c5825d0</guid>
      <link>http://blog.zabiello.com/articles/2007/12/24/event-mongrel#comment-1557</link>
    </item>
    <item>
      <title>"Szybszy, asynchroniczny Mongrel z EventMachine lub Swiftiply" by exor</title>
      <description>&lt;p&gt;No wlasnie, piszesz, ze tandem apache+mod_proxy+mongrel_cluster sie nie sprawdzil? Co sie dzialo? Wieszal sie?&lt;/p&gt;


	&lt;p&gt;Bo chyba mam to samo &amp;#8211; po restarcie mongrel_cluster wszystko jest ok, ale tak przez pare godzin&amp;#8230; Potem apache sie nie moze podlaczyc do zadnego z trzech uruchomionych mongreli. Netstat pokazuje caly czas otwarte porty.&lt;/p&gt;


	&lt;p&gt;Czy taki sam efekt miales?&lt;/p&gt;


	&lt;p&gt;Pzdr.&lt;/p&gt;</description>
      <pubDate>Mon, 07 Apr 2008 22:10:16 +0200</pubDate>
      <guid isPermaLink="false">urn:uuid:df09c1b4-72aa-4713-ab9c-64b26b05ad53</guid>
      <link>http://blog.zabiello.com/articles/2007/12/24/event-mongrel#comment-1552</link>
    </item>
    <item>
      <title>"Szybszy, asynchroniczny Mongrel z EventMachine lub Swiftiply" by wypas</title>
      <description>&lt;p&gt;a ten wynalazek?&lt;/p&gt;


	&lt;p&gt;&lt;a href="http://www.rubyinside.com/thin-a-ruby-http-daemon-thats-faster-than-mongrel-688.html" rel="nofollow"&gt;http://www.rubyinside.com/thin-a-ruby-http-daemon-thats-faster-than-mongrel-688.html&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;?? jest jeszcze szybszy podobno :)&lt;/p&gt;</description>
      <pubDate>Mon, 07 Jan 2008 19:34:38 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:10368ae0-95ff-4e7c-83e1-c2ac55dc4a9a</guid>
      <link>http://blog.zabiello.com/articles/2007/12/24/event-mongrel#comment-1348</link>
    </item>
    <item>
      <title>"Szybszy, asynchroniczny Mongrel z EventMachine lub Swiftiply" by iddqd</title>
      <description>&lt;p&gt;Widz&#281;, &#380;e jeste&#347; entuzjast&#261; Ruby. To co piszesz bardzo fajnie si&#281; czyta ale na Twoim miejscu by&#322;bym ostro&#380;niejszy w opisywaniu technologii. Mongrel/Swiftiply s&#261; bardzo niestabilne przy du&#380;ych obci&#261;&#380;eniach (idle ~5%) i je&#347;li kto&#347; je u&#380;yje na podstawie takich entuzjastycznych tekst&#243;w mo&#380;e &#322;adnie si&#281; naci&#261;&#263;.&lt;/p&gt;


	&lt;p&gt;Pozdrawiam.&lt;/p&gt;</description>
      <pubDate>Fri, 04 Jan 2008 12:58:40 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:c115b683-4dca-4ff6-8ecb-a73bc1764db3</guid>
      <link>http://blog.zabiello.com/articles/2007/12/24/event-mongrel#comment-1330</link>
    </item>
    <item>
      <title>"Szybszy, asynchroniczny Mongrel z EventMachine lub Swiftiply" by Jaros&#322;aw Zabie&#322;&#322;o</title>
      <description>&lt;p&gt;Musia&#322;em troch&#281; przebudowa&#263; tre&#347;&#263; artyku&#322;u, bo by&#322; troch&#281; niejasny i wkrad&#322;y si&#281; b&#322;&#281;dy w listingu.&lt;/p&gt;</description>
      <pubDate>Mon, 31 Dec 2007 05:18:11 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:27ab005f-35d8-4f13-820d-26e0dd7cd9ef</guid>
      <link>http://blog.zabiello.com/articles/2007/12/24/event-mongrel#comment-1328</link>
    </item>
    <item>
      <title>"Szybszy, asynchroniczny Mongrel z EventMachine lub Swiftiply" by Jaros&#322;aw Zabie&#322;&#322;o</title>
      <description>&lt;p&gt;A co to za test &amp;#8220;wpisa&#263; urla&amp;#8221;? :) Zapu&#347;&#263; przynajmniej &lt;code&gt;ab -n 1000 -c 10&lt;/code&gt; albo co&#347; podobnego. Ezra stwierdza &#380;e event Mongrel chodzi nie tylko wyra&#378;nie szybciej ale i zu&#380;ywa te&#380; mniej pami&#281;ci. Nie wiem jak du&#380;y zysk jest w RoR, ale w Merb jest spory.&lt;/p&gt;</description>
      <pubDate>Wed, 26 Dec 2007 14:16:34 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:977b64c2-2994-4d2e-b1d8-502537b96465</guid>
      <link>http://blog.zabiello.com/articles/2007/12/24/event-mongrel#comment-1322</link>
    </item>
    <item>
      <title>"Szybszy, asynchroniczny Mongrel z EventMachine lub Swiftiply" by comboy</title>
      <description>&lt;p&gt;Spr&#243;bowa&#322;em. W por&#243;wnnaiu do zwyk&#322;ego, pojedy&#324;czego mongrela wydaje si&#281; wolniejszy. Chodzi o to &#380;e po w pisaniu urla trzeba by&#322;o czeka&#263; nawet sekunde dwie zanim co&#347; wog&#243;le zacz&#281;&#322;o si&#281; dzia&#263;. Nie prowadzi&#322;em &#380;adnych benchmark&#243;w, w logach req/sec si&#281; zbytnio nie zmieni&#322;y, ale to wra&#380;enie dla odwiedzaj&#261;cego wydaje mi si&#281; gorsze.&lt;/p&gt;</description>
      <pubDate>Wed, 26 Dec 2007 11:37:42 +0100</pubDate>
      <guid isPermaLink="false">urn:uuid:05669ea1-f532-4932-85df-1a01175a6f19</guid>
      <link>http://blog.zabiello.com/articles/2007/12/24/event-mongrel#comment-1320</link>
    </item>
  </channel>
</rss>
