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.
[

http://www.napcs.com/products/rails/reverse_proxy_fix/index.html](http://www.napcs.com/products/rails/reverse_proxy_fix/index.html)

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