Showing posts with label Rails. Show all posts
Showing posts with label Rails. Show all posts

Saturday, January 31, 2009

Benchmarking JRuby on Rails

Last night, while working on a project I found a really neat use of Rails Components, but I also noticed that this part of Rails is deprecated, among other reasons because it's slow.

Well, how slow? During my quest to find out, I collected some interesting data, and even more importantly put JRuby and MRI Ruby face to face.

Disclaimer: the benchmarks were not done on a well isolated and specially configured test harness, but I did my best to gather data with informational value. All the components were used with OOB settings.

Setup

  • ruby 1.8.6 (2008-03-03 patchlevel 114) [universal-darwin9.0] + Mongrel Web Server 1.1.4
  • jruby 1.1.6 (ruby 1.8.6 patchlevel 114) (2008-12-17 rev 8388) [x86_64-java] + GlassFish gem version: 0.9.2
  • common backend: mysql5 5.0.75 Source distribution (InnoDB table engine, Rails pool set to 30)


Benchmarks

I used an excellent high quality benchmarking framework Faban for my tests. I was lazy, so I only used fhb (very similar to ab, but without its flaws) to invoke simple benchmarks:
  • simple request benchmark: bin/fhb -r 60/120/5 -c 10 http://localhost:3000/buckets/1
  • component request benchmark: bin/fhb -r 60/120/5 -c 10 http://localhost:3000/bucket1/object1
Both tests were run with JRuby as well as with RMI Ruby and in addition to that I ran the tests with Rails in single-threaded as well as multi-threaded modes. I didn't use mongler clusters or glassfish pooled instances - there was always only one Ruby instance serving all the requests.

Results

ruby 1.8.6 + mongrel
---------------------------------
simple action + single-threaded:
ops/sec: 210.900
% errors: 0.0
avg. time: 0.047
max time: 0.382
90th %: 0.095

simple action + multi-threaded:
ops/sec: 226.483
% errors: 0.0
avg. time: 0.044
max time: 0.180
90th %: 0.095

component action + single-threaded:
ops/sec: 132.950
% errors: 0.0
avg. time: 0.075
max time: 0.214
90th %: 0.130

component action + multi-threaded:
ops/sec: 131.775
% errors: 0.0
avg. time: 0.076
max time: 0.279
90th %: 0.125

jruby 1.2.6 + glassfish gem 0.9.2
----------------------------------
simple action + single-threaded:
ops/sec: 141.417
% errors: 0.0
avg. time: 0.070
max time: 0.259
90th %: 0.115

simple action + multi-threaded:
ops/sec: 247.333
% errors: 0.0
avg. time: 0.040
max time: 0.318
90th %: 0.065

component action + single-threaded:
ops/sec: 107.858
% errors: 0.0
avg. time: 0.092
max time: 0.595
90th %: 0.145

component action + multi-threaded:
ops/sec: 179.042
% errors: 0.0
avg. time: 0.055
max time: 0.357
90th %: 0.085


Platform/ActionSimple+/-Component+/-
Ruby ST 210ops0%132ops0%
Ruby MT226ops7.62%131ops-0.76%
JRuby ST141ops-32.86%107ops-18.94%
JRuby MT247ops17.62%179ops35.61%
(ST - single-threaded; MT - multi-threaded)

Conclusion

From my tests it appears that MRI is faster in single threaded mode, but JRuby makes up for the loss big time in the multi-threaded tests. It's also interesting to see that the multi-threaded mode gives MRI(green threads) a performance boost, but it's nowhere close to the boost that JRuby(native threads) can squeeze out from using multiple threads.

During the tests I noticed that rails was reporting more times spent in the db when using JRuby (2-80ms) compared to MRI (1-3ms). I don't know how reliable this data is but I wonder if this is the bottleneck that is holding JRuby back in the single threaded mode.

Sunday, January 11, 2009

Freezing activerecord-jdbc Gems into a Rails Project

Over the Christmas break a Slovak friend of mine (Hi Martin!) asked me to build a simple book library management app for a school in the Philippines where he's been volunteering for the past year. I thought to my self that if someone can volunteer one year of his life in such an amazing way, I could spend a few hours to help him out too.

