Mod_rails aka mod_rack aka mod_ruby

On Wed, Jun 11, 2008 at 5:52 PM, Thomas [email protected] wrote:

If you want a web server that can handle rails, use
apache+mod_passenger. If you want php, then use apache+mod_php.

There are so many advantages of separating mongrel from nginx (for
instance), so for once and for all leave Nginx as lean and efficient
as possible, that’s the way I love it.

Agree. People who want mod_whatever do not understand that it’s bad
design.

Honestly making Nginx and mongrel talk to each other is really easy.
It takes me a few minutes to set this up I don’t understand why people
are scared in setting up an additional server with such ease. Believe
me there are many other places where you will pull your hair.

Separating Nginx from Mongrel is much more robust than embedding
mod_rails in Nginx.

Dan M ha scritto:

On Wed, Jun 11, 2008 at 5:52 PM, Thomas [email protected] wrote:

If you want a web server that can handle rails, use
apache+mod_passenger. If you want php, then use apache+mod_php.

There are so many advantages of separating mongrel from nginx (for
instance), so for once and for all leave Nginx as lean and efficient
as possible, that’s the way I love it.

Agree. People who want mod_whatever do not understand that it’s bad design.

This can not be generalized.

The main problem is that separating the main server from the application
server means that you need to implement another server!

Implementing a robust/scalable/efficient server is not an easy task, so
using mod_whatever is the best solution (assuming, of course, that the
application is designed to taking advantage of being embedded in a
server).

Manlio P.

I think FastCGI behind nginx is a highly scalable model. You get
excellent
performance via unix domain sockets and fault tolerance by the fact that
the
FastCGI processes are independent of the web server and that you can
partition your traffic across pools of FastCGI processes listening on
different sockets. If your application divides naturally into areas of
functionality (say, API calls versus website traffic), you can route
those
to separate FastCGI sockets so that traffic backed up on one does not
adversely affect the other (except perhaps at the DB level).

Under Apache, mod_fastcgi provided a process manager to monitor FastCGI
daemons but that ties you to Apache + it’s concurrency model (1 request
per
thread/process). With lighttpd and nginx, it seems like there’s a hodge
podge of solutions such as using cgi-fcgi or spawn-fcgi to spawn FastCGI
processes but these don’t have process management. Rails has utils
called
spinner, spawner, and reaper but these don’t support unix domain sockets
and
only assign one ruby process per socket.

