Miles to go …

June 16, 2009

TOTD #84: Using Apache + mod_proxy_balancer to load balance Ruby-on-Rails running on GlassFish

Filed under: web2.0 — arungupta @ 11:00 pm

TOTD #81 explained how to install/configure nginx for load-balancing/front-ending a cluster of Rails application running on GlassFish Gem. Another popular approach in the Rails community is to use Apache HTTPD + mod_proxy_balancer. A user asked the exact details of this setup on the GlassFish Gem Forum. This Tip Of The Day (TOTD) will clearly explain the steps.

  1. Create a simple Rails scaffold and run this application using GlassFish Gem on 3 separate ports as explained in TOTD #81.
  2. Setup and configure HTTPD and mod_proxy_balancer
    1. Setup and install Apache HTTPD as explained here. I believe mod_proxy_balancer and other related modules comes pre-bundled with HTTPD, at least that’s what I observed with Mac OS X 10.5.7. Make sure that the “mod_proxy_balancer” module is enabled by verifying the following line is uncommented in “/etc/apache2/httpd.conf”:

      LoadModule proxy_balancer_module libexec/apache2/mod_proxy_balancer.so

      Please note another similar file exists in “/etc/httpd/httpd.conf” but ignore that one.

    2. Setup a mod_proxy_balancer cluster by adding the following fragment in “httpd.conf” as:
      <Proxy balancer://glassfishgem>
      BalancerMember http://localhost:3000
      BalancerMember http://localhost:3001
      BalancerMember http://localhost:3002
      </Proxy>

      The port numbers must exactly match with those used in the first step.

    3. Specify the ProxyPass directives to map the cluster to a local path as:
      ProxyPass / balancer://glassfishgem/
      CustomLog /var/log/glassfishgem.log/apache_access_log combined

      The “/” at the end of “balancer://glassfishgem” is very important to ensure that all the files are resolved correctly.

    4. Optionally, the following directive can be added to view the access log:
      CustomLog /var/log/glassfishgem.log/apache_access_log combined

      Make sure to create the directory specified in “CustomLog” directive.

  3. Now the application is accessible at “http://localhost/runlogs”. If a new GlassFish instance is started then update the <Proxy> directive and restart your HTTPD as “sudo httpd -k restart”. Dynamic update of BalancerMembers can be configured as explained here.

TOTD #81 started the Rails application in root context. You can alternatively start the application in a non-root context as:

~/tools/jruby/rails/runner >../../bin/jruby -S glassfish -e production -c myapp
Starting GlassFish server at: 10.0.177.178:3000 in production environment…
Writing log messages to: /Users/arungupta/tools/jruby-1.3.0/rails/runner/log/production.log.
Press Ctrl+C to stop.
. . .
~/tools/jruby/rails/runner >../../bin/jruby -S glassfish -e production -c myapp -p 3001
Starting GlassFish server at: 10.0.177.178:3001 in production environment…
Writing log messages to: /Users/arungupta/tools/jruby-1.3.0/rails/runner/log/production.log.
Press Ctrl+C to stop.
. . .
~/tools/jruby/rails/runner >../../bin/jruby -S glassfish -e production -c myapp -p 3002
Starting GlassFish server at: 10.0.177.178:3002 in production environment…
Writing log messages to: /Users/arungupta/tools/jruby-1.3.0/rails/runner/log/production.log.
Press Ctrl+C to stop.

and then the ProxyPass directive will change to:

ProxyPass /myapp/ balancer://glassfishgem/myapp/

The changes are highlighted in bold. And the application is now accessible at “http://localhost/myapp/runlogs”.

After discussing on Apache HTTP Server forum, the BalancerMember host/port can be printd in the log file using a custom log format. So add the following log format to “/etc/apache2/httpd.conf”:

LogFormat “%h %l %u %t \”%r\” %>s %b \”%{Referer}i\” \”%{User-agent}i\” \”%{BALANCER_WORKER_NAME}e\”" custom

And change the format from the default “combined” to the newly defined “custom” format as:

CustomLog /var/log/glassfishgem.com/apache_access_log custom

Three subsequent invocations of “http://localhost/runlogs” then prints the following log entries:

::1 – - [17/Jun/2009:10:53:53 -0700] “GET /runlogs HTTP/1.1″ 304 – “-” “Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.0.11) Gecko/2009060214 Firefox/3.0.11″ “http://localhost:3002″
::1 – - [17/Jun/2009:10:54:04 -0700] “GET /runlogs HTTP/1.1″ 200 621 “-” “Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.0.11) Gecko/2009060214 Firefox/3.0.11″ “http://localhost:3000″
::1 – - [17/Jun/2009:10:54:05 -0700] “GET /runlogs HTTP/1.1″ 304 – “-” “Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.0.11) Gecko/2009060214 Firefox/3.0.11″ “http://localhost:3001″

As evident from the last fragment of each log line, the load is distributed amongst three GlassFish Gem instances. More details on load balancer algorithm are available here.

Feel free to d
rop a comment on this blog if you are using GlassFish in production for your Rails applications. Several stories are already available at rubyonrails+glassfish+stories.

Technorati: glassfish rubyonrails apache httpd mod_proxy_balancer loadbalancing clustering

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • DZone
  • StumbleUpon
  • Technorati
  • Twitter
  • Slashdot
Related posts:
  1. TOTD #81: How to use nginx to load balance a cluster of GlassFish Gem ?
  2. Track your running miles using JRuby, Ruby-on-Rails, GlassFish, NetBeans, MySQL, and YUI Charts
  3. TOTD #37: SQLite3 with Ruby-on-Rails on GlassFish Gem
  4. TOTD #104: Popular Ruby-on-Rails applications on GlassFish v3 – Redmine, Typo, Substruct
  5. TOTD #44: JDBC Connection Pooling for Rails on GlassFish v3

4 Comments »

  1. Hi Arun
    Found your blog very useful. But one error we are getting is in log files the env variable BALANCER_WORKER_NAME is not printing. Have you faced any such issues ?

    Thanks
    Manoj

    Comment by Manoj — June 18, 2009 @ 9:16 pm

  2. Manoj, It worked for after making the appropriate change. Are you restarting your HTTPD server after changing the log format ?

    Feel free to follow up on the Apache HTTP server forum at:

    http://www.nabble.com/Backend-host-port-in-the-log-td24003433.html

    Comment by Arun Gupta — July 2, 2009 @ 9:40 am

  3. [Trackback] The GlassFish High Availability allows to setup a cluster of GlassFish instances and achieve highly scalable architecture using in-memory session state replication. This cluster can be very easily created and tested using the "clusterjsp" sample bundl…

    Comment by Arun Gupta's Blog — August 12, 2009 @ 6:11 am

  4. [Trackback] The GlassFish High Availability allows to setup a cluster of GlassFish instances and achieve highly scalable architecture using in-memory session state replication. This cluster can be very easily created and tested using the "clusterjsp" sample bundl…

    Comment by Arun Gupta's Blog — August 12, 2009 @ 9:15 am

RSS feed for comments on this post. TrackBack URL

Leave a comment

The views expressed on this blog are my own and do not necessarily reflect the views of Oracle.
Powered by WordPress