|
|
I'm really happy to announce the release of FAPWS3-0.2 a WSGI webserver based on libev. This release include several bugfixes. You can got it on my github website: http://github.com/william-os4y/fapws3/tarball/v0.2Most importantly, with this release FAPWS becomes much more stable and useful. I've tested it with many different type of configurations and it has always resisted to my differents Stress tests (with ApacheBenchmark tool): - Django webpage with a complex (and ugly) sql command with 300 concurrent requests - Simple Django webpage with 300 concurrents requets - for a simple Jpg files I've got 3524#/sec. Thanks to give it a trial. William ANNEXES: ======== Tests with 300 concurrent requests. Heavy Django page: ------------------
Server Software: fapws3/0.2
Server Hostname: 127.0.0.1
Server Port: 8084
Document Path: /acts/2009/
Document Length: 24554 bytes
Concurrency Level: 300
Time taken for tests: 166.334 seconds
Complete requests: 1000
Failed requests: 0
Write errors: 0
Total transferred: 19772014 bytes
HTML transferred: 19667754 bytes
Requests per second: 4.81 [#/sec] (mean)
Time per request: 62375.084 [ms] (mean)
Time per request: 207.917 [ms] (mean, across all concurrent requests)
Transfer rate: 116.08 [Kbytes/sec] received
Much more simple Django page -----------------------------
Server Software: fapws3/0.2
Server Hostname: 127.0.0.1
Server Port: 8084
Document Path: /membres/Off/
Document Length: 4918 bytes
Concurrency Level: 300
Time taken for tests: 23.178 seconds
Complete requests: 1000
Failed requests: 0
Write errors: 0
Total transferred: 5290304 bytes
HTML transferred: 5154064 bytes
Requests per second: 43.14 [#/sec] (mean)
Time per request: 6953.497 [ms] (mean)
Time per request: 23.178 [ms] (mean, across all concurrent requests)
Transfer rate: 222.89 [Kbytes/sec] received
Simple jpg file ----------------
Server Software: fapws3/0.2
Server Hostname: 127.0.0.1
Server Port: 8084
Document Path: /static/images/img04.jpg
Document Length: 13974 bytes
Concurrency Level: 300
Time taken for tests: 28.369 seconds
Complete requests: 100000
Failed requests: 0
Write errors: 0
Total transferred: 1416300000 bytes
HTML transferred: 1397400000 bytes
Requests per second: 3524.99 [#/sec] (mean)
Time per request: 85.107 [ms] (mean)
Time per request: 0.284 [ms] (mean, across all concurrent requests)
Transfer rate: 48754.28 [Kbytes/sec] received
As promised, you can see here under results of performance tests I've made.
Machine: AMD Athlon(tm) 64 X2 Dual Core Processor 4800+ A
OS: Linux 2.6.27-ARCH #1 SMP PREEMPT
Benchmark tool: ApacheBench, Version 2.3 ($Revision: 655654 $)
Python: Python 2.6.1
Libev: libev-3.49
Methodology: run webserver and ApacheBench ("ab" in short) on the same host;
but I use "nice -n20" for "ab". Wait enough time between each run to assure all "waiting"
connections will be effectively closed (+- 1 minute on my machine). Execute each
tests 5 times and take one "ab" report which is representative (to avoid abnormal good/bad
results).
Observations (results are in the annexes):
Errors: we don't see it in the results here bellow, but neither Fapws2 neither Fapws3 have
generated errors.
Requests per seconds: Fapws3 is a bit better(10%) than Fapws2 for low number of concurrent
requests. Above 500 concurrent requests Fapws2 is a bit better (5%).
mean: Fapws3 has a better mean than Fapws2 for all tests.
median: Fapws3 is better for all tests
Standard deviation: Both are equal until 100 concurrent requests. Above Fapws2 is better.
To summarize I would say that, thanks to libev, Fapws3 is not too bad.
As comparison, I've added results of cherrypy (threaded). By the way Charrypy is not bad
at all ;-). We can see that, as expected (cherrypy is fully written with python),
that number of requests per seconds are much lower than Fapws. We also see the impact of
a threaded system on the Standard Deviation. With such a big standard deviation, user's
perception can be quite various.
William Annexes
| Fapws3-0.1 | Fapws2-0.3 |
Server Software: fapws3/0.1
Document Path: /test
Document Length: 13 bytes
Concurrency Level: 10
Complete requests: 10000
Requests per second: 5565.03 [#/sec] (mean)
Connection Times (ms)
min mean[+/-sd] median max
Total: 1 2 0.7 2 17
|
Server Software: fapws2/0.3
Document Path: /hello
Document Length: 13 bytes
Concurrency Level: 10
Complete requests: 10000
Requests per second: 4964.60 [#/sec] (mean)
Connection Times (ms)
min mean[+/-sd] median max
Total: 1 2 0.0 2 3
|
Server Software: fapws3/0.1
Document Path: /test
Document Length: 13 bytes
Concurrency Level: 100
Complete requests: 10000
Requests per second: 5798.24 [#/sec] (mean)
Connection Times (ms)
min mean[+/-sd] median max
Total: 1 3 4.4 2 212
|
Server Software: fapws2/0.3
Document Path: /hello
Document Length: 13 bytes
Concurrency Level: 100
Complete requests: 10000
Requests per second: 4847.79 [#/sec] (mean)
Connection Times (ms)
min mean[+/-sd] median max
Total: 12 21 1.1 21 28
|
Server Software: fapws3/0.1
Document Path: /test
Document Length: 13 bytes
Concurrency Level: 500
Complete requests: 10000
Requests per second: 4464.30 [#/sec] (mean)
Connection Times (ms)
min mean[+/-sd] median max
Total: 2 20 36.1 3 368
|
Server Software: fapws2/0.3
Document Path: /hello
Document Length: 13 bytes
Concurrency Level: 500
Complete requests: 10000
Requests per second: 4818.79 [#/sec] (mean)
Connection Times (ms)
min mean[+/-sd] median max
Total: 85 103 2.6 104 107
|
Server Software: fapws3/0.1
Document Path: /test
Document Length: 13 bytes
Concurrency Level: 1000
Complete requests: 10000
Requests per second: 4300.18 [#/sec] (mean)
Connection Times (ms)
min mean[+/-sd] median max
Total: 60 120 46.3 92 220
|
Server Software: fapws2/0.3
Document Path: /hello
Document Length: 13 bytes
Concurrency Level: 1000
Complete requests: 10000
Requests per second: 4594.43 [#/sec] (mean)
Connection Times (ms)
min mean[+/-sd] median max
Total: 11 154 92.7 221 680
|
| Charrypy-3.1.1 |
Server Software: CherryPy/3.1.1
Document Path: /
Document Length: 13 bytes
Concurrency Level: 10
Complete requests: 10000
Requests per second: 1040.73 [#/sec] (mean)
Connection Times (ms)
min mean[+/-sd] median max
Total: 1 5 105.4 3 9608
|
Server Software: CherryPy/3.1.1
Document Path: /
Document Length: 13 bytes
Concurrency Level: 100
Complete requests: 10000
Requests per second: 1910.31 [#/sec] (mean)
Connection Times (ms)
min mean[+/-sd] median max
Total: 0 26 268.2 3 4884
|
Server Software: CherryPy/3.1.1
Document Path: /
Document Length: 13 bytes
Concurrency Level: 500
Complete requests: 10000
Requests per second: 1250.71 [#/sec] (mean)
Connection Times (ms)
min mean[+/-sd] median max
Total: 1 228 659.8 5 6243
|
Server Software: CherryPy/3.1.1
Document Path: /
Document Length: 13 bytes
Concurrency Level: 1000
Complete requests: 10000
Requests per second: 1518.28 [#/sec] (mean)
Connection Times (ms)
min mean[+/-sd] median max
Total: 1 275 865.1 5 6324
|
Hello all, After several months of hesitations, work, trials and tests, I'm very happy to announce the first release of Fapws3. Fapws3 is a full re-write of Fapws2 but based on libev. Indeed, since the API changes in libevent (>1.4.0) we were forced to modify the libevent sources before compiling it, just for the usage of Fapws2. This was not really comfortable. Moreover, libev is incredibly very well documented. Fapws2 will stay open just for bug fixing, but my future work will now be focused on Fapws3. This has been successfully tested on Linux 2.6.27 and FreeBSD-6.1 with libev-3.49. Benchmark between Fapws2 and Fapws3 is on going and will be published as soon as possible. And because the number of people willing to discuss about Fapws is increasing, I've setup a dedicated mailing-list: http://groups.google.com/group/fapwsFeel free to join ;-). William ANNEXES: -------- source repository for version 0.1Download fapws3-0.1 as a tarball Git repository: http://github.com/william-os4y/fapws3/tree/masterDemo site running wsgi_wiki with Fapws3: http://fapws3.vmrt.homelinux.com/
Since the crash of my server: opensource4you.com, I've spent lot of time to recover my files from few old backups.
I've not yet find back my mailing-lists for fapws, but interested people can contact me at my new gmail account: william dot os4y at gmail.com
Sorry for disturbance.
William
Thanks to Piranha, I've discovered a git repository provider: github. The new fapws2 git repository is now: http://github.com/william-os4y/fapws2/tree/master. For interested people, I've got several good feedback about FAPWS2. Some of them have internet websites runnning without any problems. Some have even reported an uptime of +2 months without any issue. You are always free to send me your websites running with fapws2, if they are public, I'll be happy to talk about them ;-). My current work with FAPWS is to facilitate the integration with libevent. Indeed, for fapws2, I'm using a different methodology to parse URL than libevent does. This force me to modify the code of libevent (evhttp_handle_request); which is not a so good solution. William
I've stored all emails from the sivit.fr support team into one Yahoo folder. Even the emails send into the Yahoo Spam. As you can see under suddenly, all of the sivit's communications were filtered out by Yahoo as Spam. Indeed, they have used wrong email format with the fromaddress. That's why yahoo complains.  On that suddent email problem, they don't give any answers. They claim that I've been informed on time about the issue and the associated risks. But, between the first mail and crash of the machine, we hae only 10 hours. Which are the sleeping hours. This was, thus, rather impossible to treat them accordingly. More over, they never explained why the server has been destroyed. And for sure, they have never give any excuses. This is just my, bad, story with them. You should not be generalised, because, maybe, some customers are happy with their quality of service. Up to everyone to decide if they are trustable.
After a Technical intervention of sivit.fr, the dedicated server has been removed. The server opensource4you.com is, thus, no more available.
I'm no more trusting them and will surely no more use their services.
I'll keep you informed when a new repository will be setup.
William
On current multi core machine, I have the idea to run several fapws2 instances for complex websites. That way I will have several fapws2 server dealing each a part of the web application.
To stay with fapws2, that means that one instance will be a "front end" web server. He will querying the others.
But what is the best way to implement such proxy mechanism (by only using libevent, no threads) ? People having knowledge, references of document exaplaining it, ... are welcome ;).
William
I've just tried compiling fapws2 with the brand new libevent library. With all the changes that they have made inside libevent, I was suprised that fapws2 is running without major changes ;). Patch for libevent-1.4: Remove "static" for the procedure called "evhttp_handle_request" in http.c. FAPWS2 over-writte this procedure, thus it cannot be static ;(. I've provided my evhttp_handle_request (with backward compatibility), but the libevent development team has not include it ;(. On the most important feature of fapws2: performance, and based on my simple "hello world" sample, I see a small improvement: 6%. (633#/sec with libevent-1.4.3 against 594#/sec with libevent-1.3e). Additional tests must be made with this new library but the starting point is promising ;). William git repositoryTar file hereAnnexe Patch on the libevent-1.4.3 sources
[libevent]$ diff http.c http_orig.c
1936c1936
< void
---
> static void
with fapws2 based on libevent-1.4.3
[fapws2]# ab -n 1000 -c10 http://127.0.0.1:8080/hello
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Finished 1000 requests
Server Software: fapws2/0.3
Server Hostname: 127.0.0.1
Server Port: 8080
Document Path: /hello
Document Length: 13 bytes
Concurrency Level: 10
Time taken for tests: 1.579206 seconds
Complete requests: 1000
Failed requests: 0
Write errors: 0
Total transferred: 105000 bytes
HTML transferred: 13000 bytes
Requests per second: 633.23 [#/sec] (mean)
Time per request: 15.792 [ms] (mean)
Time per request: 1.579 [ms] (mean, across all concurrent requests)
Transfer rate: 64.59 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.2 0 3
Processing: 1 15 9.5 12 48
Waiting: 0 14 9.4 12 48
Total: 3 15 9.5 12 48
Percentage of the requests served within a certain time (ms)
50% 12
66% 13
75% 14
80% 15
90% 38
95% 42
98% 45
99% 46
100% 48 (longest request)
with fapws2 based on libevent-1.3e
[root@myhost fapws2]# ab -n 1000 -c10 http://127.0.0.1:8080/hello
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Finished 1000 requests
Server Software: fapws2/0.2
Server Hostname: 127.0.0.1
Server Port: 8080
Document Path: /hello
Document Length: 13 bytes
Concurrency Level: 10
Time taken for tests: 1.683275 seconds
Complete requests: 1000
Failed requests: 0
Write errors: 0
Total transferred: 105000 bytes
HTML transferred: 13000 bytes
Requests per second: 594.08 [#/sec] (mean)
Time per request: 16.833 [ms] (mean)
Time per request: 1.683 [ms] (mean, across all concurrent requests)
Transfer rate: 60.60 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.1 0 2
Processing: 1 16 9.5 13 58
Waiting: 0 15 9.4 13 55
Total: 3 16 9.5 13 58
Percentage of the requests served within a certain time (ms)
50% 13
66% 14
75% 16
80% 19
90% 29
95% 42
98% 44
99% 48
100% 58 (longest request)
I've just released the 0.2 version of FAPWS2 (Fast Asynchronous Python WebServer) which is WSGI compliant. With this release, several bug fixes has been done (binaries are better working, cookies, ...). Now, FAPWS2 can now serve Django application (GET and POST), the admin page is working too ;-). Please not that FAPWS2 has been developed based on libevent-1.3x releases (on linux, but has been reported to work on Mac-OSX too). TGZ: http://www.opensource4you.com/downloads/fapws2-0.2.tgzGit repository: http://www.opensource4you.com/cgi-bin/gitweb.cgi?p=fapws2;a=summaryYour feedbacks, comments, tests results, ... are very welcome. William
Nearly 1 month after my last post, I've got a working version of fapws using the http api of libevent. Thanks to a wonderfull book call "C in a nutshell", the python API documentation and to the google code search engine, I've been able to write the required code; but also to track memory leaks, debug, ... Thus, definitively YES, writing python API in C is not that difficult (for a python developer who don't know C) Concerning our WSGI webserver, it can serve +1100#/sec on my Athlon-XP 1.2Ghz. It can resist to massive C10k attacks and it can serve Django applications (look into the samples). It was really exiting and funny to write this peace of code and I would thanks all people who provide me help, feedbacks and productive remarks. I would also specially thanks Lateef J. who has guide me (more than the others) even concerning stupid questions I have had. Because of a better integration with C, this new fapws (called fapws2, see later) is +-40% quicker than fapws for the simple hello_world. For Django application, it runs 30% quicker than CherryPy 3.0.2 (thread base). (I'm not against cherrypy, which is a great webserver. But Cherrypy is, for me, the best one, thus the reference.). At least, Fapws2 prove that select based webserver can be a good alternative to thread base one. The goal was to show the feasibility and the capabilities, lot of works still need to be done on this peace of code. Do not use it others than for tests. The prove-of-concept is finished, now, based on the results, a project can start. In that context help of everyone is welcome: for testing, coding, documentation, and ... to find a better name (sounds that fapws is too close to fap which is not related to serious IT matters ;-) ). Source code is here: http://www.opensource4you.com/cgi-bin/gitweb.cgi?p=fapws2;a=summarytgz is here: http://www.opensource4you.com/downloads/William (william _:at: opensource4you :dot:_ com) PS: Like for my previous post, prove (apache benchmark) will come soon. (added on November, 10th) ANNEXE---------------- FAPWS2 performance on "hello world":
[root@myhost]# nice -n20 ab -n1000 -c10 http://127.0.0.1:8080/
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Finished 1000 requests
Server Software: fapws2/0.1
Server Hostname: 127.0.0.1
Server Port: 8080
Document Path: /
Document Length: 13 bytes
Concurrency Level: 10
Time taken for tests: 1.313237 seconds
Complete requests: 1000
Failed requests: 0
Write errors: 0
Total transferred: 105000 bytes
HTML transferred: 13000 bytes
Requests per second: 761.48 [#/sec] (mean)
Time per request: 13.132 [ms] (mean)
Time per request: 1.313 [ms] (mean, across all concurrent requests)
Transfer rate: 77.67 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.1 0 2
Processing: 1 11 13.0 8 107
Waiting: 0 10 12.3 7 107
Total: 2 11 13.0 8 107
Percentage of the requests served within a certain time (ms)
50% 8
66% 8
75% 8
80% 9
90% 33
95% 40
98% 41
99% 106
100% 107 (longest request)
FAPWS perofrmance on "Hello world"
[root@myhost]# nice -n20 ab -n1000 -c10 http://127.0.0.1:8080/hello
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Finished 1000 requests
Server Software: fapws/0.7
Server Hostname: 127.0.0.1
Server Port: 8080
Document Path: /hello
Document Length: 11 bytes
Concurrency Level: 10
Time taken for tests: 1.909155 seconds
Complete requests: 1000
Failed requests: 0
Write errors: 0
Total transferred: 112000 bytes
HTML transferred: 11000 bytes
Requests per second: 523.79 [#/sec] (mean)
Time per request: 19.092 [ms] (mean)
Time per request: 1.909 [ms] (mean, across all concurrent requests)
Transfer rate: 57.09 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 2 8 11.0 6 108
Processing: 3 10 9.5 8 110
Waiting: 0 6 8.9 5 108
Total: 13 18 13.3 14 112
Percentage of the requests served within a certain time (ms)
50% 14
66% 14
75% 15
80% 16
90% 43
95% 47
98% 49
99% 112
100% 112 (longest request)
On this example, FAPWS2 is 45% quicker than FAPWS.
It's now long time since my last post. This surely does not means that I'm stopping FAPWS, at contrary I'm more and more convinced that one of the beauty of Python reside in his gluing capabilities. This observation is probably not new to lot of people, but for my personal case it's better now than never ;-), no ? After that small philosophical intro, please go back to our main interest: integrate libevent within the python world. What's great with libevent is that since several release, they have introduced several HTTP low level APIs: send_reply, send_error, ... I've tried to use them thanks to pyrex, ctype and swig. With every of those tools I'm facing issues, problems, ... to get a webserver working correctly. Because I want FAPWS to be light, efficient and stable, I don't like the idea to add layers on which I don't have too much control. Hoooooo, I'm already hearing some voices ;-). The point is not linked with those tools, but more to my competencies to be able to have them working correctly. Indeed, when you are new to C (which is my case) and try to understand how to use swig, trust me, this is not piece of cake. Thus I'll use the simple, low level Python API for this project. This will be a way for me to learn C and C API of Python. Will it be easy to learn C from Python ? We will see. Any how, any helps are welcome ;-). Here after, you can see a minimalist webserver serving the famous "Hello World!":
import ctypes
import sys
libevent=ctypes.cdll.LoadLibrary('libevent.so')
def root_handler(req, *arg):
#print "got request:", req
libevent.evbuffer_new.restype=ctypes.c_void_p
#Build a buffer and put page content into it
buf=libevent.evbuffer_new()
libevent.evbuffer_add_printf.argtypes=[ctypes.c_void_p, ctypes.c_char_p]
libevent.evbuffer_add_printf(buf,"Hello world!\n\n")
#send the buffer with a return code of 200
libevent.evhttp_send_reply.argtypes=[ctypes.c_void_p, ctypes.c_int, ctypes.c_char_p, ctypes.c_void_p]
libevent.evhttp_send_reply(req, 200, "OK", buf)
return 1
def main():
#We just initialise and give the server address and port
libevent.event_init()
libevent.evhttp_start.argtypes=[ctypes.c_char_p, ctypes.c_short]
libevent.evhttp_start.restype=ctypes.c_void_p
http=libevent.evhttp_start('0.0.0.0',8080)
#we lik the call to root_handler at a request of "/"
FUNC=ctypes.CFUNCTYPE(ctypes.c_int, ctypes.c_void_p)
libevent.evhttp_set_cb.argtypes=[ctypes.c_void_p, ctypes.c_char_p, ctypes.c_void_p]
libevent.evhttp_set_cb(http,"/",FUNC(root_handler), None)
#we loop and wait events ;-)
libevent.event_dispatch()
#we close the loop
print "end loop main"
libevent.evhttp_free.argtypes=[ctypes.c_void_p]
libevent.evhttp_free(http)
if __name__=="__main__":
main()
Note: I don't know exsactly why, but the server does not stop when you hit " -c". You must kill it ;-(.
Amazingly, I'm able to get 1700#/sec on my 1.2Ghz Athlon.
Annexes:
[myhost ~]$ ab -n2000 -c10 http://127.0.0.1:8080/
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/
Benchmarking 127.0.0.1 (be patient)
Server Software:
Server Hostname: 127.0.0.1
Server Port: 8080
Document Path: /
Document Length: 14 bytes
Concurrency Level: 10
Time taken for tests: 1.170227 seconds
Complete requests: 2000
Failed requests: 0
Write errors: 0
Total transferred: 196000 bytes
HTML transferred: 28000 bytes
Requests per second: 1709.07 [#/sec] (mean)
Time per request: 5.851 [ms] (mean)
Time per request: 0.585 [ms] (mean, across all concurrent requests)
Transfer rate: 163.22 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.2 0 3
Processing: 2 5 2.5 4 15
Waiting: 1 5 2.6 4 15
Total: 2 5 2.5 4 15
Percentage of the requests served within a certain time (ms)
50% 4
66% 4
75% 7
80% 7
90% 9
95% 11
98% 13
99% 14
100% 15 (longest request)
[myhost ~]$
I'm really happy to announce that we've reached (I'm no more alone on this project) a first interesting objective with FAPWS: FAPWS-0.6!!! Indeed, We don't have memory leaks any more, the server is much more stable and the WSGI implementation is now rather complete (Thanks Alex). I've tested it with a simple Django wiki ( http://e-scribe.com/news/171) ... and it works :-)!!!. In this specific case the added value of FAPWS is not that big (114 #/sec vs 81 #/sec with lighttpd+flup-scgi). But If I look at my simple wiki (code is in the samples folder of the fapws .tgz), It can go up to 628#/sec!!!. Even with all those bugs fixes, WSGI adaptations, ... the overall performance of FAPWS remains at a very high level (for a python web server): 898#/sec. I would here thanks Alex for his very valuable collaboration related to WSGI; Roberto and Lateef for their tests, ideas and feedbacks (I really hope I've not forgot someone) The active users community is not that big, but the quality is there ;-); and most important we have lot of fun with FAPWS. As I've already said, don't hesitate to give your feedbacks, ideas, comments, ... William PS: - simple demo web site running FAPWS: http://www.opensource4you.com:8080/- Code repository: http://www.opensource4you.com/cgi-bin/gitweb.cgi- download: http://www.opensource4you.com/downloads/ANNEXES -----------
[root@bsdhome ~]# nice -n 20 ab -n 1000 -c10 http://localhost:8080/hello
This is ApacheBench, Version 1.3d <$Revision: 1.73 $> apache-1.3
Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright (c) 2006 The Apache Software Foundation, http://www.apache.org/
Benchmarking localhost (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Completed 400 requests
Completed 500 requests
Completed 600 requests
Completed 700 requests
Completed 800 requests
Completed 900 requests
Finished 1000 requests
Server Software: fapws/0.6
Server Hostname: localhost
Server Port: 8080
Document Path: /hello
Document Length: 11 bytes
Concurrency Level: 10
Time taken for tests: 1.113 seconds
Complete requests: 1000
Failed requests: 0
Broken pipe errors: 0
Total transferred: 112000 bytes
HTML transferred: 11000 bytes
Requests per second: 898.47 [#/sec] (mean)
Time per request: 11.13 [ms] (mean)
Time per request: 1.11 [ms] (mean, across all concurrent requests)
Transfer rate: 100.63 [Kbytes/sec] received
Connnection Times (ms)
min mean[+/-sd] median max
Connect: 1 4 1.6 5 16
Processing: 2 6 1.9 6 18
Waiting: 1 5 1.8 5 16
Total: 9 11 1.0 10 19
Percentage of the requests served within a certain time (ms)
50% 10
66% 11
75% 11
80% 11
90% 12
95% 13
98% 14
99% 19
100% 19 (last request)
I've been busy since last 2 months to fix several bugs in the current implementation. I've nevertheless add some minor features that increase a little bit the global performance: internal caching, refactory of some classes, ... Now fapws can resist nicely to massive attacks: - via the ApacheBenchmark tool with 100, 200, ... concurrent connections. - via 50 "wget -r" in parallel. - both combined. Fapws still need to be enhanced in the HTTP headers parsing. I suspect that it can crash is the header is not correctly formatted. Based on the same html page, Fapws can reached (on my machines) 728#/sec. This is a major step compared to CP or Twisted (198#/sec). But, we still have room for improvement, indeed I have 4235#/seq with Lighttpd. Many thanks for the different feedback, comments, suggestion and bug fixes I've received. William PS: - simple web site running FAPWS: http://www.opensource4you.com:8080/- Code repository: http://www.opensource4you.com/cgi-bin/pygitweb/views.py?project=fapws%2F.git
Now that several bugs are now fixed in the kernel of FAPWS. FAPWS is now much more stable and resits very correctly to C10K attacks. On my Gentoo PC (1.2Ghz), Fapws can perform 3x faster than Cherrypy-3.0. Not because CP3 is bad, but because the heart of FAPWS is written in C ( libevent). Thanks to libevent (and pyevent), you are able to run FAPWS on Windows, Linux, *BSD, Mac OSx and Solaris machines. As said before, FAPWS is targeted to run on small hardware (limited memory, ...) like several Virtual Dedicated Servers ( VDS) offer. Up to now, the WSGI implementation is quite simplistic. If people are willing to improve this part of FAPWS with me, they are welcome ;-) (william _at_ opensource4you.com) William. links: ANNEXE: --------------- (I've made 5 concurrent requests and started CP3 with 10 threads).
Server Software: fapws/0.5
Server Hostname: localhost
Server Port: 8081
Document Path: /hello
Document Length: 11 bytes
Concurrency Level: 5
Time taken for tests: 8.421295 seconds
Complete requests: 5000
Failed requests: 0
Write errors: 0
Total transferred: 570000 bytes
HTML transferred: 55000 bytes
Requests per second: 593.73 [#/sec] (mean)
Time per request: 8.421 [ms] (mean)
Time per request: 1.684 [ms] (mean, across all concurrent requests)
Transfer rate: 66.02 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 1 3 1.4 3 15
Processing: 2 4 1.7 5 17
Waiting: 0 2 1.7 2 13
Total: 7 7 1.6 7 18
Percentage of the requests served within a certain time (ms)
50% 7
66% 8
75% 9
80% 9
90% 9
95% 9
98% 10
99% 12
100% 18 (longest request)
Server Software: CherryPy/3.0.0beta2
Server Hostname: localhost
Server Port: 8080
Document Path: /
Document Length: 12 bytes
Concurrency Level: 5
Time taken for tests: 25.149331 seconds
Complete requests: 5000
Failed requests: 0
Write errors: 0
Total transferred: 710000 bytes
HTML transferred: 60000 bytes
Requests per second: 198.81 [#/sec] (mean)
Time per request: 25.149 [ms] (mean)
Time per request: 5.030 [ms] (mean, across all concurrent requests)
Transfer rate: 27.56 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 3 10 4.8 10 27
Processing: 6 14 4.9 15 30
Waiting: 0 7 5.9 7 26
Total: 23 24 1.7 24 35
Percentage of the requests served within a certain time (ms)
50% 24
66% 24
75% 25
80% 25
90% 26
95% 26
98% 32
99% 33
100% 35 (longest request)
As said in my previous post, the code of FAPWS is now available. As my repository is git, you can browse the code on my python gitweb. If you want to see it running, you can see a demo here. - FAPWS requires to have libevent and pyevent. - FAPWS works on linux and Windows. - FAPWS is based on WSGI. - FAPWS is very light. - FAPWS is very very fast!!! William
Yes, we can make fast web server with python! I'm quite amazed to see the speed of the python web server I'm building: 1024#/sec!!!. (via ab2 -n3000 -c50) My goal is to have the fastest python web server. After several research, trial, ... I've found apricot. If you look at my past posts, you'll see how fast it is. Because this code contains errors and because the author does not answer to my mails, I've decided to start a new one from scratch; but still based on pyevent. Then it will be easier to implement WSGI. This will them be the fastest WSGI web server ? ;-). Because of libevent, this is an "event" web server. This could be seen has a drawback, but has several advantages too. The tests were made between 2 machines connected via a switched network of 100Mb and by using ab2 (the Apache benchmark tool). I'm exited by such performance result and was impatient to share it. For sure, as soon as the code will be "polished", I'll make it available for everyone. William
I like the comparison Erik Wrenholt has made. Via a simple fractal program, you can evaluate the pure performance of different programs.
Since it's a bit outdated, I've re-execute it with last version of Python, Lua, Ruby, PHP and Haskell:
- Haskell ghc-6.4.2: 2sec
- PHP-5.1.6: 2.48sec*
- Python-2.4.3: 2.65sec
- Python-2.5: 2.78sec
- Lua-5.1: 3.4sec**
- Ruby-1.8.5: 10.18sec
* I'm using microtime() instead of time()
**I'm using os.clock() instead of os.time()
All those tests was done 5x on a Windows XP(Hurrgg sorry) machine with a 2-GHz Pentium M 760 and 1GB of RAM
UPDATE:
Based on a comment about psyco, here the result of the the script simply by adding:
import psyco
psyco.full()
at the top the script.
- python-2.4 + psyco 1.5.1: 0.37sec!!!
Same machine, same configuration, same methodology to make the test
To stay aligned with my previous post about python web framework performance, I've decided to validate Django through a simple wiki application: DjangoWiki. As reminder, the tests consist to execute the famous ApacheBenchmark tool with 100 concurrent requests. To be comparable (if we can), the tests are running on the same machine (Kernel, SQLite-3.2.1, python-2.4.2, ...) as for the Axiom+Nevow+Twisted tests. Specific tools required here are flup-0.5 and lighttpd-1.4.11 I've made tests with an empty SQLite DB (just 2 records). The results here after shows that: - The webserver (lighttpd+flup/scgi+django) resists quite well to 100 concurrent ab2 requests.
- The webserver can accept 85 requests per second without caching
- The server can accept 209 (!!!) requests per second with the cache enabled
Here after the raw results, I let you judge. Appendix: Django WSGIServer results
wi@linuxhome ~ $ nice -n 20 ab2 -n1000 -c100 http://localhost:8000/wiki/FrontPage/
This is ApacheBench, Version 2.0.41-dev <$Revision: 1.121.2.12 $> apache-2.0
Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright (c) 1998-2002 The Apache Software Foundation, http://www.apache.org/
Server Software: WSGIServer/0.1
Server Hostname: localhost
Server Port: 8000
Document Path: /wiki/FrontPage/
Document Length: 609 bytes
Concurrency Level: 100
Time taken for tests: 20.340463 seconds
Complete requests: 1000
Failed requests: 0
Write errors: 0
Total transferred: 754004 bytes
HTML transferred: 611436 bytes
Requests per second: 49.16 [#/sec] (mean)
Time per request: 2034.046 [ms] (mean)
Time per request: 20.340 [ms] (mean, across all concurrent requests)
Transfer rate: 36.18 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 506 1429.0 47 9096
Processing: 12 260 1150.8 69 13290
Waiting: 0 243 1152.6 48 13288
Total: 82 767 2131.9 108 16288
Percentage of the requests served within a certain time (ms)
50% 108
66% 116
75% 134
80% 140
90% 3194
95% 3963
98% 9181
99% 11976
100% 16288 (longest request)
Appendix: Django SCGI server (via flup) integrated with lighttpd-1.4.11
wi@linuxhome ~ $ nice -n 20 ab2 -n1000 -c100 http://test/wiki/FrontPage/
This is ApacheBench, Version 2.0.41-dev <$Revision: 1.121.2.12 $> apache-2.0
Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright (c) 1998-2002 The Apache Software Foundation, http://www.apache.org/
Server Software: lighttpd/1.4.11
Server Hostname: test
Server Port: 80
Document Path: /wiki/FrontPage/
Document Length: 609 bytes
Concurrency Level: 100
Time taken for tests: 11.700603 seconds
Complete requests: 1000
Failed requests: 0
Write errors: 0
Total transferred: 798845 bytes
HTML transferred: 609000 bytes
Requests per second: 85.47 [#/sec] (mean)
Time per request: 1170.060 [ms] (mean)
Time per request: 11.701 [ms] (mean, across all concurrent requests)
Transfer rate: 66.66 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 17 573 327.6 580 1167
Processing: 31 593 328.1 589 1182
Waiting: 2 570 334.2 567 1167
Total: 1152 1167 15.6 1161 1203
Percentage of the requests served within a certain time (ms)
50% 1161
66% 1164
75% 1178
80% 1182
90% 1201
95% 1201
98% 1201
99% 1201
100% 1203 (longest request)
Appendix: Django SCGI server (same as before), but with cache enabled (300 seconds)
vi@linuxhome ~/Documents/livejournal $ nice -n 20 ab2 -n1000 -c100 http://test/wiki/FrontPage/
This is ApacheBench, Version 2.0.41-dev <$Revision: 1.121.2.12 $> apache-2.0
Copyright (c) 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright (c) 1998-2002 The Apache Software Foundation, http://www.apache.org/
Server Software: lighttpd/1.4.11
Server Hostname: test
Server Port: 80
Document Path: /wiki/FrontPage/
Document Length: 609 bytes
Concurrency Level: 100
Time taken for tests: 4.771269 seconds
Complete requests: 1000
Failed requests: 0
Write errors: 0
Total transferred: 952509 bytes
HTML transferred: 609000 bytes
Requests per second: 209.59 [#/sec] (mean)
Time per request: 477.127 [ms] (mean)
Time per request: 4.771 [ms] (mean, across all concurrent requests)
Transfer rate: 194.92 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 16 235 117.9 239 440
Processing: 24 238 117.8 234 447
Waiting: 2 219 126.7 219 440
Total: 460 473 6.0 474 490
Percentage of the requests served within a certain time (ms)
50% 474
66% 476
75% 476
80% 477
90% 482
95% 483
98% 490
99% 490
100% 490 (longest request)
I'm proud to announce the first beta release of a summarize tool that allow you to easily got the main message of a text. This tool highlight in yellow the most important sentences of the text in their context. You will them be able to understand the essence of the text in a couple of seconds. It is based on a semantic and statistical analysis of the different text you analyze. Those statistics are personal, thus required you to be registered, but an anonymous user has been defined to allow everyone to see what the tool can do. It has been fully written in python with Quixote for the web interface. Website: http://summary.opensource4you.comWilliam |