django高並發優化


我開始對web開發產生了興趣,並決定自己也嘗試開發一個網站。在此之前,我做過3年的java application的開發,對web開發應該算一無所知。在比較了java,php,ror,和python后,我選擇了基於python的web框架 - django 。到目前為止,我還認為這是一個明智的決定。Django高效的開發效率讓我僅僅用一個月的業余時間,就基本完成了網站的開發。這是一個網絡書簽的網站,我加上了一些有意思的特性,讓網站顯得有些與眾不同。

我購買了域名和Dreamhost 的主機空間。Dreamhost支持django,並且第一年的費用只有180元人民幣。2006年11月份,http://www.hpbookmarks.com 上線了。網友們發來了善意的評論,“很有創意”,“點意思”,“一些feature很不錯”。同時,還有一個非常一致的意見就是,“訪問速度太慢了”。其實,當時的情況不只是訪問速度慢,而且是相當不穩定。很多時候是幾個小時網站無法訪問。當時,我並沒有在意,因為我有兩個自以為“合理”的解釋。第一,我用的是國外最便宜的虛擬主機,國內訪問慢是很正常的。第二,django的還處於0.95的狀態,效率和穩定性方面有問題也正常。

但是,我慢慢發現上面的解釋不過是自己騙自己的借口。很多用dreamhost的網站,訪問起來也很快。而且django也已經被成功應用在許多大型的網站。我開始認真考慮提高網站速度的問題了。畢竟,速度慢的網站很可能在第一次就失去的用戶,他們可以永遠不會再來了。終於,我進行了下面一步一步的優化工作,並且取得了一個看起來還不錯的結果。

第一步,用Ajax提高用戶體驗

由於我的網站上鏈接字體的大小是根據點擊次數決定,所以每次點擊都要提交到服務器端並記錄次數,再在客戶端打開網站鏈接。這在localhost測試的時候沒有發現問題,但是部署到服務器上,會感到明顯的等待。解決辦法就是用Ajax。用戶點擊網站鏈接后就直接打開,再通過Ajax將點擊的事件提交到服務器端記錄。這樣用戶感覺不到任何延時。

第二步,將邏輯移到客戶端的javascript中

在開始的時候,“網站標簽高亮”和“手氣不錯”的功能都是提交到服務器端操作,然后返回結果的。后來,我發現其實很多邏輯是可以移到客戶端,由 javascript來實現的。Javascript非常強大,可以完成很多復雜的邏輯。將邏輯移到客戶端的javascript中,可以很有效的減少和服務器通訊的次數,獲得更好的訪問速度。

第三步,解決進程的

由於采用的是fastCGI的方式,我配置了django.fcgi。可是,我發現系統進程中,有大量的django.fcgi進程被標記為 < defunct>(失去功能)。這些進程會導致服務器有時無法正常訪問。我開始嘗試用命令來kill掉這些進程,但是很快發現這無法從根本上解決問題。后來,我看到一個老外在blog上提到一個解決方案,將django.fcgi改名為dispatch.fcgi。原來,dispatch.fcgi是一個dreamhost的系統進程,它的健壯性是可以得到保障的。果然,我將django.fcgi改名為 dispatch.fcgi后,的現象再沒有出現。

第四步,優化SQL語句

SQL語句的執行通常也是一個很花費時間的操作。經過檢查,我發現我的一條SQL語句,是一個嵌套三層的子表查詢。而這條SQL還必須是一個Raw SQL,即不能采用django的OR Maping。這意味着不能被cache緩存,每次都是真刀真槍的執行。更失敗的是,經過我的分析,這條SQL完全可以不執行。這是一次設計上的失誤,標

准的over design(過渡設計)。當時,我是想通過數據庫得到一個最精確的統計值。后來發現,這個值完全可以用一個近似的常量代替。優化SQL,尤其是避免不必要的SQL執行,帶來的效果是非常明顯的。

第五步,盡量減少頁面大小

隨着添加網站越來越多,有一天我發現django生成的首頁已經達到了80k。我很清楚這是一個非常不能被接受的數字。我開始檢查頁面,很快發現了線索。 第一,因為偷懶,頁面中很多layout是用空格( )實現的。第二,因為為了增加代碼可讀行,調試方便,每行生成的頁面都增加換行符 (\n)。第三,最糟糕的是,大量的用了

inline css。就是將css style直接嵌入標記塊中。於是,我立即動手,用css的align解決layout,去掉\n,將inline css抽象到獨立的css文件中。這樣下來,在不更改任何內容的情況下,80k變成了57k。(補充:由於網站鏈接大部分是打開新窗口,所以用了大量的 target=_blank。在ylsdd的提示下,在html的head里增加了,又節約了4k。)

第六步,用gzip進行頁面壓縮

當我興高采烈的把頁面優化結果貼到了smth bbs上,卻被直接潑了盆涼水。原來百分之二十幾的優化結果,實在太一般了。ylsdd給我了一個很重要的線索,deflate。原來apache的 deflate模塊可以把文件進行gzip壓縮,壓縮后的文件傳到瀏覽器后再被解壓。主流的瀏覽器都支持這種gzip的解壓操作。於是,我在apache 的配置文

件中加入了Add OutputFilter DEFAULT html css js的語句。經過測試,css,js這些文本文件的壓縮后都只有原來尺寸的25%。這里,和大家分享一個網站http://www.port80software.com/products/httpzip/compresscheck 它的作用是檢測你的網站是否被壓縮,以及壓縮比率等。

第七步,回歸靜態頁面

新的問題又來了。原來deflate只支持靜態文件的壓縮。而我的首頁是django動態生成的,deflate模塊沒有進行壓縮。我突然想到,網站的首頁為什么不能是靜態頁面呢?於是,我增加了一個runtime的api,這個api提供的是和原來一樣由django動態生成的頁面。我又寫了一個 python的程序,通過urllib2模塊下載這個動態生成的頁面,並保存為index.html。我將網站的root映射到index.html這個靜態頁面。最后,通過linux crontab定義一個行為,每五分鍾執行一下這個python程序,生成新的index.html。值得一提的是,由於網絡原因,python程序不一定每次都能准確完整的下載動態生成的頁面。所以我們必須再進行一個校驗算法。當頁面大小要超過一定數字,頁面中出現某個校驗字符串的情況下,才保存 index.html。這樣,每次用戶提交的訪問,不是由服務器端動態生成頁面,極大的節省了服務器端的開銷。而靜態頁面又可以有效的被deflate壓縮。最后結果,首頁被壓縮為13k,為原來的22%。唯一的區別就是,新提交和推薦的網站不能立即出現在首頁。但是我認為,這應該是可以被接受的。

至此,網站的優化工作基本完成。網站的訪問速度從原來30秒以上,縮短到3秒左右,應該說算是一個飛躍。雖然,3秒的速度也不是非常快,但是,考慮到虛擬主機等客觀原因,這個結果我還是滿意的。原來感覺我的網站很慢的朋友們,也可以再試試。

以上的優化方案出自我的個人經驗,並不一定適合所有網站。但是,它告訴我們一個事實。影響網站訪問速度的不僅僅是服務器配置,網絡帶寬。也許,你糟糕的設計,低效率的方案也是致命的因素。應當注意的是,優化工作也不能匆匆上手。一定要仔細研究,具體情況具體分析,得到統計數據,找到真正的問題所在,再開始優化。相信自己,提高網站的訪問速度並不是不可能。畢竟,Nothing is Impossible。祝大家成功。

轉自:http://www.360doc.cn/article/2459_392441.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM