Passenger dying … too many apache processes

I encountered this problem when I first started working with Passenger, and have run into it repeatedly over the last year, so I thought I’d just throw out the fix I have for it.

Usually people having these problems are usually running the prefork MPM and have a section in their apache config file that looks like this

# prefork MPM
# StartServers: number of server processes to start
# MinSpareServers: minimum number of server processes which are kept spare
# MaxSpareServers: maximum number of server processes which are kept spare
# MaxClients: maximum number of server processes allowed to start
# MaxRequestsPerChild: maximum number of requests a server process serves
<IfModule mpm_prefork_module>
StartServers          5
MinSpareServers       5
MaxSpareServers      10
MaxClients          150
MaxRequestsPerChild   0
</IfModule>

#Aside: To find out if  what multi processing module (mpm) you are runing (worker or prefork) just run this command.
apache2 -l
(it may also be httpd/httpd2/apache/apache2ctl/apachectl -l)

The apache processes themselves don’t usually take up a lot of memory, I’ve seen anywhere from 0.2MB – 14MB … but they usually lie in the range of 2 – 6MB.
The problem comes if you get a traffic spike and Apache spawns up to 150 process to handle the traffic.

You can see that you can easily have 300MB – 1GB of memory allocated to the processes and, consequently, run out of memory so that your server is now unresponsive.

The fix for this is to set MaxClients to, at minimum, your StartServers + Min Spare Servers. But you also want to take into consideration the Max Instances of your app that you’ve set for passenger and how many requests you want to be able to serve at a time.

From Apache documentation

The MaxClients directive sets the limit on the number of simultaneous requests that will be served. Any connection attempts over the MaxClients limit will normally be queued, up to a number based on the ListenBacklog directive. Once a child process is freed at the end of a different request, the connection will then be serviced.

Be sure to increase this number if you are running php apps on your server as well.

Hope this helps.


rake aborted! development database is not configured.

You might have been happily running migrations on your development box for weeks and go to get the application set up on a production server.
And all might even have been going well until you ran

rake db:migrate

only to see it crash and burn like this.

** Invoke db:migrate (first_time)
** Invoke environment (first_time)
** Execute environment
rake aborted!
development database is not configured

Fear not ye intrepid developer!
This happens when you leave out the development specifications in your database.yml.
(If you don’t define development.rb, you’ll get a weirder “No such file or directory – …../development.rb” error)

Apparently rake db:migrate runs in development mode no matter what environment you’re in (still looking into the reason for this).
So what you have to do is call migrate like this

rake db:migrate RAILS_ENV=production <—- or whatever your environment is

That should get you back on the path to true happiness.

How to get a 25% boost in your Rails app?

I was working on a rails app today, and got to wondering about the very many

SHOW FIELDS FROM

MySql queries I was seeing.

I had always thought about whether there was a way to get rid of those completely, or reducing the number of them by caching or something.
Well, today I actually did some digging and found this little gold nugget about “SHOW FIELDS” calls in Rails.

Apparently, Rails does cache MySql “SHOW FIELDS ” with one notable exception.

However, upon inspection it turns out that Rails DOES NOT cache ‘SHOW FIELDS’ queries for has_and_belongs_to_many associations. So every time a select or an insert is done via a Rails has_and_belongs_to_many association, a ‘SHOW FIELDS’ on the join table is executed.

So the dreaded HABTM association strikes again!
Those darned things are pure evil eh? 😀

Well the awesome blog writer figured out a patch to fix the problem.

And in his tests he reported this (see image below for reference) …

After rolling this change out we have seen a very noticeable improvement on performance. By using New Relic’s Compare With Yesterday feature (see chart below) we can see that our application response time dropped from an average of about 560 ms per request to 420 ms per request. This is roughly a 25% performance increase. The yellow line shows today, the blue line is yesterday. CPU and database load decreased by about 25% as well.

A 25% improvement in application response time!?!?!
Sign. me. up.

New Relic monitor app showing 25% improvement in response time

I followed the Rails ticket on this particular issue and couldn’t figure out whether the fix had been rolled into a Rails version yet. I asked the blog author and he says the patch has been included in Rails 2.3, so if you’re running that, this does not apply to you.

I’m about to apply this patch to a couple of applications, hopefully it helps you too.
Please post in the comments about your experience. Same? better? worse?

requiring gems from github (specifically flickr-fu and xml_magic) using config.gem

So the rails way of requiring a gem in your app is by using the config.gem instruction in environment.rb (as opposed to sticking a require statement in your environment.rb).

However including gems from github is a different beast … sometimes the gem author will tell you exactly how to do it, or sometimes they won’t, as the case with flickr-fu.

Just fyi … typically when you are including a gem from git hub you will want to do something like this …

config.gem 'gem-name-from-'gem -list'-command', :lib => 'github_gem_name', :source => 'http://gems.github.com'

“gem name from gem -list command” … by this I mean that you should run a gem -list command from your command line and use the name that shows up for your gem there.

… so the will_paginate gem config.gem statement looks like this …

config.gem 'mislav-will_paginate', :lib => 'will_paginate', :source => 'http://gems.github.com'

but for the xml-magic gem, its this ….

config.gem 'xml-magic', :lib => 'xml_magic', :source => 'http://gems.github.com'

and for the flickr-fu gem, its this ….

config.gem 'flickr-fu', :lib => 'flickr_fu', :source => 'http://gems.github.com'

Its not documented anywhere.

I had to figure it out by trial-and error, now you don’t have to 😀

How to uninstall a plugin in Rails

This one is simple, but I couldn’t find a decent google result for it.

Before you uninstall the plugin, you have to get its name … go to the vendors directory in your app folder and get the name of the folder

In this case the name of the plugin is “active_scaffold”

Go to the directory of the app you want the plugin removed from and type in

ruby script/plugin remove active_scaffold

or if you’re on a Linux box

./script/plugin remove active scaffold

Cakephp Filter gotcha for rails folks

Usually in Rails, if you specify a before_filter in the base controller ‘ApplicationController’ (in application.rb), every other controller in that app inherits that filter, so that even if you specify a before_filter in another controller … the filter in application.rb always runs
Example:

class ApplicationController < ActionController::Base
   before_filter :check_login
end
class UploadsController < ApplicationController
    before_filter :get_data
end

The :check_login method is always run even though UploadsController specifies another before_filter.
(You can stop this behavior by specifying a skip_before_filter :check_login in the Uploads Controller)

However if you take this mindset with you to cakephp Continue reading