Apache rewrite技術實現Apache到lighttpd遷移
來源:互聯網
上載者:User
毫無疑問Apache是一個優秀的web server,但它也不萬能的,在一些特定的環境下,也有Apache力不從心的時候。手上一台server由於瞬間高密度的訪問非常多,因此Apache 1.3.x應付起來有點吃力,表現為響應速度慢,而且非常耗資源,Swap經常都是佔滿的。有一兩次還導致機器負載過高(高達30-40,有個別時刻居然達到150之巨),感覺要死機的樣子。 為此,必須尋求一個解決之道。分析之下,這台server目前的情況主要是由於運行了大量的fastcgi應用,而且這些應用的並發非常密集,平時白天就有200-300個串連,厲害的時候有近1000個在用進程。apache的運行情況top如下: 25806 nobody 15 0 7224 5888 1652 S 0.0 0.5 0:10 1 httpd 28152 nobody 15 0 6576 5856 1680 S 0.0 0.5 0:01 1 httpd 28686 nobody 15 0 7224 5808 1652 S 0.0 0.5 0:01 1 httpd 可見每個process的Share 記憶體就有1.6MB之多,如果是1000個進程就是1.6G了。加上其他開銷,實際需要2G的儲存空間,機器的記憶體是1G,交換區是1G,那實際上Swap將全部耗盡。 如何降低這些開銷呢?fastcgi應用程式已經較好的最佳化了,耗費的資源很少,而且只有少於10個進程在運行,因此問題不在fastcgi。問題在Apache的並發響應能力,以及資源佔用上。 使用lighttpd可以較好的解決這個問題,lighttpd基於單進程多工技術,因此消耗的資源非常少。而且支援fastcgi,但由於對php的支援僅限於fastcgi,與機器現有的一些網站並不能很好的相容,因此考慮前端(80連接埠)用Apache,後端(2088)用lighttpd,通過rewrite技術,將fastcgi請求轉交(Redirect)給後端的lighttpd處理。 這樣原理上就能使apache的進程大幅度減少,並只是負責請求的轉寄而已,可以充分的利用原來的進程資源。而lighttpd消耗的cpu/memory資源也較低,因此完成同樣的任務,Apache+lighttpd的方案就比原來的純Apache要好得多。 實際運行證明,效率要好得多,響應速度提高了一個數量級以上。客戶反映良好。 Apache rewrite + lighttpd 實現方法原來負載較高的網站主機名稱highload.xxx.com ,啟動並執行fastcgi prefix是/fcgi-bin。因此需要對這個虛擬機器主機進行Rewrite配置。 第一步,編譯apache,啟用mod_rewrite: ./configure / --with-layout=Apache --prefix=/usr/local/httpd / --enable-shared=max --enable-module=rewrite / --enable-shared=rewrite 安裝並載入好之後,配置highload.xxx.com的虛擬機器主機,在VirtualHost裡增加: RewriteEngine on RewriteRule ^//fcgi-bin//(.+) http://highload.xxx.com:2088/$1 第二步,編譯lighttpd,配置fastcgi並使lighttpd監聽於2088連接埠: ./configure --prefix=/usr/local/lighttpd 配置: server.modules = ( "mod_access", "mod_fastcgi", "mod_accesslog" ) server.document-root = "/var/www/vhost/highload/fcgi-bin/" server.errorlog = "/var/log/lighttpd/lighttpd.error.log" server.indexfiles = ( "index.php", "index.html", "index.htm", "default.htm" ) mimetype.assign = ( ".pdf" => "application/pdf", ".sig" => "application/pgp-signature", ".spl" => "application/futuresplash", ".class" => "application/octet-stream", ".ps" => "application/postscript", ".torrent" => "application/x-bittorrent", ".dvi" => "application/x-dvi", ".gz" => "application/x-gzip", ".pac" => "application/x-ns-proxy-autoconfig", ".swf" => "application/x-shockwave-flash", ".tar.gz" => "application/x-tgz", ".tgz" => "application/x-tgz", ".tar" => "application/x-tar", ".zip" => "application/zip", ".mp3" => "audio/mpeg", ".m3u" => "audio/x-mpegurl", ".wma" => "audio/x-ms-wma", ".wax" => "audio/x-ms-wax", ".ogg" => "audio/x-wav", ".wav" => "audio/x-wav", ".gif" => "image/gif", ".jpg" => "image/jpeg", ".jpeg" => "image/jpeg", ".png" => "image/png", ".xbm" => "image/x-xbitmap", ".xpm" => "image/x-xpixmap", ".xwd" => "image/x-xwindowdump", ".css" => "text/css", ".html" => "text/html", ".htm" => "text/html", ".js" => "text/javascript", ".asc" => "text/plain", ".c" => "text/plain", ".conf" => "text/plain", ".text" => "text/plain", ".txt" => "text/plain", ".dtd" => "text/xml", ".xml" => "text/xml", ".mpeg" => "video/mpeg", ".mpg" => "video/mpeg", ".mov" => "video/quicktime", ".qt" => "video/quicktime", ".avi" => "video/x-msvideo", ".asf" => "video/x-ms-asf", ".asx" => "video/x-ms-asf", ".wmv" => "video/x-ms-wmv", ".bz2" => "application/x-bzip", ".tbz" => "application/x-bzip-compressed-tar", ".tar.bz2" => "application/x-bzip-compressed-tar" ) url.access-deny = ( "~", ".inc" ) server.port = 2080 fastcgi.server = ( "prog1" => ("prog1" =>("socket" => "/tmp/prog1.socket")), "prog2" => ("prog2" =>("socket" => "/tmp/prog2.socket")) ) 這樣lighttpd將監聽於2088連接埠,訪問http://highload.xxx.com:2088/prog1或prog2就可以執行fastcgi應用了。 注意,由於prog1/prog2等程式是非PHP 的fastcgi程式,由perl/c寫成,因此必須用lighttpd的spawn-fcgi程式實現將這些fcgi應用運行,才能啟動lighttpd,否則lighttpd會出錯。 進入/usr/local/lighttpd/bin,執行: ./spawn-fcgi -s /tmp/prog1.socket -f /var/www/vhost/highload/prog1 ./spawn-fcgi -s /tmp/prog2.socket -f /var/www/vhost/highload/prog2 執行成功的話,將顯示: spawn-fcgi.c.160: child spawned successfully: PID: 602 重新啟動apache,這樣凡是訪問http://highload.xxx.com/fcgi-bin/prog1或prog2,將自動定向到http://highload.xxx.com:2080/prog*。 經過這樣改進後,平均的Apache進程數從650-700降低到250,其餘的400-500個並發就由lighttpd來處理。整機的負載也降低了很多。主要是記憶體使用量大幅度降低了。只有原來的40%用量,swap餘量非常足夠:-) 而且最重要的是,響應速度快了很多。以下是並發請求的監視圖: 注意:圖上顯示的是按每秒的並發請求次數,而不是並發串連數,並發串連數大概是這個數的10倍,也即如果有25請求/秒,那麼實際在一段時間內的持續並發串連數就有250-300個。