Since from his description it was obvious that he was looking for a low maintenance solution, I though that a rails application with an embedded database would be a good choice. I worked with derby (JavaDB) in the past and I knew that derby drivers were already available as an active-record adapter gem, so I thought that it would be pretty simple to set up dev environment using Rails, JRuby, and embedded derby db. Surprisingly there were a few issues along the way.

I started with defining the database config in config/database.yml:
development:
adapter: jdbcderby
database: db/library_development
pool: 5
timeout: 5000
...
...
The database files for the dev db will be stored under RAILS_ROOT/db/library_development

Secondly I specified the gem dependency in config/environment.rb (you gotta love this Rails 2.1+ feature):
Rails::Initializer.run do |config|
...
config.gem "activerecord-jdbcderby-adapter", :version => '0.9', :lib => 'active_record/connection_adapters/jdbcderby_adapter'
...
end
Note that you must specify the :lib parameter, otherwise Rails won't be able to initialize the gem and you'll end up with:
no such file to load -- activerecord-jdbcderby-adapter
So far so good. Now let's install the gems we depend on:
$ jruby -S rake gems:install
(in /Users/me3x/Development/library)
rake aborted!
Please install the jdbcderby adapter: `gem install activerecord-jdbcderby-adapter` (no such file to load -- active_record/connection_adapters/jdbcderby_adapter)

(See full trace by running task with --trace)
Huh? I asked rake to install gems and I get an error that I need to install gems first? It turns out that this error comes from ActiveRecord, which tries to initialize db according to database.yml, and only then environment.rb gets to be read.

Ok, so let's install the db dependencies manually:
$ sudo jruby -S gem install activerecord-jdbcderby-adapter
Password:
JRuby limited openssl loaded. gem install jruby-openssl for full support.
http://wiki.jruby.org/wiki/JRuby_Builtin_OpenSSL
Successfully installed activerecord-jdbc-adapter-0.9
Successfully installed jdbc-derby-10.3.2.1
Successfully installed activerecord-jdbcderby-adapter-0.9
3 gems installed
Installing ri documentation for activerecord-jdbc-adapter-0.9...
Installing ri documentation for jdbc-derby-10.3.2.1...
Installing ri documentation for activerecord-jdbcderby-adapter-0.9...
Installing RDoc documentation for activerecord-jdbc-adapter-0.9...
Installing RDoc documentation for jdbc-derby-10.3.2.1...
Installing RDoc documentation for activerecord-jdbcderby-adapter-0.9...
Cool, let's check if all the dependencies are available:
$ jruby -S rake gems
(in /Users/me3x/Development/library)
- [I] activerecord-jdbcderby-adapter = 0.9
- [I] activerecord-jdbc-adapter = 0.9
- [I] jdbc-derby = 10.3.2.1

I = Installed
F = Frozen
R = Framework (loaded before rails starts)
Yay, all dependencies are installed.

In the past when dependencies couldn't be declared in environment.rb, I found developing with frozen rails and gems much more manageable, especially when the app is being developed by more than one person. This also made for less deployment surprises. With the config.gem defined dependencies, the situation changes quite a bit, but there are situations when it still makes sense to freeze gems into the project. So let's freeze the gems:
$ jruby -S rake gems:unpack:dependencies
(in /Users/me3x/Development/library)
WARNING:  Installing to ~/.gem since /usr/local/jruby/jruby-1.1.6/lib/ruby/gems/1.8 and
   /usr/local/jruby/current/bin aren't both writable.
Unpacked gem: '/Users/me3x/Development/library/vendor/gems/activerecord-jdbcderby-adapter-0.9'
Unpacked gem: '/Users/me3x/Development/library/vendor/gems/activerecord-jdbc-adapter-0.9'
Unpacked gem: '/Users/me3x/Development/library/vendor/gems/jdbc-derby-10.3.2.1'
Looks good, let's check it:
$ jruby -S rake gems
(in /Users/me3x/Development/library)
- [F] activerecord-jdbcderby-adapter = 0.9
- [F] activerecord-jdbc-adapter = 0.9
- [F] jdbc-derby = 10.3.2.1

