星期日, 6月 24, 2007

Thread dying problem may fixed in django/flup.

一直都耳聞django的apache+mod_fastcgi+thread mode在高負載狀況下有問題,
甚至也有人將之歸結於python的thread實作有問題,
所以我一直以來都是使用prefork的方式來啟動fastcgi/wsgi,
上禮拜在替django作負載調試的時候,
也發現thread mode在超高壓力測試的情況下,的確會停止運作造成service unavailable
(concurrency > 1000)
因此才花時間找出真正的原因(至少在我這邊的原因),
應該是django所採用(其實不止django, pylons跟turbogears也有採用)
的FastCGI to WSGI adapter -- flup,
在threadpool的實作上有些許的小問題, 沒有對運作異常的thread拋出例外的情形加以處理,
才導致了發生問題的thread沒有再次進入threadpool,所以運作一陣子後會讓所有thread悄悄死去.

在修正了這個問題之後, 即使在concurrency > 1000的情況下仍然保持順暢運作,
也擺脫了使用modpython或prefork mode的fastcgi大量耗用伺服器記憶體的情形,
thread mode + FastCGI/WSGI 果然才是王道!

已提交patch, 期待新版的flup收納之後, 讓python的web framework在thread mode下運作更順利.

4 則留言:

匿名 提到...

如果不考虑内存问题,prefork 是否性能要高于 thread 模式呢?

使徒提姆 !? 提到...

基本上如果不考慮內存(memory)問題, 並且你的web程式是CPU-bound的程式,prefork mode 可以在雙或多核心CPU上運作順利並分散程式到多個CPU,或許會性能較高, 但其他情況的話(如單核cpu或需大量concurrent(併發) 聯接)我建議你直接採用thread mode, 因為基本上很難不考慮內存(memory)問題.另外,我的patch已在數月前收納在flup的hg repo裡了.

匿名 提到...

谢谢,我已经在 flup-1.0 release 里面看到合并后的代码了..

呵呵,理论上可以以 flup 同样的接口来写一个 C 的模块来提高性能吧.

使徒提姆 !? 提到...

如果你對C的實作有興趣或想研究,
可以考慮同一作者所寫的ajp-wsgi