Mongrel Performance Issue

I have Mongre'/Apache set up and serving up a ROR website which has some images. I followed these instructions,

http://mongrel.rubyforge.org/docs/apache.html

My problem is that it is so slow, it's useless.

How can I begin to optimize? Anyone?

Thanks, Jim

Have you checked out the tuneup guide on the mongrel site?

Also, read: http://rubyforge.org/pipermail/mongrel-users/2006-September/001548.html

and don’t worry about Zed calling you “a stupid moron,” he does that to all of us. Because he loves us.

Did you use the first proxypass instructions? If so, mongrel is serving up all your static content, and is not terribly great at that. Apache is. Scroll down and use some rewrite rules to forward static requests to either the proxy or a mongrel_cluster of 1.

Have you checked out the tuneup guide on the mongrel site?

Also, read: http://rubyforge.org/pipermail/mongrel-users/2006-September/001548.html

and don't worry about Zed calling you "a stupid moron," he does that to all of us. Because he loves us.

I call myself a stupid moron too, the problem is universal among programmers for some reason. :slight_smile:

Did you use the first proxypass instructions? If so, mongrel is serving up all your static content, and is not terribly great at that. Apache is. Scroll down and use some rewrite rules to forward static requests to either the proxy or a mongrel_cluster of 1.

Yes definitely look at how things are configured and make sure that you've ruled out all the usual suspects like mongrel serving files and too much stuff on one server.

Zed, Anyone,

I have been playing with RoR & more recently Mongrel & have at last almost got the set up I consider to be the smartest (I am sort of emulating mod_jk which is fantastic for using a context in a url to direct specific urls to any tomcat on any nearby computer). In effect I can't & don't want to use Virtual Hosting plus I am condemmed to used Win2003 for our corporate servers.

Mongrel has been fantastic for what I am doing. This is what I do to redirect Apache (2.2.3) traffic coming in on port 80 to my mongrel app on port 8087 ...

1) In the <app>\config\routes.rb file I change map.connect ':controller/:action/:id' to map.connect 'ms01/:controller/:action/:id'

