I often read about Nginx and Mongrel being used together. Can someone explain to me how they are different? Why is Mongrel needed? Why is it not advisable to have Nginx directly communicate to the many Rails servers?
Both are web servers, but they do not share the same focus :
- Mongrel is basically a ruby application server that presents an HTTP Interface. It does one thing, taking a request, passing it to your ruby code and serves the answer back in http. It does not handle concurrency, or any performance related feature. One mongrel means there is one ruby process that will handle requests.
- Nginx is a fully featured web server, aimed at performances. It can deliver high performance on static files and can't handle Ruby, Python or any other language in a direct manner. It relies on FastGCI or proxying to other application servers to do that.
To be clear, your rails app by itself isn't directly usable, it needs what you can call a container (I suggest you read some about http://rack.github.com/), in this case Mongrel. When you run rails console, it's usually webrick, the most basic web "app" server we have in Ruby (it's part of the standard library).
Then why do we use Nginx in front ? Let's consider we use only Mongrel : we fire a mongrel instance, listening on the port 80. If your requests takes for example 500 ms to complete, you can handle 2 clients per second any nothing more. But wait that's clearly not enough. Let's fire another mongrel instance. But we can't have it listen on the port 80 since it's already used by the first instance and there's nothing we can do about it.
So we need something in front that can handle multiple Mongrel instances, by still listening the port 80. You throw in a Nginx server, that will (proxy) dispatch the requests to your many mongrel instances and you can now add more instances to serve more clients simultaneously.
Back to answering your question, having NGinx communicating to a rails server, means firing one or many Mongrel (or Thin / Unicorn, whatever server is available) and informing NGinx it has to pass the requests to them. It's a popular pattern to host rails services next to using Passenger, which basically provides a way for Apache workers to handle ruby code.
Difference between Nginx and Mongrel
Both are indeed HTTP server, but their focus is different. Mongrel is a fast HTTP server aimed mostly at Ruby-based applications. it's easily extensible with Ruby code. However, it's not very good at serving static files, i.e. it's slower than Apache and nginx. Also, Rails is single threaded, meaning that during the course of a request (calling a controller method until the actual rendering) the mongrel is locked.
To work around the above mentioned disadvantages of Mongrel and Rails, the preferred setup in a production app is to put either Apache or nginx as the main webserver and if a request for a non- static Rails page is received, to pass this to a number of underlying mongrels, let the mongrel hand back the rendered page to Apache/nginx and serve that page, together with static files such as images/ stylesheets/… It might seem a bit daunting and complex at first, but once you actually implement it, it's extremely powerful and stable (I have several apps that have been running for months to years on a server without a single restart). It boils down to this, let Apache/nginx do what it's best at, let the mongrel cluster do what it's best at, everybody is happy.
Choosing nginx over Apache is mostly based on memory considerations. Apache is quite a hefty webserver, especially if all you actually do is serve some static files with it and balance the rest over a bunch of mongrels. Nginx is very lightweight and performant and can do the same job just as good as Apache. But if you're familiar with Apache, don't want to get the grips with nginx configuration and have lots of memory on your server, you can still go for Apache. On a basic VPS, nginx is a more suitable approach.
for your more information
Apache vs Nginx
They're both web servers. They can serve static files but - with the right modules - can also serve dynamic web apps e.g. those written in PHP. Apache is more popular and has more features, Nginx is smaller and faster and has less features.
Neither Apache nor Nginx can serve Rails apps out-of-the-box. To do that you need to use Apache/Nginx in combination with some kind of add-on, described later.
Apache and Nginx can also act as reverse proxies, meaning that they can take an incoming HTTP request and forward it to another server which also speaks HTTP. When that server responds with an HTTP response, Apache/Nginx will forward the response back to the client. You will learn later why this is relevant.
Mongrel vs WEBrick
Mongrel is a Ruby "application server". In concrete terms this means that Mongrel is an application which:
- Loads your Rails app inside its own process space.
- Sets up a TCP socket, allowing it to communicate with the outside world (e.g. the Internet). Mongrel listens for HTTP requests on this socket and passes the request data to the Rails app. The Rails app then returns an object which describes how the HTTP response should look like, and Mongrel takes care of converting it to an actual HTTP response (the actual bytes) and sends it back over the socket.
WEBrick does the same thing. Differences with Mongrel:
- It is written entirely in Ruby. Mongrel is part Ruby part C; mostly Ruby, but its HTTP parser is written in C for performance.
- WEBrick is slower and less robust. It has some known memory leaks and some known HTTP parsing problems.
- WEBrick is usually only used as the default server during development because WEBrick is included in Ruby by default. Mongrel needs to be installed separately. Nobody uses WEBrick in production environments.
Another Ruby application server that falls under the same category is Thin. While it's internally different from both Mongrel and WEBrick it falls under the same category when it comes to usage and its overall role in the server stack.
© 2022 - 2024 — McMap. All rights reserved.