Posts for: #Django

Django with nginx

聽說效能比較好,聽說安全性不錯,聽說記憶體用很少

聽別人說不準,還是自己試試才知道

所以單純只是試試試看,跑起來如何,自己寫個筆記

我的nginx上, server 設定,Django fastcgi 的部份照舊 ,如果跟我一樣是用 unix socket 來連的話,權限要可以讓 nginx 寫入


limit_zone one $binary_remote_addr 10m;
server {
listen 80;
server_name s.localhost.com h.localhost.com;
#server_name home.digez.com stock.digez.com;

access_log /var/log/nginx/access.log;
location /site_media {
alias /home/terry/media/;
}
location /media {
alias /home/terry/django_src/django/contrib/admin/media/;
}
location / {
#fastcgi_pass 127.0.0.1:8080;
fastcgi_pass unix:/home/terry/run/digez.sock;
fastcgi_param REQUEST_METHOD $request_method;
fastcgi_param QUERY_STRING $query_string;
fastcgi_param CONTENT_TYPE $content_type;
fastcgi_param CONTENT_LENGTH $content_length;
fastcgi_param REMOTE_ADDR $remote_addr;
fastcgi_param SERVER_PORT $server_port;
fastcgi_param SERVER_PROTOCOL $server_protocol;
fastcgi_param SERVER_NAME $server_name;
fastcgi_param PATH_INFO $fastcgi_script_name;
fastcgi_pass_header Authorization;
fastcgi_intercept_errors off;
limit_conn one 5;
}

}


更新
2010-01-05 設定加入, fastcgi_param REMOTE_ADDR $remote_addr; Django 需要

相關連結
Django
nginx
參考資料
http://wiki.nginx.org/Main

http://stackoverflow.com/questions/605173/how-to-nginx-virtual-servers-fcgi-for-django

http://david-paste.cn/paste/20/

http://stackoverflow.com/questions/605173/how-to-nginx-virtual-servers-fcgi-for-django

哇哈哈 Good bye Internal Server Error

首先,這是一篇自首的白爛文,由於學藝不精,基礎不好,所以我的 Django Site 一直被

Internal Server Error 咬到,已經兩個星期沒有發生了,應該算解對了

事由

我的 Django Site 是用 Fastcgi 的方式,跑在 Lighttpd 後面,不過,我是用 supervisor 來控制 Django ,所以應該都不會死掉才對

問題

不管,跑 thread 或是 prefork ,跑久了,都會有 Internal Server Error 出現,也就是我的 Django Site 的 process 死了,一直找不到原因,不過發生這種情形的時候,大多 Django 的 process 已經 fork 到一大串啦,分析網站流量,應該還不至於出現這種情形才對,除了幾個背後跑的分析工作比較吃資源,所以一直以來,我都是蠻烏龜的先擺著(雖然男子漢,是絕不可以這樣的),不過,一星期,大概都有一次 Internal Server Error 發生,必須重跑 Django Site 才可以活過來


分析結果,大多是 Backgroud 的程式,使用資料庫太兇了,supervisor 以為我的 Django Site 掛了,所以就又幫我重開,可是舊的 Kill 不掉,就這樣,我的系統越跑越慢,慢到,資料庫不回應,就算掛了,Lighttpd 把 user request 送到,Django 的 Fastcgi 時,就變成 Internal Server Error

初步解法

真的很簡單

只要在 Lighttpd 的 fastcgi server 裡的設定,加
“max-procs” => 5,

這樣就會控制住總量啦,這樣,Lighttpd 和 supervisor 可以合作好一點

我是只要 5 隻就夠了,就在也沒有 Internal Server Error 了

期待,我的 Django Site 下一次真的被網友打到爆

站務 DigEZ 的網站已經跑在 Django 1.0 上了

已經把 http://stock.digez.comhttp://home.digez.com 都移到 Django 1.0 了,也找出不穩定的原因,希望服務以後都可以乖乖

