用Lighttpd還是Nginx/Mongrel? 
現(xiàn)在Nginx/Mongrel的部署方式越來越受歡迎了,很多人置疑Lighttpd/FastCGI,并且現(xiàn)在也涌現(xiàn)了一些比Mongrel性能更好的例如Thin,ebb等ruby應(yīng)用服務(wù)器,那Lighttpd/FastCGI真的過時了嗎?
大家有興趣可以看一下我這篇文章:RoR部署方案深度剖析,Lighttpd提供了很多其他Web服務(wù)器不具備的優(yōu)勢,可以最大化FastCGI的性能。現(xiàn)在Mongrel/Thin/ebb都利用了一些多線程或者事件IO機制來提供并發(fā)性能,這是FastCGI所不具備的,但遺憾的是Rails框架是單線程的,最終還是必須單進程單線程來執(zhí)行Rails請求,所以這些并發(fā)優(yōu)勢無用武之地。但一些其他Ruby的Web框架例如camping,weavers已經(jīng)開始支持ruby多線程,提供了比Rails好得多的性能,mongrel/ebb只有在這些web框架上面才能發(fā)揮其性能優(yōu)勢。
所以只要你還是用Rails框架,Lighttpd/FastCGI就是性能最好的部署方案。
大家有興趣可以看一下我這篇文章:RoR部署方案深度剖析,Lighttpd提供了很多其他Web服務(wù)器不具備的優(yōu)勢,可以最大化FastCGI的性能。現(xiàn)在Mongrel/Thin/ebb都利用了一些多線程或者事件IO機制來提供并發(fā)性能,這是FastCGI所不具備的,但遺憾的是Rails框架是單線程的,最終還是必須單進程單線程來執(zhí)行Rails請求,所以這些并發(fā)優(yōu)勢無用武之地。但一些其他Ruby的Web框架例如camping,weavers已經(jīng)開始支持ruby多線程,提供了比Rails好得多的性能,mongrel/ebb只有在這些web框架上面才能發(fā)揮其性能優(yōu)勢。
所以只要你還是用Rails框架,Lighttpd/FastCGI就是性能最好的部署方案。
ubuntu安裝ruby缺少readline和zlib庫 
有些人的ubuntu安裝的庫不全,比方說缺少readline庫,缺少zlib庫,可能會導(dǎo)致自己手工編譯安裝ruby的失敗,那么就用apt-get先把庫安裝好。
編譯lighttpd的時候報告缺少pcre庫 
RHEL/CentOS用戶可能要用yum安裝一下pcre/pcre-devel這兩個庫,ubuntu用戶用apt-get安裝一下,Linux熟手也可以自己下載源代碼編譯安裝,Pcre是Perl兼容的正則表達式庫,Lighttpd的Rewrite功能需要它。
ubuntu操作系統(tǒng)執(zhí)行rc.lighttpd腳本報錯 
如果你的Linux是ubuntu,那么需要自己創(chuàng)建啟動腳本,lighttpd官方wiki上面已經(jīng)給出來一個該腳本示例,地址在:
http://redmine.lighttpd.net/wiki/1/ScriptsUbuntu
rc.lighttpd這個腳本是針對SuSE Linux寫的,此外還提供了一個rc.lighttpd.redhat是針對RedHat Linux寫的,你自己寫一個控制腳本,也不過是舉手之勞:
創(chuàng)建一個shell腳本,內(nèi)容如上,chmod u+x lighttpd.sh,這個腳本就可以用來啟動關(guān)閉和重起lighttpd了
http://redmine.lighttpd.net/wiki/1/ScriptsUbuntu
rc.lighttpd這個腳本是針對SuSE Linux寫的,此外還提供了一個rc.lighttpd.redhat是針對RedHat Linux寫的,你自己寫一個控制腳本,也不過是舉手之勞:
- #!/bin/sh
- case "$1" in
- start)
- /usr/local/lighttpd/sbin/lighttpd -f /etc/lighttpd/lighttpd.conf > /dev/null 2>&1
- ;;
- stop)
- killall lighttpd
- ;;
- restart)
- $0 stop
- sleep 1
- $0 start
- ;;
- *)
- echo "Usage: lighttpd.sh {start|stop|restart}"
- ;;
- esac
- exit 0
創(chuàng)建一個shell腳本,內(nèi)容如上,chmod u+x lighttpd.sh,這個腳本就可以用來啟動關(guān)閉和重起lighttpd了
啟動Lighttpd的時候報錯,說XXX目錄找不到 
Lighttpd啟動之后默認情況下會寫access log,error log,如果你啟動了壓縮過程,還會把文件壓縮過的版本放在壓縮目錄下面,所以檢查一下你的lighttpd.conf配置文件,是不是這些目錄還沒有,或者路徑不對。
lighttpd可以啟動,但配了Rails就無法啟動 
如果無法啟動Rails,要學(xué)會自己看Lighttpd的error log和Rails項目的log目錄下面的fastcgi crash log,在這兩個log文件當(dāng)中可以找到出錯原因。
其中一種常犯的錯誤是:Rails項目在Windows上面創(chuàng)建和開發(fā),最后部署到Linux Server上面。這種情況下dispatch.fcgi這個腳本的ruby解析器路徑是 #!c:/ruby/bin/ruby.exe 這個路徑在Linux上面肯定是錯誤的,你可以改成#!/usr/bin/env ruby,或者干脆在Linux上面創(chuàng)建該Rails項目。
此外在windows上面創(chuàng)建的Rails項目,dispatch.fcgi沒有可執(zhí)行權(quán)限,這也需要你在Linux上面先賦予可執(zhí)行權(quán)限才行。你可以嘗試著手工運行該腳本cd public && ./dispatch.fcgi,看看是否可以運行。
其中一種常犯的錯誤是:Rails項目在Windows上面創(chuàng)建和開發(fā),最后部署到Linux Server上面。這種情況下dispatch.fcgi這個腳本的ruby解析器路徑是 #!c:/ruby/bin/ruby.exe 這個路徑在Linux上面肯定是錯誤的,你可以改成#!/usr/bin/env ruby,或者干脆在Linux上面創(chuàng)建該Rails項目。
此外在windows上面創(chuàng)建的Rails項目,dispatch.fcgi沒有可執(zhí)行權(quán)限,這也需要你在Linux上面先賦予可執(zhí)行權(quán)限才行。你可以嘗試著手工運行該腳本cd public && ./dispatch.fcgi,看看是否可以運行。
啟動lighttpd報錯,說找不到socket路徑 
我在前面安裝文檔中給出來的配置內(nèi)容如下:
就算照抄你要改改路徑吧?這個demo當(dāng)中的socket路徑是/tmp/lighttpd/socket/rails.socket,那你要照抄,先檢查一下有沒有/tmp/lighttpd/sock目錄總是應(yīng)該的吧?其實用啥路徑都無妨,關(guān)鍵就是別照抄,領(lǐng)會原理,根據(jù)自己的環(huán)境做相應(yīng)的調(diào)整。
- $HTTP["host"] == "www.xxx.com" {
- server.document-root = "/yourrails/public"
- server.error-handler-404 = "/dispatch.fcgi"
- fastcgi.server = (".fcgi" =>
- ("localhost" =>
- ("min-procs" => 10,
- "max-procs" => 10,
- "socket" => "/tmp/lighttpd/socket/rails.socket",
- "bin-path" => "/yourrails/public/dispatch.fcgi",
- "bin-environment" => ("RAILS_ENV" => "production")
- )
- )
- )
- }
就算照抄你要改改路徑吧?這個demo當(dāng)中的socket路徑是/tmp/lighttpd/socket/rails.socket,那你要照抄,先檢查一下有沒有/tmp/lighttpd/sock目錄總是應(yīng)該的吧?其實用啥路徑都無妨,關(guān)鍵就是別照抄,領(lǐng)會原理,根據(jù)自己的環(huán)境做相應(yīng)的調(diào)整。
lighttpd正常啟動了,但訪問Rails出現(xiàn)404 
在lighttpd的虛擬域配置里面有一項
意思是當(dāng)lighttpd找不到URL對應(yīng)的硬盤文件,就會調(diào)用Rails的dispatch.fcgi去處理該URL請求,這也是lighttpd訪問Rails的主要方式,其性能比URL轉(zhuǎn)發(fā)要快。如果你在配置文件里面忽略了這一行,lighttpd就會直接返回404錯誤,而不是交給Rails處理。
- server.error-handler-404 = "/dispatch.fcgi"
意思是當(dāng)lighttpd找不到URL對應(yīng)的硬盤文件,就會調(diào)用Rails的dispatch.fcgi去處理該URL請求,這也是lighttpd訪問Rails的主要方式,其性能比URL轉(zhuǎn)發(fā)要快。如果你在配置文件里面忽略了這一行,lighttpd就會直接返回404錯誤,而不是交給Rails處理。
多次重起lighttpd以后fastcgi進程越來越多 
正常情況下,關(guān)閉Lighttpd以后,dispatch進程就會銷毀,但是在dispatch進程處理請求的時候關(guān)閉lighttpd,dispatch進程并不會馬上關(guān)閉,而是處理完畢當(dāng)前請求,才會關(guān)閉掉。一些極端情況下,可能會導(dǎo)致dispatch進程一直不關(guān)閉,dispatch進程就會越來越多。解決辦法很簡單 killall -9 dispatch.fcgi,只管殺進程就好了。
lighttpd和FastCGI部署在不同的服務(wù)器怎么配置 
這種情況下,Lighttpd只是連接遠程服務(wù)器的TCP端口,而不負責(zé)啟動dispatch.fcgi進程,因此需要自己寫腳本啟動關(guān)閉dispatch.fcgi進程。lighttpd提供了一個spawn-fcgi的程序,可以用來啟動dispatch.fcgi進程,監(jiān)聽TCP端口,你可以自己寫一個shell腳本來完成這個工作。另外spawn-fcgi還可以啟動dispatch.fcgi進程,創(chuàng)建本機的unix socket端口,和本機lighttpd通訊,例如:
例如:
執(zhí)行 ./dispatch.sh start 將啟動10個dispatch.fcgi進程,在/tmp/lighttpd/sock目錄下面創(chuàng)建了10個unix socket文件,然后配置lighttpd去連接這10個socket文件:
這樣做的好處是,每次重新部署應(yīng)用,就不需要重起lighttpd了,只需要執(zhí)行自己的dispatch.sh來重起dispatch.fcgi進程就可以了。同時也可以很好的解決上一個fastcgi進程堆積的問題。
如果遠程部署,配置方式是一樣的,就是lighttp連接的端口改為:
dispatch.sh創(chuàng)建dispatch.fcgi進程的時候,使用 -t 參數(shù)創(chuàng)建tcp端口,而不是 -s 創(chuàng)建unix socket文件即可。
例如:
- #!/bin/sh
- DISPATCH_PATH=/yourrailsapp/public/dispatch.fcgi
- SOCKET_PATH=/tmp/lighttpd/socket
- RAILS_ENV=production
- export RAILS_ENV
- case "$1" in
- start)
- for num in 0 1 2 3 4 5 6 7 8 9
- do
- /usr/local/lighttpd/bin/spawn-fcgi -f $DISPATCH_PATH -s $SOCKET_PATH/rails.socket-$num
- done
- ;;
- stop)
- killall -9 dispatch.fcgi
- ;;
- restart)
- $0 stop
- $0 start
- ;;
- *)
- echo "Usage: dispatch.sh {start|stop|restart}"
- ;;
- esac
- exit 0
執(zhí)行 ./dispatch.sh start 將啟動10個dispatch.fcgi進程,在/tmp/lighttpd/sock目錄下面創(chuàng)建了10個unix socket文件,然后配置lighttpd去連接這10個socket文件:
- $HTTP["host"] =~ "www.xxx.com$" {
- server.document-root = "/yourrails/public"
- server.error-handler-404 = "/dispatch.fcgi"
- fastcgi.server = (".fcgi" =>
- (
- ("socket"=>"/tmp/lighttpd/socket/rails.socket-0"),
- ("socket"=>"/tmp/lighttpd/socket/rails.socket-1"),
- ("socket"=>"/tmp/lighttpd/socket/rails.socket-2"),
- ("socket"=>"/tmp/lighttpd/socket/rails.socket-3"),
- ("socket"=>"/tmp/lighttpd/socket/rails.socket-4"),
- ("socket"=>"/tmp/lighttpd/socket/rails.socket-5"),
- ("socket"=>"/tmp/lighttpd/socket/rails.socket-6"),
- ("socket"=>"/tmp/lighttpd/socket/rails.socket-7"),
- ("socket"=>"/tmp/lighttpd/socket/rails.socket-8"),
- ("socket"=>"/tmp/lighttpd/socket/rails.socket-9")
- )
- )
- }
這樣做的好處是,每次重新部署應(yīng)用,就不需要重起lighttpd了,只需要執(zhí)行自己的dispatch.sh來重起dispatch.fcgi進程就可以了。同時也可以很好的解決上一個fastcgi進程堆積的問題。
如果遠程部署,配置方式是一樣的,就是lighttp連接的端口改為:
- ("host"=>"192.168.0.1, "port"=>3001),
- ("host"=>"192.168.0.1, "port"=>3002),
- ......
dispatch.sh創(chuàng)建dispatch.fcgi進程的時候,使用 -t 參數(shù)創(chuàng)建tcp端口,而不是 -s 創(chuàng)建unix socket文件即可。
rails應(yīng)用不在根目錄下,在子目錄下怎么配置 
例如你的rails應(yīng)用必須使用某個網(wǎng)站的子目錄,如:http://www.xxx.com/myapp,那么lighttpd的配置要進行相應(yīng)的修改:
1、要使用$HTTP["url"]去匹配你要訪問的子目錄,根據(jù)該子目錄進行特定的配置。這樣做的好處是,你可以在一個虛擬域下面部署多個rails應(yīng)用,用子目錄分開就可以了。
2、使用alias.url來指定目錄別名,這可以保證你的靜態(tài)資源例如js,css,images訪問路徑是正常的
3、server.error-handler-404 要加上前綴: "/myapp/dispatch.fcgi"
4、在fastcgi配置里面,也要匹配該URL,特別注意,應(yīng)該增加一項:"check-local" => "disable"的配置項
在進行如上配置以后,lighttpd已經(jīng)可以正常的處理子目錄了,但是Rails的routes仍然無法正常工作,這需要我們修改Rails的配置文件config/environment.rb,在最后面添加如下代碼:
修改Rails處理URL請求的默認前綴。
好了,現(xiàn)在你可以打開瀏覽器測試一下了。
- $HTTP["host"] == "www.xxx.com" {
- $HTTP["url"] =~ "^/myapp" {
- server.document-root = "/home/webroot/demo/public"
- alias.url = ("/myapp" => "/home/webroot/demo/public")
- server.error-handler-404 = "/myapp/dispatch.fcgi"
- fastcgi.server = ("/myapp/dispatch.fcgi" =>
- ("localhost" =>
- ("min-procs" => 1,
- "max-procs" => 10,
- "socket" => "/tmp/rails.socket",
- "check-local" => "disable",
- "bin-path" => "/home/webroot/demo/public/dispatch.fcgi",
- "bin-environment" => ("RAILS_ENV" => "production")
- )
- )
- )
- }
- }
1、要使用$HTTP["url"]去匹配你要訪問的子目錄,根據(jù)該子目錄進行特定的配置。這樣做的好處是,你可以在一個虛擬域下面部署多個rails應(yīng)用,用子目錄分開就可以了。
2、使用alias.url來指定目錄別名,這可以保證你的靜態(tài)資源例如js,css,images訪問路徑是正常的
3、server.error-handler-404 要加上前綴: "/myapp/dispatch.fcgi"
4、在fastcgi配置里面,也要匹配該URL,特別注意,應(yīng)該增加一項:"check-local" => "disable"的配置項
在進行如上配置以后,lighttpd已經(jīng)可以正常的處理子目錄了,但是Rails的routes仍然無法正常工作,這需要我們修改Rails的配置文件config/environment.rb,在最后面添加如下代碼:
- class ActionController::AbstractRequest
- def relative_url_root
- '/myapp'
- end
- end
修改Rails處理URL請求的默認前綴。
好了,現(xiàn)在你可以打開瀏覽器測試一下了。
我使用了Rails的頁面緩存,卻不生效 
Rails的頁面緩存機制本質(zhì)上是動態(tài)頁面靜態(tài)化技術(shù),當(dāng)你第一次訪問頁面的時候,在public目錄下面生成靜態(tài)頁面,后續(xù)同樣的請求,Web服務(wù)器將直接返回靜態(tài)頁面,不再轉(zhuǎn)發(fā)給Rails處理了。那么你如何讓W(xué)eb服務(wù)器知道一個動態(tài)請求的URL應(yīng)該去尋找相應(yīng)的靜態(tài)頁面呢?這需要在lighttpd里面增加如下的配置:
將所有URL請求統(tǒng)統(tǒng)重寫為后綴.html的靜態(tài)頁面請求,如果lighttpd找不到該靜態(tài)頁面,就會觸發(fā)404,轉(zhuǎn)發(fā)給Rails的dispatch.fcgi處理。但是如果你的Rails應(yīng)用不使用Rails頁面緩存,則不要寫這個配置,以免不必要的增加lighttpd的負擔(dān)和增加處理請求的步驟。
- url.rewrite = ( "^/$" => "index.html", "^([^.]+)$" => "$1.html" )
將所有URL請求統(tǒng)統(tǒng)重寫為后綴.html的靜態(tài)頁面請求,如果lighttpd找不到該靜態(tài)頁面,就會觸發(fā)404,轉(zhuǎn)發(fā)給Rails的dispatch.fcgi處理。但是如果你的Rails應(yīng)用不使用Rails頁面緩存,則不要寫這個配置,以免不必要的增加lighttpd的負擔(dān)和增加處理請求的步驟。
安徽新華電腦學(xué)校專業(yè)職業(yè)規(guī)劃師為你提供更多幫助【在線咨詢】