What have you found for these years?

2013-04-13

Re: Regarding the recommended Ruby app server

Last mail.

updated 2013-04-14 00:59
Here's the DoS attack script.

from: Lin Jen-Shin (godfat)
date: Thu, Apr 11, 2013 at 12:48 AM
subject: Re: Regarding the recommended Ruby app server

As what I said before, the concern is for slow clients. The slower
the clients are, the bigger the concern would be.

I just wrote some simple testing codes which I hope can demonstrate
the concern.

Running `./bench.sh` would create a dummy 5M payload which would be
sent via `ab -n 10 -c 5`. You could play around the numbers. The
application code is simple, please see `config.ru`.

The application basically only does multipart parsing, and nothing
else. I am not sure if Rails would be doing this lazily or eagerly,
but whenever you're calling `params` in a Rails action, it would
definitely do this.

You can see there's a huge difference between running Unicorn or
Rainbows! with EventMachine. With Unicorn, the `diff` time would be
quite long, because Unicorn doesn't read the body for you. The read
time would be spent in the application. That means, the Unicorn worker
is blocked until the uploading is done. You can try a sort of DoS
attack which sends a ton of requests with never ending body to
applications whichever try to parse the request body with Unicorn.

While running Rainbows! with EventMachine, the `diff` time would be
quite short, because Rainbows! would be buffering the body from the
request, and only pass it down to the application whenever it is fully
buffered. The read time would be spent in EventMachine, which won't
block the worker from processing the other fast clients.

However, this is still suffering from head-of-queue blocking issue.
Consider the application does some heavy computing. Let's say it's
sleeping for 5 seconds.

Since Rainbows! with EventMachine is still single threaded, if the
application is sleeping for 5 seconds, during this period,
EventMachine cannot handle the other clients, blocking/idling them.
We can't see this issue in this test though. You can add a sleep
there to experiment this.

By my simple benchmark, Unicorn completed ten 5M requests in 46
seconds. Rainbows! with EventMachine completed the same set of
requests in 35 seconds. It might not be dramatically, but that's
only ten requests. I didn't test it extensively so it might not
be accurate though.

For reference, the benchmark was run on Rackspace (Arch Linux) and
hitting http://slow-uploading.herokuapp.com/

*

At the moment, if people are not willing to try my EventMachine with
threads
implementation in my last mail, I would recommend out-of-box
Rainbows! with EventMachine as a start.

Or rather, using Nginx and Unicorn together might be even better. I
would love to collaborate with you to try out buildpack to build a
statically linked Nginx while deploying. I never tried it before.

By the way, do you know dotCloud?
It allows you to upload an Nginx config to run your custom Nginx. It's
quite useful. Hope Heroku could also provide something like that.

0 retries:

Post a Comment

All texts are licensed under CC Attribution 3.0