股神大富翁 http://stock.digez.com 新增,將發言整理成 micro blog 的功能,完成度 40%

所有財經領域的人,不想一天到晚虎爛的人,來證實自己的實力吧

這是我目前的預測,還蠻迅的

http://stock.digez.com/users/terry/

不過有 guts 就來發言吧

期待已久的 1.0

Django 最近 trunk 的變化可說是非常的快,為的就是,讓人期待已久的 1.0 可以早日現身,過了1.0 之後,開發團隊可是保證會維護版本的回住支援,也就是一般我們在做軟體開發時,到了對自己開發的東西非常有信心,可以掛保證的階段

Newform Admin 和 Gis 的 branch 都已經合併了,也做了無數的修正,看來這一個 1.0 要服用,還要有些勇氣才行


目前,更新到 trunk後,程式部份需更動

Admin 的定義從 Db Model 的定義之中獨立出來,得到更大的彈性,也可以進一步的客製化

File Upload 有了修改,不在是原本的 Dict object,變成,django/core/files/base.py 裡 class File 的繼承物件,記得改寫 file upload 的程式

FileField, ImageField 的介面也有一些修改

詳細請參考原廠文件 或是 Look the source

給阿怪 Lighttpd + Fastcgi + Django

我的環境

Debian testing
Python 2.5.2
MySQL 5.0.51a
Lighttpd 1.4.19
Django Django version 0.97-pre-SVN-7480

Django 專案位址,您要對應您自己的位址

/home/terry/digez


Python 的部份
要安裝 python-flup

Django 的部份

一般只要把 django 用 fastcgi 的方式跑起來,即可

在命令列執行方式,其中 socket 還有 pidfile 可以放在你喜歡的地方,注意權限沒有問題就可以,也可以用 TCP 的方式執行 fastcgi
可以在命令列下打 ./manage.py help runfcgi 得到更多的提示



/home/terry/digez/manage.py runfcgi socket=/home/terry/run/digez.sock pidfile=/home/terry/run/digez.pid


您可以把執行的方式,寫成 Linux 或是 FreeBSD 下的 init.d 的執行方式,也可以用 supervisord 的方式來監控啟動

init.d 的方式可以參考 http://code.djangoproject.com/wiki/InitdScriptForDebian


Lighttpd 的部份
至少必須把 fastcgi 的模組啟動
在 Debian 的環境下,用 root的權限,在命令列下打

lighttpd-enable-mod


來啟動,下面是我執行的結果

terry:# lighttpd-enable-mod
Available modules: auth cgi fastcgi proxy rrdtool simple-vhost ssi ssl status userdir
Already enabled modules: fastcgi simple-vhost

Enable module:


下面則是在 Lighttpd 下,我設的 virtual host,我所有的主機都是設定 virtual host 的方式
下面是整個 virtual host 的設定檔,我的環境下是放在 /etc/lighttpd/conf-enabled/10-simple-vhost.conf
有井字號開頭的,整行是註解
在這裡面要注意的是 socket file 的權限,如果是 執行 Lighttpd 的 user 是 www-data 的話,socket 檔案的權限就要是 www-data 可以的讀寫
設定裡那個叫 /mysite.fcgi 的檔案,是假的,不必真實存在


## Simple name-based virtual hosting
##
## Documentation: /usr/share/doc/lighttpd-doc/simple-vhost.txt
## http://www.lighttpd.net/documentation/simple-vhost.html

server.modules += ( “mod_simple_vhost” )

