【Passenger的安裝與卸載管理】
===========================================================
推薦方式是使用Pushion Passenger和Nginx的綁定install方式,這種方式可以分為:交互式和非交互式
交互式的方式下會(huì)顯示并提示安裝過程中輸入各種參數(shù)。非交互式的方式可以運(yùn)行:
sudo passenger-install-nginx-module --help
查看各種靜默安裝的參數(shù)。其中有幾個(gè)是比較關(guān)鍵的:
--auto 自動(dòng)確認(rèn)"按下Enter鍵繼續(xù)"
--prefix=DIR 設(shè)置Nginx安裝目錄(默認(rèn)是/opt/nginx)
--auto-download 自動(dòng)下載和安裝Nginx
另外一種是通過手工配置和便宜Nginx。在下載Nginx的源代碼后進(jìn)行編譯時(shí),添加如下的參數(shù)
./configure -add-module=/path-to-passenger-root/ext/nginx
這里path-to-passenger-root是Passenger的根目錄。有兩種方式可以獲得這路徑:如果是通過gem方
式安裝的??梢院?jiǎn)單運(yùn)行如下命令獲得Passenger的根目錄:passenger-config --root 如果是通過源碼
安裝的,那么指定源代碼解壓后的根目錄就可以了。
在編譯完成后,修改Nginix的配置文件(/opt/nginx/conf/nginx.conf),在HTTP模塊內(nèi)添加如下一行后
重啟Nginix即可
passenger_root /path-to-passenger-root;
如果是升級(jí)或者降級(jí)Nginx或者Passenger,也是同樣的步驟。
如果要臨時(shí)去除Passenger的支持又不想完全卸載Passenger的話,只要把Nginx中所有關(guān)于Passenger
的配置參數(shù)全部注釋掉(通常都是以passenger-xxx打頭的),并重啟Nginx就可以了。
要徹底刪除Passenger,首先把Nginx配置文件中所有關(guān)于Passenger的配置選項(xiàng)全部刪除。接下來如果
是通過gem方式安裝的,執(zhí)行:gem uninstall passenger 或者直接刪除Passenger的安裝目錄。然后重
新編譯和安裝Nginx即可。
===========================================================
【為Passenger指定Ruby的運(yùn)行目錄】
===========================================================
如果系統(tǒng)安裝了多個(gè)Ruby解析器,需要指定一個(gè)Ruby運(yùn)行目錄。如果是通過RVM來安裝Ruby解析器的,
那么RVM會(huì)將默認(rèn)使用的Ruby解析器添加到PATH環(huán)境變量下??梢赃\(yùn)行echo $PATH檢測(cè),如果沒有的
話則手工添加到$PATH的最前面。
administrator@RoR-PRD:~$ rvm list
rvm rubies
ruby-1.9.2-p290 [ i686 ]
=> ree-1.8.7-2011.03 [ i686 ]
administrator@RoR-PRD:~$ echo $PATH
/home/administrator/.rvm/gems/ree-1.8.7-2011.03@release/bin: \
/home/administrator/.rvm/gems/ree-1.8.7-2011.03@global/bin: \
/home/administrator/.rvm/rubies/ree-1.8.7-2011.03/bin: \
/home/administrator/.rvm/bin: \
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
===========================================================
【重新發(fā)布一個(gè)Rails應(yīng)用】
===========================================================
重新發(fā)布一個(gè)Rails應(yīng)用,只需要再次上傳文件后,通知Passenger重啟應(yīng)用就可以。這里有兩種方式:
第一種是重啟Nginx。另外一種是每次在發(fā)布之前,通過如下命令新建或者更新一個(gè)名為restart.txt的文
件,讓Nginx檢測(cè)到文件更新(timestamp改變)而自動(dòng)在下次請(qǐng)求到來時(shí)重啟應(yīng)用。
touch /webapps/mycook/tmp/restart.txt
必須注意的是:Passenger并不會(huì)自動(dòng)為部署的應(yīng)用創(chuàng)建好DB的環(huán)境,依然需要在發(fā)布新的應(yīng)用之后,
手工執(zhí)行:rake db:migrate RAILS_ENV=production
===========================================================
【Nginx中配置項(xiàng)的覆蓋問題】
===========================================================
server {
listen 80;
server_name localhost;
root /home/administrator/deploy/demo/public/; # <--- be sure to point to 'public'!
passenger_enabled on;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root html;
index index.html index.htm;
}
}
上面的配置選項(xiàng)中,一開始將root指定為對(duì)應(yīng)的Rails應(yīng)用的public目錄,但是在下面的location / {...}中
又將root指定為當(dāng)前目錄下的index.html或者index.htm,所以會(huì)覆蓋前面的root配置,當(dāng)在瀏覽器下
輸入:http://localhost/時(shí),顯示的不是應(yīng)用的根目錄,而是Nginx的歡迎頁(yè)面。
不過不建議這樣配置,因?yàn)檫@樣會(huì)令到當(dāng)站點(diǎn)無(wú)法訪問時(shí),無(wú)法判斷是Nginx的問題還是應(yīng)用的問題。如
果要在本機(jī)再配置,可以這些寫:
server {
listen 80;
server_name 127.0.0.1;
root /home/administrator/deploy/demo/public/; # <--- be sure to point to 'public'!
passenger_enabled on;
}
但是URL就要變成這樣:http://127.0.0.1:80/,如果使用localhost,則Nginx會(huì)默認(rèn)使用server_name
+ port 來分派請(qǐng)求,所以當(dāng)輸入:http://localhost:80/時(shí)依然會(huì)被Nginx默認(rèn)的服務(wù)器攔截,返回Nginx
的默認(rèn)頁(yè)面
===========================================================
【部署為一個(gè)URI】
===========================================================
假設(shè)現(xiàn)在已經(jīng)有了一個(gè)server配置:
server {
listen 80;
server_name www.phusion.nl;
root /websites/phusion;
}
我想將新的應(yīng)用部署在這個(gè)sever下面,并且請(qǐng)求的URL是這樣的:http://www.phusion.nl/rails。
首先在現(xiàn)有的root下面創(chuàng)建一個(gè)soft link,指向改Rails應(yīng)用:
sudo ln -s /home/administrator/deploy/demo/public /opt/nginx/html/demo
然后在原有的sever下添加如下配置:
server {
listen 80;
server_name localhost;
passenger_enabled on; # 新添加的
passenger_base_uri /demo; # 新添加的
}
然后重啟Nginx: sudo /etc/init.d/nginx restart。重新訪問:http://localhost/demo
通過這一點(diǎn),我可以實(shí)現(xiàn)將多個(gè)Rails應(yīng)用部署在同一臺(tái)機(jī)器下面的問題:只要指定不同的passenger_base_uri
===========================================================
【Passenger的配置選項(xiàng)】
===========================================================
>> passenger_root <directory>
指定Passenger的安裝根目錄
>> passenger_ruby <filename>
指定Passenger使用的Ruby解析器的目錄(按照安裝過程中推薦的值即可)
>> passenger_enabled on|off
可以定義在http/server/location/if ,默認(rèn)off
>> passenger_base_uri <uri>
可以定義在http/server/location/if 中多次定義,為同一VPS配置多個(gè)應(yīng)用
>> passenger_use_global_queue <on|off>
默認(rèn)情況下Passenger使用一個(gè)全局隊(duì)列(Global queue)來存放請(qǐng)求。當(dāng)有請(qǐng)求到來時(shí)會(huì)首先看后端的處
理進(jìn)程是否有空閑的,有的話將該請(qǐng)求轉(zhuǎn)發(fā)給請(qǐng)求進(jìn)程。沒有的話則存儲(chǔ)在自己的隊(duì)列里面。當(dāng)該功能被
關(guān)閉時(shí),會(huì)在各個(gè)后臺(tái)進(jìn)程的內(nèi)部自己維護(hù)一個(gè)獨(dú)立的隊(duì)列,而不是全局共享的。這樣會(huì)出現(xiàn)一個(gè)情況:
假如某個(gè)后臺(tái)進(jìn)程因?yàn)閽炱鸬膔equest數(shù)量比較少,那么Passenger會(huì)把新的請(qǐng)求都分配到該進(jìn)程。如果新
的請(qǐng)求都是屬于比較耗時(shí)的請(qǐng)求,那么會(huì)造成該進(jìn)程壓力非常大,響應(yīng)速度變慢。但其它已經(jīng)處理完請(qǐng)求
的空閑進(jìn)程卻無(wú)法派上用場(chǎng)。
默認(rèn)情況下這個(gè)參數(shù)的值是on
>> passenger_buffer_response <on|off>
當(dāng)這個(gè)參數(shù)被配置為on時(shí),Passenger會(huì)對(duì)頁(yè)面的輸出進(jìn)行緩存。也就是將response緩存到Passenger
中,然后逐步發(fā)送到客戶端。這樣做的目的是為了避免在response的內(nèi)容比較大時(shí),整個(gè)應(yīng)用的實(shí)例被
鎖住,直到所有的內(nèi)容都被完全發(fā)送到客戶端為止。
默認(rèn)情況下這個(gè)參數(shù)的值是on
>> passenger_friendly_error_pages on|off
可以讓passenger在錯(cuò)誤發(fā)生時(shí)以一種友好的形式來顯示錯(cuò)誤信息(包括堆棧調(diào)用,啟動(dòng)信息,建議等)。
強(qiáng)烈建議在生產(chǎn)環(huán)境下關(guān)閉該參數(shù)
默認(rèn)情況下這個(gè)參數(shù)的值是on
>> passenger_max_pool_size <integer>
這個(gè)參數(shù)用于配置Passenger同一時(shí)刻可以并行的RoR/Rack應(yīng)用實(shí)例的數(shù)量(注意是所有Rails應(yīng)用)。推薦
的參數(shù)值至少等于CPU(內(nèi)核的數(shù)目)。如果有2G的RAM,那么可以配置為30個(gè)。如果是只有256M內(nèi)存
的VPS則建議配置為2
這個(gè)參數(shù)只能在http block中定義,默認(rèn)值是6
>> passenger_min_instances <integer>
這個(gè)參數(shù)用于指定Passenger應(yīng)該保留的Rails應(yīng)用的數(shù)目。它會(huì)在應(yīng)用第一次被訪問時(shí),讓Passenger啟
動(dòng)等于這個(gè)數(shù)目的實(shí)例并一直保持在內(nèi)存中。即便是一直處于空閑狀態(tài)或者到了清除時(shí)間。
注意這個(gè)參數(shù)并不會(huì)pre-start應(yīng)用!也即是說只有在應(yīng)用第一次被訪問時(shí),才會(huì)創(chuàng)建對(duì)應(yīng)數(shù)目的實(shí)例,而
不會(huì)在Nginx啟動(dòng)時(shí)就預(yù)先加載。所以第一次訪問時(shí)有可能會(huì)比較慢。如果需要需要預(yù)加載,需要配合另外
一個(gè)參數(shù)passenger_pre_start
這個(gè)參數(shù)的默認(rèn)值是1
>> passenger_max_instances_per_app <integer>
這個(gè)參數(shù)和上面max_pool_size的區(qū)別是,max_pool_size是限定Passenger可以同時(shí)啟動(dòng)的所有Rails/
Rack應(yīng)用的數(shù)目(可以是多個(gè)app instance的總和),而這個(gè)參數(shù)是用于單獨(dú)指定某個(gè)app instance的數(shù)量
的。這個(gè)參數(shù)可以限制某個(gè)app instance占用了所有的pool和CPU時(shí)間片。
這個(gè)參數(shù)的值必須小于passenger_max_pool_size,0代表單個(gè)應(yīng)用的實(shí)例數(shù)量沒有限制(最大值等于
max_pool_size)。
這個(gè)參數(shù)只能在http block中定義,默認(rèn)值是0
>> passenger_pool_idle_time <integer>
這個(gè)參數(shù)指定了每個(gè)app instance最長(zhǎng)的空閑時(shí)間。當(dāng)一個(gè)應(yīng)用在指定的時(shí)間內(nèi)都沒有接收到請(qǐng)求而處于
空閑狀態(tài)的時(shí)候,它將會(huì)被銷毀而回收所占用的內(nèi)存。
推薦的配置時(shí)間是應(yīng)用頁(yè)面平均訪問時(shí)間 * 2。如果設(shè)置的值過小意味著應(yīng)用會(huì)經(jīng)常被實(shí)例化和銷毀,這
個(gè)過程比較耗時(shí)。如果是在非共享的主機(jī)環(huán)境下,或者需要7*24小時(shí)的響應(yīng),應(yīng)該設(shè)置為0
當(dāng)時(shí)設(shè)置為0不意味著永遠(yuǎn)不會(huì)被銷毀。當(dāng)另外一個(gè)app instance需要啟動(dòng)一個(gè)worker process但Pass-
enger已經(jīng)沒有工作線程了時(shí),會(huì)強(qiáng)制將一個(gè)空閑狀態(tài)的app instance回收以空出worker process
這個(gè)參數(shù)只能在http block中定義,默認(rèn)值是300秒
>> passenger_pre_start <url>
這個(gè)參數(shù)可以讓Passenger在Nginx啟動(dòng)時(shí),預(yù)先加載指定的應(yīng)用。但要注意的是即便是預(yù)先加載的應(yīng)用
在passenger_pool_idel_time 到達(dá)時(shí),也會(huì)被銷毀。如果需要繼續(xù)保留在內(nèi)存中,就要搭配前面提到的
passenger_min_instances。
URL支持完整的server_name,也可以是sub-URI
這個(gè)參數(shù)只能在http block中定義,可以被定義無(wú)限次。
>> passenger_log_level <integer>
這個(gè)參數(shù)可以指定Passenger如何往Nginx的日志文件中寫日志。參數(shù)值越大寫入的內(nèi)容越詳細(xì)。總共
分為4級(jí):0 僅顯示錯(cuò)誤和異常;1 顯示有用的調(diào)試信息(供管理員定位錯(cuò)誤用);2 顯示更加詳細(xì)的信息
(供開發(fā)過程使用);3 顯示所有日志信息。
這個(gè)參數(shù)只能在http block中定義,默認(rèn)的級(jí)別是0
>> passenger_debug_log_file <filename>
這個(gè)參數(shù)可以指定Passenger將錯(cuò)誤和調(diào)試信息寫到何處。
這個(gè)參數(shù)只能在http block中定義,默認(rèn)情況下日志會(huì)寫到Nginx的全局日志文件
>> rails_env <string>
這個(gè)參數(shù)允許針對(duì)不同的應(yīng)用,設(shè)置不同的環(huán)境。可以在http/server/block/if block中定義,每處一次
這個(gè)參數(shù)的默認(rèn)值是production
===========================================================
【分析工具】
===========================================================
>> passenger-memory-stats
這個(gè)命令需要在root用戶下執(zhí)行??梢允褂?rvmsudo passenger-memory-stats 來查看所有的內(nèi)存情況
>> passenger-status
這個(gè)命令同樣需要在root用戶下執(zhí)行。可以使用 rvmsudo passenger-status 來查看Passenger的情況
----------- General information -----------
max = 6 # 等同于passenger_pool_max_size
count = 0 # 當(dāng)前存活的用例,小于等于max值
active = 0 # 當(dāng)前活躍的用例,小于等于count值
inactive = 0 # 當(dāng)前空閑的用例,等于count-active
Waiting on global queue: 0
----------- Domains -----------
/var/www/projects/app1-foobar:
PID: 9617 Sessions: 0 Processed: 7 Uptime: 2m 23s
Sessions: 0 # 當(dāng)前應(yīng)用有多少客戶端連接等待處理
Processed:7 # 截至當(dāng)前為止總共處理了多少個(gè)請(qǐng)求
----------- Application groups -----------
如果應(yīng)用是基于Ruby on Rails的,當(dāng)進(jìn)程被kill掉時(shí),日志會(huì)寫在應(yīng)用自身的日志文件中,而不是Nginx
的日志文件。所以先檢查production.log,如果沒有異常信息再檢查Nginx的error.log文件
===========================================================
【其它】
===========================================================
假設(shè)在Rails應(yīng)用下有Gemfile,那么Passenger會(huì)自動(dòng)執(zhí)行Bundle.setup()方法
當(dāng)應(yīng)用部署為Sub-uri的形式時(shí),由于根路徑發(fā)生了變化,所以靜態(tài)資源(圖片,CSS,JS)的相對(duì)路徑都會(huì)
發(fā)生變化。這個(gè)時(shí)候如果使用靜態(tài)路徑那么所有靜態(tài)資源都將找不到文件,所以無(wú)論在何種部署情況下,
都推薦使用Rails提供的幫助方法:image_tag、stylesheet_link_tag、javascript_include_tag 來創(chuàng)建
相對(duì)的資源路徑。
===========================================================
-------------------------------------------------------------
生活就像打牌,不是要抓一手好牌,而是要盡力打好一手爛牌。
posted on 2011-11-13 23:29
Paul Lin 閱讀(11050)
評(píng)論(1) 編輯 收藏 所屬分類:
RoR