william_os4y ([info]william_os4y) wrote,
@ 2009-02-25 19:53:00
Previous Entry  Add to memories!  Tell a Friend  Next Entry
FAPWS-0.2 (WSGI server based on libev)
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.2

Most 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



(11 comments) - (Post a new comment)


[info]tdilshod
2009-02-26 11:07 am UTC (link)
It would be interesting to compare it with libebb based wsgi server and with some another server like apache or nginx for static files.

(Reply to this) (Thread)


[info]shep256
2009-07-15 08:32 pm UTC (link)
Thanks for pointing to libebb. Very interesting.

The very good side of fapws3 is that it manages libev completely, so you don't need python libev bindings. AFAIK, at this moment there are no maintained python libev bindings and libebb requires you to manage libev on yourself. There is pyev on googlecode, but it is for python3 and author doesn't even mention about it. As if it's 2014 already and everyone is using python3.

(Reply to this) (Parent)

Cookies
(Anonymous)
2009-04-10 09:54 pm UTC (link)

Is there a bug !? When i send Cookie it is not recieved by the browser. All other headers are sent.

(Reply to this) (Thread)

Re: Cookies
(Anonymous)
2009-04-11 07:28 am UTC (link)
FAPWS is running fine with cookies.
With more details, I can maybe help you.

Please join our mailinglist: http://groups.google.com/group/fapws
Easier and more efficient to exchange ideas and peace of code.

(Reply to this) (Parent)

FAPWS Goals
(Anonymous)
2009-05-14 06:28 pm UTC (link)
What are the FAPWS goals? is it intended to be used instead of Apache or Nginx or other web servers in production? do you think it will match or improve upon the speed and performance of those? or it's just a convenience server to be used when there's no other server installed and one needs a quick way around?

(Reply to this) (Thread)

Re: FAPWS Goals
[info]william_os4y
2009-05-14 07:02 pm UTC (link)
FAPWS is a very quick and light python webserver.
I'm using it on small machines and it run perfectly since months without any reboot ;-).

(Reply to this) (Parent)


[info]shep256
2009-07-15 08:28 pm UTC (link)
First of all, i must totally congratulate you with new libev based fapws2.

BUT. You're repeating the same error as with all previous fapws.

No wonder you get silly 4/40 rps with django. Because requests block on DB. While you can't really solve it with sqlite, you could make network enabled DB connection through libev too. Thus you would get much greater rps. 1k is a good goal. Not really achievable with django templates. But you could at least get 500 rps which is higher than threaded setups.

The same error is you don't provide a way to make outgoing connection from fapws. While i could understand that maybe fapws is not really a network backend like eventlet/twisted/etc. The fact is, people usually build web applications with database. The fact is, usual database bindings block.

# To get website working good we need: (not important now)
# 1) load balancer (haproxy is there)
# 2) static server (nginx/lighty/varnish, all good)
To get good web SDK we need:
3) wsgi server (fapws3 is almost there)
4) either async network backend with handler multiplexion (eventlet, twisted is there)
or async database bindings (don't know any)
5) wsgi enabled framework (django, pylons, lots of choices, all good)

So we (python web developers that is) are currently stuck at 3/4 stage. And there are tons of various compromises. For example, we (at my job) are currently deploying with spawning, which runs N=cores processes (to make busy all cores because python threads don't yet scale to cores) with M threads in each. That's a bit heavy, but it works well with blocking database bindings, so we're all happy. I'm not, since i have strong belief we don't need threads there.

Twisted is another compromise. But i hate it with passion. It makes you split code into small callbacks which is ugly. But they've done good async network and even database bindings AFAIK.

Eventlet is another compromise. It offers shiny great light threads, which are great. And they even work. Brilliant! But they don't hide it, network has lots of bugs. Maybe that's because they're trying to cover so many backends (select, poll, libevent, libev). My coworkers tried to get their special database connection pool working with Postgresql and failed. But it works with Mysql. What a disappointing fail!

And there's fapws. Which is faster than everything we've seen before, obviously, it must be so. You've shown it on "simple jpg file" test. I got 24K rps with eventlet (simple custom protocol, no HTTP, not blocking on disk, though, but that's python. You have C HTTP implementation). But is there a point to serve static files with high-level python code? My guess is no. But, you could make complex rules in python and yield X-Accel-Redirect header to nginx, which would read files and serve. In particular, that's one of the greatest appliance of fapws available today. Another great appliance is to build a webchat, w/o database. Simple queue in memory, and COMET-ing to all clients. Great.

Maybe we have yet to see python async DB bindings arising, which would allow us to unleash the power of Fapws3 on great libev. But then again, to make use of it, fapws should not hide internal socket. Please, let us make outgoing connections using fapws3's internal loop.

I'm bad C dev, better at python, but i could help with support and testing, including on heavy loaded production environment.