I = Installed
F = Frozen
R = Framework (loaded before rails starts)
Nice all the dependencies are now frozen!

Friday, February 08, 2008

Mediacast Deployment Diagram

During our last meeting, Arun suggested that I publish the high-level deployment diagram of mediacast.sun.com. So here it is:



I described everything in textual form in my previous blog entry about mediacast.

Sunday, January 27, 2008

JRuby on Rails Rewrite of mediacast.sun.com Launched

A few days ago, we finally released Mediacast 2.0 - a complete rewrite of the old Mediacast application.



The original application was based on a few servlets, filters, and a lot of JSPs. It was all put together in hurry a few of years ago, when one of those fire-drill requests came to provide Sun employees with a site where they could publish files. The old code was hard to maintain and extend, and that's why we decided to EOL the old code base and write something better from scratch.

I'm a fan of Rails and for the past year I've been amazed by the great progress of the JRuby project. This was one of the reasons why I suggested that we could try to rewrite the app in Rails and deploy it in a regular Java web container, thanks to JRuby and Goldspike. It took some time for Rama to give us a go-ahead, but finally in late September, two other colleagues (with no Rails or JRuby experience) and I started to work on the rewrite alongside our other projects (forums.sun.com and wikis.sun.com).

Many people asked us why JRuby on Rails was picked for this project. Here is an incomplete list of reasons:
  • we were starting from scratch, so we were not tied to any legacy code, and could pick any web framework that runs on Java
  • proof of concept project to evaluate the technology for other uses across our organization
  • verify that Rails really delivers the rapid development promise
  • something new/fun for the team to help balance out the not-so-fun stuff :)

Here is my experience:

Rails and JRuby Learning Curve


I worked on my first Rails project in the summer of 2006 and since then I worked on a few other (internal) Rails projects. But having to teach others and deploy an application externally using JRuby was a new experience for me.

As far as teaching goes, I can't critique myself, but what I can say is that I had a lot of good help thanks to some Rails, Ruby and JRuby books, and many websites and blogs that have sprung up on the Internet in the last couple of years.

Learning JRuby (with previous Ruby and Java experience) is easy, because most of the time "it just works" and very rarely is the developer aware that the C-based MRI Ruby interpreter is not being used. The ability to access and seamlessly integrate with existing or new Java code is a huge plus without which we would not have been able to launch this project successfully (more on this later).

The deployment part was a different story. The Ruby on Rails application can be deployed in many different ways and JRuby offers a new alternative approach to all of them. Instead of e.g. having Apache webserver reverse-proxy requests to an army of Mongrels, JRuby and Goldspike make it possible to deploy Rails applications in a JavaEE web container. IMO this is much cleaner than anything else that is available in the non-JRuby Rails world. The downside is that this deployment method is quite new and there isn't a lot of documentation and community knowledge about it.

Application Architecture


Our app is a simple database-driven Rails application consisting of a handful of models, 4 controllers, and a bunch of view templates. The only piece of data that is not stored in the database are the actual files, which are stored on the file system.

To be on the safe side when it comes to performance, we employed quite a lot of fragment caching, which sped up our application quite a bit.

Development Environment


Our development environment is based on a self-contained1 JRuby (1.0.3) on Rails (1.2.6) application stored in a Mercurial repository. The IDE we use is NetBeans 6 with Ruby support and Mercurial plugin. The DB of our choice is MySQL and servers we use during development are WEBrick and Glassfish v2ur1.

NetBeans makes it super easy to write the Ruby code and offers a lot of neat features for Rails application development. I have to say that Tor and the gang did a great job. In fact I switched from Eclipse to NetBeans thanks to its great Ruby support.

Because the application runs in the JVM we can use JConsole to monitor the app while load testing which comes in really handy!

So all is good here, except for one thing. I got used to using the amazing ruby-debug debugger for debugging my Ruby on Rails applications. This debugger is not yet available for JRuby on Rails application (unless you hack your way through). I read somewhere that jruby-debug should be available with NetBeans 6.1. Once that is done, the JRoR dev environment will be on par with RoR (in fact thanks to tools like JConsole it will be superior).

