88

To jump on the band-wagon of Phusion Passenger we've setup a staging server for a small rails app to test things out.

So far it has been very nice to use, it makes installing/configuring and deploying apps a breeze. The problem is the site we're using doesn't get hit very often and it seems to shut down the servers in the background. Meaning when someone goes to the site they have a really long wait until it starts up a new server to handle the request. We've read through the documentation, tried quite a few different set-ups (smart/smart-lv2 modes, passengeridletime etc) and still haven't found a real solution.

After ploughing through Google results we can't really find useful information. Currently we have a cron job that makes a request every-so-often in an attempt to keep the servers running.

Is anyone else experiencing this problem and do you have any advice for a fix?

tsdbrown
  • 5,038
  • 3
  • 36
  • 40
  • I also found this nugget on the Passenger Doc Site: http://www.modrails.com/documentation/Users%20guide%20Apache.html#PassengerPreStart – dewrich Aug 11 '11 at 16:48
  • @dewrich I found a tool ( http://wekkars.com ) that does exactly what your cronjob is doing – SteenhouwerD Mar 11 '12 at 10:12

7 Answers7

120

What's happening is that your Application and/or ApplicationSpawners are shutting down due to time-out. To process your new request, Passenger has to startup a new copy of your application, which can take several seconds, even on a fast machine. To fix the issue, there are a few Apache configuration options you can use to keep your Application alive.

Here's specifically what I've done on my servers. The PassengerSpawnMethod and PassengerMaxPreloaderIdleTime are the configuration options most important in your situation.

# Speeds up spawn time tremendously -- if your app is compatible. 
# RMagick seems to be incompatible with smart spawning
# Older versions of Passenger called this RailsSpawnMethod
PassengerSpawnMethod smart

# Keep the application instances alive longer. Default is 300 (seconds)
PassengerPoolIdleTime 1000

# Keep the spawners alive, which speeds up spawning a new Application
# listener after a period of inactivity at the expense of memory.
# Older versions of Passenger called this RailsAppSpawnerIdleTime
PassengerMaxPreloaderIdleTime 0

# Just in case you're leaking memory, restart a listener 
# after processing 5000 requests
PassengerMaxRequests 5000

By using "smart" spawning mode and turning off PassengerMaxPreloaderIdleTime, Passenger will keep 1 copy of your application in memory at all times (after the first request after starting Apache). Individual Application listeners will be forked from this copy, which is a super-cheap operation. It happens so quickly you can't tell whether or not your application has had to spawn a listener.

If your app is incompatible with smart spawning, I'd recommend keeping a large PassengerPoolIdleTime and hitting your site periodically using curl and a cronjob or monit or something to ensure the listener stays alive.

The Passenger User Guide is an awesome reference for these and more configuration options.

edit: If your app is incompatible with smart spawning, there are some new options that are very nice

# Automatically hit your site when apache starts, so that you don't have to wait
# for the first request for passenger to "spin up" your application. This even
# helps when you have smart spawning enabled. 
PassengerPreStart http://myexample.com/
PassengerPreStart http://myexample2.com:3500/

# the minimum number of application instances that must be kept around whenever 
# the application is first accessed or after passenger cleans up idle instances
# With this option, 3 application instances will ALWAYS be available after the
# first request, even after passenger cleans up idle ones
PassengerMinInstances 3

So, if you combine PassengerPreStart and PassengerMinInstances, Passenger will spin up 3 instances immediately after apache loads, and will always keep at least 3 instances up, so your users will rarely (if ever) see a delay.

Or, if you're using smart spawning (recommended) with PassengerMaxPreloaderIdleTime 0 already, you can add PassengerPreStart to get the additional benefit of immediate startup.

Many thanks to the heroes at phusion.nl!

John Douthat
  • 40,711
  • 10
  • 69
  • 66
  • Thank you very much for your answer. I believe we have tried most of those setting but maybe not in the correct combination. I will get testing tomorrow and revert. – tsdbrown May 12 '09 at 16:31
  • This is awesome. I was having the same problem with my Nginx/Phusion Passenger install and this helped me tremendously. – Scott Arrington Jun 28 '10 at 18:08
  • I've tried this setup and see no performance improvements, but our app is using RMagick. Are there any workarounds for this? Why doesn't it work with RMagick? – Chip Castle Sep 15 '11 at 03:46
  • 1
    `RailsSpawnMethod` is deprecated in favor of `PassengerSpawnMethod` http://www.modrails.com/documentation/Users%20guide%20Apache.html#PassengerSpawnMethod – paulus Sep 11 '12 at 08:18
  • 1
    Hi, I'm having the same issue and I'd like to try that configuration, but I don't know where does that configuration must to be placed. thanks! – joseramonc Nov 25 '13 at 07:34
  • @JoseRamonCamacho All of these can be placed in your global apache configuration file. Some of the options can also be placed in vhost configuration blocks or other places. All of the details can be found in the Passenger documentation, which is linked in the answer. – John Douthat Nov 25 '13 at 17:26
  • Please also mention the config file name where to place all this. – Paul Jun 17 '14 at 12:58
  • pardon my ignorance, but what file is this? i'm looking for where this options are set and i cannot find anything. – roloenusa Jul 19 '14 at 01:51
41

Just incase there are any nginx server users stumbling upon this question, both the 'PassengerMaxRequests' and 'PassengerStatThrottleRate' directives don't translate to nginx. However the others do:

rails_spawn_method smart;
rails_app_spawner_idle_time 0;
rails_framework_spawner_idle_time 0;
passenger_pool_idle_time 1000;

HTH!

EDIT rails_spawn_method is deprecated in passenger 3 instead use

passenger_spawn_method smart; 

everything else is just good till date.

Pritesh Jain
  • 9,106
  • 4
  • 37
  • 51
Gav
  • 11,062
  • 7
  • 33
  • 35
  • 7
    Thanks for this. One thing to note is that I had to stuff the passenger_pool_idle_time in my main nginx.conf with the other global settings instead of just in the specific site config where rails was enabled. – Scott Arrington Jun 28 '10 at 18:08
  • but error on passenger 4: `"passenger_max_preloader_idle_time" directive is duplicate` – Moon soon Jun 09 '15 at 13:38
5

You can also use PassengerMinInstances:

http://www.modrails.com/documentation/Users%20guide%20Apache.html#PassengerMinInstances

This can be combined with PassengerPreStart

Josh
  • 8,329
  • 4
  • 36
  • 33
  • From the docs: "You should set this option to a non-zero value if you want to avoid potentially long startup times after a website has been idle for an extended period." Seems like the perfect answer for the OP's question. – Chuck Feb 26 '13 at 15:45
2

RE:

# Additionally keep a copy of the Rails framework in memory. If you're 
# using multiple apps on the same version of Rails, this will speed up
# the creation of new RailsAppSpawners. This isn't necessary if you're
# only running one or 2 applications, or if your applications use
# different versions of Rails.
RailsFrameworkSpawnerIdleTime 0

Just something to add and might be useful.

The default spawn method in the current release is "smart-lv2", which skips the framework spawner, so setting the framework spawner timeout wouldn't have effect anyway unless you explicitly set the spawn method to "smart".

Source: http://groups.google.com/group/phusion-passenger/browse_thread/thread/c21b8d17cdb073fd?pli=1

Shuoling Liu
  • 491
  • 6
  • 19
1

If your host is a shared server, like mine, you can't change the settings and are stuck with a cron job.

  • For this particular application thankfully it's not. But I'll bare that in mind for the future thanks. – tsdbrown May 13 '09 at 08:27
1

I had also this problem but I was not able to change the passenger settings because I had no write permission to this file. I found a tool ( http://www.wekkars.com ) that keeps my app responding fast. Maybe this can also be a solution for you.

SteenhouwerD
  • 1,819
  • 1
  • 16
  • 22
0

check the version of passenger. it was RailsSpawnMethod <string> for old versions.

If so (if I remember correctly), replace Passenger with Rails in all the configuration directives or look for old passenger docs for more details

j0k
  • 22,600
  • 28
  • 79
  • 90
JmJ
  • 1