Hacker News new | ask | show | jobs
by cperciva 6332 days ago
Sad town happens. 1 in 4 requests after Request A will go to port 8000, and all of those requests will wait in line as that mongrel chugs away at the slow request...

I don't use Rails, or even Ruby at all if I can avoid it, so I'm sure I'm missing something obvious here, but... why in the world would anyone want to use a web server which can only handle one request at once?

4 comments

It's not the webserver, it's Rails; prior to 2.2 it used a Big Giant Lock around the dispatcher, so it would serialize requests.

Of course, even without that Ruby itself will only use a single CPU, since the interpreter itself has a Big Giant Lock, but it can still use threads to multiplex requests and avoid wasting time waiting on every IO.

JRuby allows for proper concurrent multithreaded request handling; I'm surprised it's not a more popular deployment option.

Sorry, what's the platonic ideal you're suggesting as an alternative? There are threaded Ruby web servers, but, just like with Python, the interpreter is mostly giantlocked. The overwhelming majority of web apps out there are running under Apache, which just like Mongrel is preforking and queueing, not running everything simultaneously.
If you have N requests hitting Apache and one of them is slow, that one slow request will run in its own process while the fast requests are sent off to other processes. The fact that each process only handles one request at once is irrelevant.
Uh, this is how Rails setups work too. You aren't talking directly to Mongrel.
Maybe I misunderstood the article -- it sounded to me like requests were being distributed between Mongrel processes and queued on the individual processes rather than being queued centrally and only allocated to individual processes when a process is free (like Apache does).
The problem with Mongrel is that you allocate N mongrel instances at setup time. Apache, on the other hand, can dynamically allocate new processes (up to a limit) in order to meet increased demand. This is especially important for people like me, who host more than one site on a machine, and want to be able to handle load up to a certain point without fiddling with config files every time there is a spike in traffic.
That's correct -- the load balancer passes the traffic directly to Mongrel, and each mongrel has its own internal queue / mutex.

That's why you run like 4 or 8 or 12 or N many mongrels to handle additional load.

"Sorry, what's the platonic ideal you're suggesting as an alternative?"

Something like Yaws, built in Erlang. With fine-grain threading that works well, you don't get the one-to-one OS process to task mapping.

But that certainly comes with its own set of tradeoffs. There are some workloads where that can be a massive win, but committing to any of the currently still-obscure languages/runtimes that can pull this off with panache means you're committing to a less-well-developed library environment.

Facebook chat runs on Erlang for a reason... and the rest of Facebook runs on PHP, also for a reason.

I get that feeling too every time I read an article like this.

I develop 90% of my stuff on the Microsoft stack, and it just plain handles anything you can throw at it out of the box. We see 2,000,000 pageviews a day steady state, and very seldom lift the CPU off of zero, with nothing more than bread and butter index and stored procedure tuning.

With that as a baseline, I just don't see why all these little startups are having such problems just keeping their website up under a little traffic. I can't believe that these scripted ORMs are really that inefficient that you'd need to spend this amount of effort bolting 3rd party stuff onto them just to keep them alive.

There has to be something else going on. What, exactly am I missing here?

Mongrel is multithreaded, solid, and fast, the issue was with, which Rails wasn't thread-safe until a little while ago.