Production Environment


We use a pair of load-balanced T2000 with Solaris 10, JDK6 and SJSAS 9.1u1. These two servers share a nfs NAS drive used for file storage and fragment cache storage. The DB backend is a MySQL database server, which we access through a connection pool set up in the app server.

All of this was fairly easy to set up. As you can see there were no special requirements when comparing this environment to a usual JavaEE production environment.

The Good


Once my colleagues grasped some RoR basics, we got the core of the application up and running fairly fast. Sometimes it still amazes even me how much one can do with Rails in a short amount of time. Thanks to a small amount of code one needs to write, the code review process is fast as well, and fixing a bug often means changing only a few lines of code.

The Bad


Since most of the C-based gems are not compatible out-of-box with JRuby (at the moment), the jruby-extras project aims to deliver JRuby compatible versions of these libraries. One of these libraries - JRuby-OpenSSL - was needed for me to integrate our app with our authentication webservice. I soon found out that JRuby-OpenSSL was not completely implemented yet and parts of functionality that I needed were missing. I'm sure that it is just a matter of time when problems like this will go away (if it hasn't happened already) as these libraries will mature.

The Ugly


The Goldspike project provides a bridge between the JavaEE and RoR world. It does this by dispatching the incoming HTTP requests into Rails running in a JRuby runtime.

This works great for all requests that take little time to process, but if you have long-running requests like large file uploads or downloads, these requests will occupy your JRuby runtimes and you soon realize that you are running out of runtimes in your small pool, at which point your application becomes unresponsive for any new requests.

This was the biggest problem we hit, but thanks to the possibility to seamlessly integrate Java code into our JRoR app and a great idea that my colleague Peter had, we solved this issue quite elegantly.

JRuby and Java Come to the Rescue


The two main issues we faced and that consumed most of my time on this project were related to the immaturity of the libraries around JRuby and application characteristics specific to JRoR deployment. Both of these issues can be resolved thanks to years of long Java and JavaEE history, and their libraries.

The problem with reliable connection to our SOAP-over-HTTPS based authentication webservice was resolved by generating a client Java webservice stub and using that instead of SOAP4R which didn't work properly because of the problems with JRuby-OpenSSL.

The second problem with the long-running processes occupying our precious JRuby runtimes, we solved by using a servlet filter and a fake HttpServletResponse (that we sent to Goldspike instead of the original one) and streaming the data from the filter instead from the runtime. I'll write a separate blog entry on this.

Overall Impression


This project was/is fun to work on. We experimented with quite a few new (for us) technologies and learned a lot along the way. To be honest, I expected to deploy the app much sooner but at that time I was not aware of the two above mentioned issues which consumed a lot of my time.

I was a bit worried about the performance of the application, but that turned out to be a non issue once we had the download servlet filter in place, and with the performance improvements in JRuby 1.1 things will be even better in the future.

Overall I'm happy with the outcome of our project and I look forward to adding more functionality to the application.

Our Future Plans


From the infrastructure perspective:
  • upgrade to JRuby 1.1 and Rails 2.0
  • start using Warbler, which looks to be superior to Goldspike's Rails plugin, for building the war file
  • experiment with in-memory session state replication in Glassfish

From the feature perspective:
  • better categorization of media items
  • search functionality via integration with search.sun.com
  • previews of media items
  • new UI design
  • and the toughest one - audio and video streaming