(Reply to this) (Thread)


[info]william_os4y
2009-07-17 07:07 am UTC (link)
Hi,

Thanks for your encouragements.

My objective with Fapws is to make the lighter and the faster wsgi server.

You are correct that blocking DB will become the bottle neck, but you have a simple, and efficient, solution yet: load balancing.
Thanks to the small memory foot print of Fapws you can run lot of them in parallel. Together with pound, an efficient load balancer, you can share the load between all your different fapws servers.
This is simple to managed, efficient and easy to implement. don't you think ?

And as you mention, non-blocking DB are coming. Thus feel free to use them instead of sqlite.

William

(Reply to this) (Parent)(Thread)


[info]shep256
2009-07-17 08:18 am UTC (link)
Thanks to the small memory foot print of Fapws you can run lot of them in parallel. Together with pound, an efficient load balancer, you can share the load between all your different fapws servers.
This is simple to managed, efficient and easy to implement. don't you think ?


No, i don't think running 100 instances of fapws is a solution for two reasons: 1) you're still running a python interpreter process, which is hell heavy. 2) you're wasting memory on not yet came requests. And when they come more than you expected, DB is still a bottleneck. This is no different (it is actually worse) approach than the old school Apache+CGI scheme. Apache at least could spawn more handlers when requests are coming and keep the memory low when request burst is ended.

And as you mention, non-blocking DB are coming. Thus feel free to use them instead of sqlite.

Any network enabled DB is non-blocking for application server. Async python DB bindings are to come. I don't know any besides twisted. And when they come, we need to be able to add onread/write events into main event loop which is completely hidden by fapws.

In fact, one could start writing an async DB binding right away. The show stopper is an event system.

Don't you want to write a generic python2 interface to libev, probably? :)

(Reply to this) (Parent)(Thread)


(Anonymous)
2009-07-21 08:20 am UTC (link)
With my most complex Django website, the python associated process "heat" 25251KB in memory and Pound use 2x 6371KB.
The "out of the box" (on my archlinux machine) apache server comes with 7 processes of 47150KB. And I don't think that the python plugin is already loaded.

Thus Fapws is really light compared to apache.

Compared to Lighttpd; lighty heats 7712KB, but requires to have python fastcgi or scgi or wsgi servers too. Thus lighttpd is comparable to pound.

The problems with cgi pages is that each spawed process need to load the python (or perl, php, ...) interpreter. This is why apache has put in place the concept of perl, python and php bindings and to pre-load them.

Regarding high load ... spawing, threading, ... will put you in danger because this can fully load your machine. Thus you need to have an algorythme to manage those threads and assure they will not goes over a max limit. Than use apache, this is what it does.

Regarding DB ... To my point of view, this is not the goal of a web server to manage the DB binding. If you are not satisfied by your DB, change it.
Have you look at ZODB and his ZEO server ? If I'm correct, this sounds to be a nice asynchronous approach.

If you absolutely needs to have async IO, think about simple flat files. Depending on your OS, this could be managed asynchronously.
Fapws is using this features for static files. Fapws does not wait the end of a big file before providing response to other requests. It use block of 32768bytes.

Regarding libev ... I'm using it to reach my goals: Fast asynchronous python wsgi server. No, my goal is not to write a libev binding.

Sorry to not fully match your needs, but contributions are welcome.

William

(Reply to this) (Parent)(Thread)


[info]shep256
2009-07-21 09:49 am UTC (link)
Regarding high load ... spawing, threading, ... will put you in danger because this can fully load your machine. Thus you need to have an algorythme to manage those threads and assure they will not goes over a max limit. Than use apache, this is what it does.


Spawning starts as many threads as you tell it to. And this number never changes. That's a bit like your pound with constant number of fapws backends.

Regarding DB ... To my point of view, this is not the goal of a web server to manage the DB binding. If you are not satisfied by your DB, change it.
Have you look at ZODB and his ZEO server ? If I'm correct, this sounds to be a nice asynchronous approach.


It doesn't matter which database exactly. To do any async DB, dev must inject events into mainloop.

If you absolutely needs to have async IO, think about simple flat files. Depending on your OS, this could be managed asynchronously.
Fapws is using this features for static files. Fapws does not wait the end of a big file before providing response to other requests. It use block of 32768bytes.


That's great, BTW. nginx doesn't read files asynchronously, that's why it has 'workers'. Does fapws3 read files asynchronously without new events in libev? I thought that's impossible. Does it have to do anything with WSGI iterable result?

Sorry to not fully match your needs, but contributions are welcome.


I'm currently writing python binding to that http-parser library which is used in libebb. Interested?

(Reply to this) (Parent)


(11 comments) - (Post a new comment)

Create an Account
Forgot your login or password?
Login w/ OpenID
English • Español • Deutsch • Русский…