## The document root of a virtual host isdocument-root =
## simple-vhost.server-root + $HTTP[“host”] + simple-vhost.document-root
simple-vhost.server-root = “/var/www”
simple-vhost.document-root = “/blog/"
simple-vhost.default-host = “home.digez.com”
$HTTP[“host”] = “^(home.digez.com|stock.digez.com)$” {
server.document-root = “/home/terry/digez”

fastcgi.server = (
“/mysite.fcgi” => (
“main” => (
# Use host / port instead of socket for TCP fastcgi
#“host” => “127.0.0.1”,
#“port” => 8080,
“socket” => “/home/terry/run/digez.sock”,
“check-local” => “disable”,
)
),

)
alias.url = (
“/media/” => “/home/terry/django_src/django/contrib/admin/media/”,
“/site_media/” => “/home/terry/media/”,
)

url.rewrite-once = (
“^(/media.)$” => “$1”,
“^(/site_media.
)$” => “$1”,
“^/favicon.ico$” => “/site_media/images/favicon.ico”,
“^(/.*)$” => “/mysite.fcgi$1”,
)
}







以上Lighttpd 設定更改過後,該重新啟動的要啟動過後才會生效,有關於 Lighttpd 設定還有多進階的方法,可以幫我們擋攻擊,或是增加效能 ;-)

測試一下 Django threading mode

之前有些一篇, prefork or threaded 之中提到的 Internal Server Error 大約找到原因了,還不是非常的確定就是了,原因是資料庫,覆載太重了,我太常跑一些有的沒的,我的電腦真是太可憐了,所以接下來,網站,應該會衝 threade 的模式試試看

prefork or threaded

開發好的網站程式最終還是會裝在網站伺服器上,開放對外面的服務,實際考驗你寫程式的效能,及整個架構能否負荷對所有網民的請求

這是最近試過的組合

Lighttpd + fastcgi + Django prefork

Lighttpd + fastcgi + Django threaded

Lighttpd + scgi + Django prefork

Lighttpd + scgi + Django threaded

用 apache 附的 ab 作壓力測試 ,concurrency 100, 1000 request 100, 1000

Django 都是使用 local unix sock 的方式跑,用預設的 maxchildren=50 請求頁面是一個 Django 的 cache 頁面,有 6個 MySQL 的查詢

環境

Debian Linux 2.6.24-1-686,Lighttpd 1.4.19,MySQL 5.0.51a, Python2.5.2,python-flup 1.0-1,python-mysqldb 1.2.2-6,Django version 0.97-pre-SVN-7480

IBM X60 CPU Intel Core Duo 1.83 RAM 1G

調整 Django 的架構方式得到的結論

效能上 scgi 和 fastcgi 並無太大的差別

所以只比較 prefork,threaded

效能
threaded > prefork
成功完成 web 請求數最多,最快
threaded Requests per second: 438.89 [#/sec] (mean)
prefork Requests per second: 129.53 [#/sec] (mean)
穩定度
prefork > threaded
threaded 模式運作一段時間後會出現 Internal Server Error,沒有回應

兩種模式,在壓力過大的時候,都會出現無法回應,要等待才能回復,這是正常的現象,因為,Lighttpd pass 給 Django,也要 Django 來得及回應

不過,在真實的運作中, threaded 出現的 Internal Server Error 是不會回復的,需重新啟動 Django 才行

結論就是,先不要對 threaded 的效能流口水,prefork 擋著先

希望有大大可以有建議

參考資料

http://www.alrond.com/en/2007/jan/25/performance-test-of-6-leading-frameworks/
http://timchen119.blogspot.com/2007/06/thread-dying-problem-may-fixed-in.html

supervisor 讓你的 Django 活久一點

過去曾經提過一篇Keep your daemon nerver die,有關 supervisor 的文章,今天,要小記一下, 用supervisord 來控制 Django ,若是發現程式運作發生問題,會自動幫你重新啟動

這是放在設定檔 /etc/supervisord.conf 裡的片段
digez 就是我自己取的名字,因為是要讓 supervisor 來監控,所以 daemonize 設成 false,要注意的是 sock file 的權限,必須是 user www-data 可以讀寫的權限,我的環境是 Debian testing, python 2.5.2


[program:digez]
command=/home/web/digez/manage.py runfcgi daemonize=false socket=/home/web/run/digez.sock pidfile=/home/web/run/digez.pid
user=www-data
autostart=true
autorestart=true
stdout_logfile=/var/log/digez.log