JRuby/Goldspike/Glassfish Things I Would Like to See Improved


  • I'm not sure if it is us and our (mis)configuration, Goldspike, JRuby or Glassfish, but right now we need quite a big JVM heap to keep things running. With 8 JRuby instances in the pool and Http thread count set to 512, we need -Xmx set to 2-2.5GB. This is a bit too much I think. We'll have to look into this and find the culprit.
  • The application startup is quite slow, especially on a machine like T2000, which doesn't perform well for heavy-weighted single-threaded operations. I don't see a reason, why Goldspike couldn't initialize the JRuby runtime pool concurrently cutting down the startup time significantly.
  • Offload JRuby runtimes as much as possible. Currently operations like file upload or file download (via Rails' send_file) are handled by JRuby runtimes. I think that it should be possible to take care of these operations outside of the runtime, allowing the runtime to process other rails requests in the meantime.



1 - Rails and all the other gems and jars are frozen into the project

Monday, October 29, 2007

Inflector/environment.rb Bug in Rails

Today I needed to get Rails to grok an uncountable noun "media". Easy you think, right? Just add an inflection rule.

So I went to config/environment.rb, uncommented the Inflection example and modified it with my "media" noun, just like this:
Rails::Initializer.run do |config|
  ...
  ...
  ...
  
  Inflector.inflections do |inflect|
    inflect.uncountable %w( media )
  end

  # See Rails::Configuration for more options
end

# Add new mime types for use in respond_to blocks:
# Mime::Type.register "text/richtext", :rtf
# Mime::Type.register "application/x-mobile", :mobile

When I tried to run rails console or tests I saw an error like this:
me@Xbook:testapp$ ./script/console 
Loading development environment.
./script/../config/../config/environment.rb:55:NameError: uninitialized constant Inflector
/opt/local/lib/ruby/gems/1.8/gems/actionpack-1.13.5/lib/action_controller/assertions/selector_assertions.rb:525:NoMethodError: undefined method `camelize' for "top":String
/Users/me3x/Development/DSE/mediacast2/apps/testapp/app/controllers/application.rb:4:NameError: uninitialized constant ActionController::Base

The problem turned out to be in the commented-out rails example in environment.rb. The Inflector.inflections block must not be nested within the Initializer.run block.

This fixes the problem:
Rails::Initializer.run do |config|
  ...
  ...
  ...

  # See Rails::Configuration for more options
end

Inflector.inflections do |inflect|
  inflect.uncountable %w( media )
end

# Add new mime types for use in respond_to blocks:
# Mime::Type.register "text/richtext", :rtf
# Mime::Type.register "application/x-mobile", :mobile

Wednesday, September 12, 2007

NetBeans IDE 6.0 Beta 1 is Out!

While searching for a nightly build of NetBeans I noticed that NB6 Beta 1 is out. Great!

I'm looking forward to using the new version. After spending the last couple of weeks (or months?) developing in NB6M10, I can't wait to see what this release brings.

The first thing that stuck me though is the lack of "drag&drop" installation on MacOS which was replaced with "pkg-style" installer. I liked the drag&drop installation better - it's more mac-ish. I hope the surprises that will follow will only be pleasant.

Thanks, NB guys!

Download link: http://bits.netbeans.org/download/6.0/milestones/latest/


Monday, May 14, 2007

Hello I'm RubyOnRails, Hello I'm Java :-)

This is pretty good! The Java-developer half of me feels offended, but the RubyOnRails half is laughing hard :-D

Saturday, May 12, 2007

JavaOne Day 4 - Toy Show, Comparing (G)Rails and JavaEE, DTrace in Java

JavaOne 2007 is over, it's time to put the conference badge away and start working on the ideas that I was inspired with. It's a damn long list. I should ask my manager for a week off now (if not more) to have enough time to scratch the surface of things on my TODO list. Rama? :)



Friday was the Toy Show day. If you didn't attend, check out the video online, it was quite a show with a lot of interesting and inspiring demos.

From the sessions:

I went to a session called "Comparing the Developer Experience of Java EE 5.0, Ruby on Rails, and Grails: Lessons Learned from Developing One Application". Having a year of experience developing Rails applications and a couple of years on and off with JaveEE, I was mainly interested in seeing how Grails compares to these two.

The session was somewhat disappointing, mainly because the guys running the session were coming from the JavaEE world and all they were trying to prove was that JavaEE is still the best choice nowadays. Don't take me wrong, JaveEE is certainly a cool technology and has its place in the industry, but there are often better ways to solve some problems or parts of complex problems.

The worst of all was their benchmarking strategy. Comparing Rails running on WEBrick to Grails and JaveEE applications running on Glassfish and Sun Java System Application Server is nonsense. That's like comparing PHP application with Derby backend to JavaEE app with an Oracle or Postgres cluster as the backend. I think that there is a pretty good reason why Sun doesn't bundle Java with Postgres as Java DB but uses Derby instead. WEBrick has it's place in the Rails world, but it's certainly not a production server that scales well.

Also if you create a CRUD application in Rails using the scaffold method instead of the scaffold generator, as they did, you might as well recompile your JSP pages for each request in the JavaEE application to be fair. So the benchmark was flawed for many reason.

I wish they benchmarked the Rails app deployed on a recommended production setup or even more interesting would be to see how the Rails application deployed as a WAR on Glassfish performs. This is one of the things that is on my long TODO list to do after JavaOne.

I also went to a Java DTracing session ("Cranking Up Java Application Performance with DTrace"). Adam Leventhal, one of the creators of DTrace, obviously knew what he was talking about and Jarod Jenson, a consultant specializing on DTrace was truly amazing - throughout the session he was typing like a crazy monkey and DTracing applications in real time! If they make a video of this session available online, this is definitely something you want to see :).

It wasn't big news that it was possible to DTrace Java applications. The limited support was there in JDK 5.0, but with JDK 6.0 things have improved by heaps. There is a lot of new probes in the JVM and these probes can be enabled without even restarting the application! JDK 7.0 will bring support for creating user defined probes in Java applications. This will be a major step forward.

Overall JavaOne was really good, I had a lot of fun and enjoyed it a lot. Too bad that it lasts only four days. I'm already looking forward to next year's conference and I'm definitely going to do everything in my power to come again!

Saturday, September 02, 2006

Solaris + Lighttpd + FastCGI + SSL HowTo

Update (07-05-18): You might also want to check out CoolStack, an optimized open source software stack for the Sun Solaris Operating System.

I hadn't heard about Lighttpd (Lighty) web server before I started to be interested in Ruby on Rails (RoR). Lighttpd is fast, scalable, secure, flexible and lightweight webserver which in RoR community is preferred production web server. One of the main advantages of Lighttpd compared to Apache, for example, is the built in support for FastCGI and very easy yet flexible configuration.

When I was preparing the production environment for one of the RoR applications I was working on lately, I found that even though there is quite a lot of HowTos for installing lighttpd on linux and MacOS, there is not a single one that I could find that would describe this procedure on Solaris / OpenSolaris OS.

While setting up the production environment I got stuck on some steps, and I hope that this HowTo will help anyone trying to deploy his RoR application on Solaris and to avoid problems I had.

Targeted configuration: Solaris 10 + Lighttpd + FastCGI + SSL

1. Prerequisites I started out with the core installation of Solaris 10, this means that I needed to add some packages. Before you start, make sure you have these Solaris packages installed:
  • SUNWhea >>> needed by lighttpd
  • SUNWtoo >>
  • SUNWlibmr >>> needed by fastcgi
  • SUNWlibm >>
If you plan to use only sun compiler to compile everything you will also need SUNWbtool and SUNWsprot packages.

From blastwave.org via pkg-get get:
  • openssl >>> needed by lighttpd for ssl
And one more thing, you must get Sun C Compiler, otherwise you won't be able to install ruby-fastcgi bindings (explained later). Sun C Compiler is part of Sun Studio, which you can download for free here (a free SDN account is needed). There are two ways described on the website how one can get the compiler:
  • option 1) 202MB - works
  • option 2) 365MB - haven't tried
Once downloaded, follow the "Setup" instructions on the website above.

Now we should be ready to start.

2. Lighttpd
At first we should install Lighttpd which can be downloaded from here. (I used gcc to compile this one)
./configure --with-openssl=/opt/csw --with-ldap --with-bzip2 --with-zlib
The output from the configure command should end like this:
Features:

enabled:
auth-crypt
auth-ldap
compress-bzip2
compress-deflate
compress-gzip
large-files
network-ipv6
network-openssl
regex-conditionals
...
...


Make sure the "network-openssl" is in the list of enabled features, if it is not there, check the output from configure tests and if you see that openssl was found and right below it is:
checking for BIO_f_base64 in -lcrypto... no
check your configure arguments and make sure that --with-openssl=/path/to/openssl is set correctly (if installed via pkg-get it will resided in /opt/csw). If this is not done properly everything will compile correctly but the --with-openssl option will be ignored silently!

Let's finish up the installation:

make
make install
Test if everything went well with -v switch
$ ligttpd -v
lighttpd-1.4.11 (ssl) - a light and fast webserver
Build-Date: Aug 30 2006 15:19:28
If there is no "(ssl)" after the version, something is wrong, check if you set --with-openssl=/path correctly.
3. FastCGI
Now we need to install FastCGI which can be downloaded from here:
./configure   --prefix=/usr/local
make
make install

4. ruby-fcgi

Next step is to install ruby-fcgi bindings. This is where I got really stuck. To be able to install this, you need the Sun C Compiler mentioned earlier. If you installed ruby and ruby gems via pkg-get as I did, it comes preconfigured to use Sun compiler by default, even if one is not installed. And if you don't have this compiler you will see all sorts of weird errors when installing gems with native extensions.

Once you have the compiler, installation is trivial. If you are building it manually, download sources here:
ruby install.rb config -- --with-fcgi-dir=/usr/local
ruby install.rb setup
ruby install.rb install
or when using ruby gems:
gem install fcgi -- --with-fcgi-dir=/usr/local
Note the double "--", that is not a typo, it's simply the way how to send parameters to extconf.rb

If you see an error like this:
install.rb: entering config phase...
---> lib
<--- lib ---> ext
---> ext/fcgi
/opt/csw/bin/ruby /root/ruby-fcgi-0.8.6/ext/fcgi/extconf.rb
checking for fcgiapp.h... yes
checking for FCGX_Accept() in -lfcgi... no
<--- ext/fcgi <--- ext
Note this part:
checking for fcgiapp.h... yes
checking for FCGX_Accept() in -lfcgi... no
It most likely means that you are using GCC and not Sun C Compiler, check if cc in your path is pointing to Sun C Compiler, you might also check if the environmental variable CC is not set to gcc. Let's test if fcgi and ruby-fcgi bindings were correctly installed by these commands in irb:
irb(main):001:0> require 'fcgi.so'
=> true
irb(main):001:0> require 'fcgi'
=> true
If both "require" calls return true, you have successfully installed FastCGI and ruby is able to invoke it. 5. SSL Certificate
If you don't have your server certificate yet, you can create a self signed one like this:
openssl req -new -x509 -keyout server.pem -nodes -out server.pem -days 1000
6. Configuring Lighty
Create lighttpd.conf
server.port = 443
server.bind = "0.0.0.0"
server.modules = ( "mod_rewrite", "mod_fastcgi", "mod_accesslog" )
url.rewrite = ( "^/$" => " index.html", "^([^.]+)$" => "$1.html" )
server.error-handler-404 = "/dispatch.fcgi"
server.document-root = "/path_to_your_app/public"
server.errorlog = "/path_to_your_app/log/server.log"
accesslog.filename = "/path_to_your_app/log/access_log"
ssl.engine = "enable"
ssl.pemfile = "/path_to_your_pem_file/server.pem"

fastcgi.server = (".fcgi" =>
( "localhost" =>
(
"min-procs" => 10,
"max-procs" => 10,
"socket"    => "/tmp/yourapp.fcgi.socket",
"bin-path"  => "/path_to_your_app/public/dispatch.fcgi",
"bin-environment" => ( "RAILS_ENV" => "production" )
))
)

mimetype.assign = (
".css"        =>  "text/css",
".gif"        =>  "image/gif",
".html"       =>  "text/html",
".jpeg"       =>  "image/jpeg",
".jpg"        =>  "image/jpeg",
".js"         =>  "text/javascript",
".pdf"        =>  "application/pdf",
".png"        =>  "image/png",
".txt"        =>  "text/plain",
)

7. Ta-da!
Let's start the server

lighttpd -f lighttpd.conf

I hope that these instructions helped you to get Lighty on Solaris.

If you have other recommendations or have problems with the installation, feel free to leave a comment.

Enjoy..

PS: A big thanks to my friend J who helped me figure out that you need Sun C compiler for ruby-fcgi to compile.

UPDATE: added reference to SUNWbtool and SUNWsprot packages in case you want to compile everything with Sun's compiler.