Supervisor (http://supervisord.org/) provides a
language/platform/framework-agnostic, full-service process manager
(including restarts with backoff, groups of identical processes, remote
management, pluggable event handling, and pluggable RPC customization)
that
can be used with any web server. I recently added support for managing
FastCGI processes. The changes are in the trunk and not yet released as
an
official version.

Roger

On Thu, Jun 12, 2008 at 4:24 AM, Manlio P.
[email protected] wrote:

This can not be generalized.

Of course it can. There are bad designs, and there good designs.
Apache’s mod_* is an example of bad design from the viewpoint of
security and reliability. The modules are loaded into the web server.
If one of the modules is compromised or buggy the whole system is
compromised or buggy. Also large amounts of RAM need to be used for
all the mod_*. Also the security boundaries cannot be set between
modules because they’re just one process. The analogy can be made
between Sendmail and qmail. Sendmail is monolithic and not modular.
qmail is modular. Look how many exploits Sendmail had… Sendmail is
also slow and hard to administer.

The main problem is that separating the main server from the application
server means that you need to implement another server!

Yes, and that’s GOOD - modular design.

Implementing a robust/scalable/efficient server is not an easy task, so
using mod_whatever is the best solution (assuming, of course, that the
application is designed to taking advantage of being embedded in a server).

It’s not, you are just hung up on this idea for some reason. I think
you may be thinking that mod_* is MUCH faster, while in reality it’s
not that much faster. If you weigh benefits vs. risks it’s not worth
it. Web servers are web servers, and applications are applications.
This is also the original UNIX mantra (many little programs each doing
its specific little purpose) that Apache and Sendmail do not follow.

Okay, people, let’s sum this thread up.

Creting mod_rails/mod_ruby/mod_rack is not a good idea. There are some
ideas why such a module might be useful, but for every such idea
there’s an explanation why it actually won’t work. I’ll try to
summarize them here:

  • Making mod_r* makes things work faster. True indeed, but the
    ‘things’ we’re talking about in here are just passing HTTP request to
    the Rails/Rack app. But everyone surely knows that it’s the time spent
    inside Ruby/Rails is the most critical part, not passing HTTP request
    to it.

  • mod_r* would ease configuration. Yeah, it’s really ridiculous.
    Configuration of such module would be pretty much bound to it’s
    implementation, for example one would have to choose number of child
    processes, subinterpreters etc. Pretty troublesome.

  • Making a HTTP server is hard, so let’s make mod_r*. Tricky one.
    Making fast, robust, reliable etc. HTTP server (like the one whose
    name starts with N and ends with x) is difficult. So is creating good
    mod_r* module. It’s far more easier to create simple HTTP server like
    Mongrel or run R* app via FastCGI.

So these are the main arguments why mod_r* might be good idea and
explanations why these arguments do not hold. But the main reason why
mod_r* is bad (i.e. the one reason that convinced me) is the
‘separation of concerns’/‘bad design’ reason. Those two things really
should not go together.

Thanks for all the input and a very interesting discussion. You taught
me a lot, guys!

Cheers,

Mike

Dan M ha scritto:

all the mod_*. Also the security boundaries cannot be set between
modules because they’re just one process.

As I have said, you are generalizing.
Embedding in Nginx is quite different than embedding in Apache.

The analogy can be made
between Sendmail and qmail. Sendmail is monolithic and not modular.
qmail is modular. Look how many exploits Sendmail had… Sendmail is
also slow and hard to administer.

The main problem is that separating the main server from the application
server means that you need to implement another server!

Yes, and that’s GOOD - modular design.

Ok.
But, please, tell me what’s the the difference if this “backend” server
is implemented in pure Python or embedded in Nginx!

[…]

Manlio P.

If the module inside Nginx crashes, Nginx crashes too. If the python
or ruby backend server outside Nginx crashes, Nginx will stay be
alive.

Thomas ha scritto:

If the module inside Nginx crashes, Nginx crashes too.

Wrong.
Only the worker process crashes, not Nginx.

[…]

Manlio P.

And what happens when you run out of worker processes? When the module
crashes are you sure it releases all its memory?

On Fri, Jun 13, 2008 at 05:09:18PM +0200, Thomas wrote:

And what happens when you run out of worker processes?

The master process respawns a new worker process.

When the module crashes are you sure it releases all its memory?

The kernel reclaims process memory.

On Fri, Jun 13, 2008 at 6:24 AM, Manlio P.
[email protected] wrote:

As I have said, you are generalizing.
Good.

Embedding in Nginx is quite different than embedding in Apache.
It’s still embedding. Let web servers be web servers and application
servers and languages be separate.
Roger H. put it well in the above post.

Ok.
But, please, tell me what’s the the difference if this “backend” server is
implemented in pure Python or embedded in Nginx!

The difference is it’s not embedded in nginx. We have plenty of
bloated and insecure software.

On Sat, 2008-06-14 at 17:57 -0400, Dan M wrote:

On Fri, Jun 13, 2008 at 6:24 AM, Manlio P.
[email protected] wrote:

Embedding in Nginx is quite different than embedding in Apache.
It’s still embedding. Let web servers be web servers and application
servers and languages be separate.

In general I agree with the sentiment that embedding languages (ala
Apache’s mod_python) is bad. However, in fairness, the recommended
deployment for Manlio’s mod_wsgi it to not run it in your main Nginx
instance, rather to run a specialized Nginx instance that is proxied to:

Plain Nginx → Nginx+mod_wsgi → application

While this might seem like splitting hairs, the difference is that
rather than looking at it as embedding your application in Nginx, you
should look at is as your application using Nginx as an application
server (in the specific case of Python, you would be using Nginx rather
than, say CherryPy’s HTTP server). This means you can alleviate some
security issues by running that instance as a less privileged user, the
“bloat” is restricted to this instance (and probably not much worse than
any other Python application), etc.

Regards,
Cliff