(this adds a context into the url *but* only for the dynamic content. By this I mean that for all RoR generated urls for dynamic content, RoR adds ms01/ and in Apache conf all I add is ...

ReWriteEngine on ReWriteRule ^/ms1/(.*) http://localhost:8087/ms1/$1 [P]

(for me ms1 = Mongrel service one)

Now without the uneeded gumph of Virtual hosts I can tell my Apache to go to any Mongrel server I want, on any port, and or any other server & we do plan to have different apps on different servers as well as some on the same server as Apache.

BUT, in RoR the static urls don't get the ms1/ added - RoR when looking for <app>\public (for images, stylesheets and javascripts), goes to the Apache server's default homedir I there is no rewrite rule I can think of that can identify the static url of one particular app vs any other app.

The problem I have is that doing what I am doing means that all static content such as images/stylesheets and javascripts for all apps must be placed on the one server in one folder while I can put the dynamic content anywhere.

Ideally RoR would give me an option to add the ms1\ string onto the front of my static content urls just as it now adds ms1\ onto the front of my dynamic urls. If I could add a context string (even better if for example I could make it different to the dynamic content url (i.e. for dynamic add ms1d\ and on the static content add ms1s\ then I could direct Apache to where ever I like for either type of content - even both contexts to the same server if I wanted - all the control is in the Apache conf file.

If anyone can suggest a way or a ReWriteRule or a Condition that would allow me to identify incoming urls to Apache, both static content and dynamic content, and to identify which <app> these urls belong to, I will have a very flexible way of implementing multiple apps on multiple servers. With Java/Apache & Tomcat, I have this today with mod_jk. I feel I am so close to getting this same flexibility in RoR.

Thanks

Doug M (IT Tech Architect & one big Rails & Mongrel fan)

Zed Shaw wrote:

CORRECTION

In the first few lines I refer to ms01\ but I later decided to use ms1\ but missed correcting the 1st 3 or so references.

The ms1\ could be any context string one likes we here actually use a very formal wssp01\ for deploying web services on Tomcat - it stands for web service service point # 1 mssp01\ Mongrel Service Service PZoint #1

etc:

DSM

I wrote a plugin for Rails apps that might do exactly what you need. It’s designed to handle this sort of problem. You leave your routes alone (standard routes) and apply the prefix in the configuration file for the plugin.

It’s meant to handle dumb reverse proxies, so it expects the full front-side URL. (http://www.foo.bar/ms1 ) but it works like a charm, rewriting all URLs appropriately.

The nice thing is that it only applies this fix in production mode so you can continue to develop your app locally without having to enable / disable the plugin. [

Reverse Proxy Fix Plugin | New Auburn Personal Computer Services LLC](Reverse Proxy Fix Plugin | New Auburn Personal Computer Services LLC)

Let me know if this works for you.

Brian,

Many thanks - this does handle reverse proxying. It also appears to handle the urls. What is not clear to me is if it addresses the issue that RoR adds prefixes onto dynamic content but not static content (public: images, stylesheets and javascripts).

If I had an add-in that allowed me to nominate a url context (such as ms1/) that was to go on the front of the static content (the stuff we normally have to put in /public/ ) I know this would mean I then have to create a folder ms1/ in /public/ and move the static content for this app from /public/ to /public/ms1 for testing and production.

You fix is great for production but it appears designed to cater for the base machine url. What I need is the ability to redirect urls based on the application they are aimed at (using a context such as /ms1 in the url).

http://www.myserver.com/ms1/index.rhtml I can make this work in routes.rb http://www.myserver.com/stylesheet/name.css - RoR does not apply the routes.rb change to this url & it cannot be intercepted on apache.

Cheers

DSM

My plugin does handle that. It modifies the URLs for requests and also deals with the static files by modifying the value of asset_host. The reason it was written was so that I could run Mongrel on Windows behind IIS which has little to offer in the way of a decent reverse proxy.

Just for clarification:

Yes it is catered towards using the machine’s base URL… but in theory it should work if you just used /ms1 as the base_url instead of a full path.

It simply prepends urls with whatever is in the base path. In theory you’d place this on a linux box with several instances on ( backend.mydomain.com) and set the base_url to http://www.mydomain.com/ms1 and set appropriate proxying. All requests created by Rails would be rewritten to use the frontend address.

Of course, this only works if you have used the Rails helpers to generate your links.

I contributed some stuff to the upcoming Rails Deployment book about these types of setups… but I have some older articles that might help you out.

http://www.napcs.com/howto/rails/deploy/index.html

See the one titled ‘Serving Multiple Rails Applications on Windows with Apache and Mongrel’. I do it without using VHOSTS. Some of the steps are a little out of date because Mongrel has changed a bit, but I’m not updating anything because of the book.

Brian

Many thanks for your input

I will read up that info.

Also just on the offchance - did you use to work in IBM's Smalltalk Team There was a Brian Hogan there that I had dealings with when IBM released VisualAge Smalltalk, as soon as I saw your name & an association with Ruby I wondered

Cheers

Doug M

Brian,

I read the doc 'Serving Multiple Rails Apps on Windows with Apache & Mongrel & that is indeed enough to meet what I want.

I think that since you wrote that there is now a good mod_proxy module for Apache so your input has given me some ideas to try first but without doubt your mod will do it.

Many thanks

Doug Marker

@Doug:

Glad I was able to point you in the right direction.

I have never worked at IBM :slight_smile:

Brian,

One other question I have is it would be fantastic to be able to use a mod like you have created (more I look at it the better it looks :slight_smile: ) to be able to optionally set a different url prefix for static content. This increases the flexibility markedly.

Mongrel isn't so good at handling large volumes of static images & no one really wants to create say 6 apps on different Mongrel instances (perhaps on different servers) but have to put the static input for all these apps in one common directory because of the urls RoR generates for static input have no identifying contexts to use in proxy redirection & I gather that you mod uses the same url for both static and dynamic content. Mongrel doesn't have (IIRC) the ability to further redirect requests for static content (such as images) to another server (even if it could it becomes messy)

Cheers

Doug M

Brian,

Having reread all the info in your posts & done some delving into 'asset_host' I have succeeded in achiving all the goals I set out to.

I have multiple apps. Apache as the front-end, have activated Mod_rewrite & Mod_proxy etc:

Each apps urls are split into dynamic content and static content. and each has its own url prefix examples For app1 dyna content = http://myapachesvr/ms1d/store For app1 static content = http://myapachesvr/ms1s/stylesheets/somestylesheet.css

Apache sees the ms1? context & using rewrite & proxying rules directs each type of content for this app, to the appropriate location.

This is simple & works well. I can place the static content on apache in sep folder for each app and let mongrel instances serve the dynamic content.

Performance seems fine.

Cheers

Doug M