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-dev python-virtualenv $ virtualenv webservice $ . webservice/bin/activate $ pip install gevent gunicornWell, 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.
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 webservice $ cat > application.py #!/usr/bin/env python def application(environ, start_response): start_response("200 OK", [("Content-type", "text/plain")]) return [ "Hello World!" ]Just in case you're not familiar with UNIX, press Ctrl-D after the last line to save the file.
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/ 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)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.