And worse - the usual LAMP stack is terrible at handling anything that's actually asynchronous in nature, like WebSocket or Comet. It can also be a pretty big security hole as well, see Slowloris.
And yet, you have to read lengthy manuals and fiddle with lengthy config files to get anything done with the traditional web servers - instead of getting shit done, like, right now. Seriously, this is 2011. You're doing more for less if you're sticking to the 2000 ways.
Let's try another way.
So, let's say you have a usual Ubuntu, or Debian, or the more trendy Mint machine. Try this in your home directory:
$ sudo apt-get install libevent-2.0 libevent-dev python-virtualenvWell, congratulations! You've already got a self-contained web server package installed with the above four lines of shell commands! If your Linux machine has libevent and virtualenv installed already, you can even cut out the first line.
$ virtualenv webservice
$ . webservice/bin/activate
$ pip install gevent gunicorn
So, 3 lines of shell code to get the infrastructure ready.
The Apache guy is.. eh.. still looking through the manual pages for how to set up virtual hosts. We'll get back to him later, after the late-night news, supper, and.. watching grass grow.
Now, for the web server's content, we'll try a Hello World first. It'll be a Python script for now - we'll make it more like a real web server (i.e. serves your .html, .js, .css and runs scripts and frameworks just like your Apache, nginx, etc.) in another post.
$ cd webserviceJust in case you're not familiar with UNIX, press Ctrl-D after the last line to save the file.
$ cat > application.py
#!/usr/bin/env python
def application(environ, start_response):
start_response("200 OK", [("Content-type", "text/plain")])
return [ "Hello World!" ]
So, 3 lines of Python code to make the server serve.. something.
Finally.. we start the web server:
$ gunicorn -w8 -k gevent --keep-alive 60 application:applicationAnd.. it's alive! It's running at port 8000 by default. You can see it in http://localhost:8000/
The performance isn't shabby as well, considering the web server part of it (i.e. gevent.pywsgi, which handles the underlying HTTP protocol) is written in 100% Python:
$ ab -c 32 -n 12000 http://localhost:8000/For comparison, Apache 2.2 running on the same machine, serving a static file does 12k requests per second. And you can pretty much forget about playing with Comets in it without a lot of configurations and modifications.
This is ApacheBench, Version 2.3 <$Revision: 655654 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking localhost (be patient)
Completed 1200 requests
Completed 2400 requests
Completed 3600 requests
Completed 4800 requests
Completed 6000 requests
Completed 7200 requests
Completed 8400 requests
Completed 9600 requests
Completed 10800 requests
Completed 12000 requests
Finished 12000 requests
Server Software: gunicorn/0.13.4
Server Hostname: localhost
Server Port: 8000
Document Path: /
Document Length: 12 bytes
Concurrency Level: 32
Time taken for tests: 1.182 seconds
Complete requests: 12000
Failed requests: 0
Write errors: 0
Total transferred: 1644000 bytes
HTML transferred: 144000 bytes
Requests per second: 10148.61 [#/sec] (mean)
Time per request: 3.153 [ms] (mean)
Time per request: 0.099 [ms] (mean, across all concurrent requests)
Transfer rate: 1357.77 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.2 0 4
Processing: 0 3 1.9 2 22
Waiting: 0 3 1.9 2 22
Total: 1 3 2.0 3 23
Percentage of the requests served within a certain time (ms)
50% 3
66% 3
75% 4
80% 4
90% 5
95% 6
98% 8
99% 11
100% 23 (longest request)
1 comments:
Does setting up gunicorn with gevent based workers solve the whole slowloris attack problem? As far as I know, gunicorn needs a buffering proxy to prevent slowloris attacks.
Post a Comment