問題
最近在遷移即將到期的虛擬機(jī)思恐,虛擬機(jī)上面跑著Nginx對(duì)外提供服務(wù)沾谜。在切換到新的虛擬機(jī)后膊毁,有業(yè)務(wù)方反映上傳圖片失敗,Nginx返回響應(yīng)碼411.
第一次遇到這種問題基跑,在網(wǎng)上搜索一番后發(fā)現(xiàn)是低版本Nginx存在的問題婚温。新的虛擬機(jī)上面的Nginx是通過yum源安裝的,版本為1.0.15. 該版本的Nginx在處理 POST 方式上傳文件的時(shí)候會(huì)觸發(fā)該問題媳否,給客戶端返回響應(yīng)碼411.
解決方案
OK栅螟,知道是Nginx版本太低導(dǎo)致的,那解決方案就是升級(jí)Nginx了篱竭。如何不影響線上服務(wù)平滑升級(jí)Nginx呢力图?
平滑升級(jí)Nginx
源碼編譯
到Nginx官網(wǎng)下載最新穩(wěn)定版:
wget http://nginx.org/download/nginx-1.8.0.tar.gz
解壓縮并進(jìn)入源碼目錄:
tar zxf nginx-1.8.0.tar.gz
cd nginx-1.8.0
查看老版本Nginx的編譯配置:
nginx -V
復(fù)制上述命令輸出的配置參數(shù),加到 ./configure 后面掺逼,修改prefix參數(shù)為其它目錄:
./configure --prefix=/home/ubuntu/nginx <其它復(fù)制過來的配置參數(shù)>
執(zhí)行完上面的命令搪哪,你可能看到如下錯(cuò)誤信息,提示rewrite模塊需要PCRE庫(kù):
./configure: error: the HTTP rewrite module requires the PCRE library.
You can either disable the module by using --without-http_rewrite_module
option, or install the PCRE library into the system, or build the PCRE library
statically from the source with nginx by using --with-pcre=<path> option.
到PCRE官方FTP服務(wù)器下載PCRE并解壓縮:
wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.36.tar.gz
tar zxf pcre-8.36.tar.gz
在Nginx的源碼目錄再次執(zhí)行配置命令坪圾,這次加上--with-pcre選項(xiàng):
./configure --prefix=/home/ubuntu/nginx <其它復(fù)制過來的配置參數(shù)> --with-pcre=/home/ubuntu/pcre-8.36
如果仍然提示缺少一些依賴庫(kù)晓折,安裝這些庫(kù):
# on ubuntu/debian system
sudo apt-get install libssl-dev libxml2-dev libxslt-dev libgd-dev libgeoip-dev
配置無誤后,然后執(zhí)行make命令兽泄。至此漓概,編譯好的nginx可執(zhí)行文件在當(dāng)前目錄的子目錄objs里面。
平滑升級(jí)
-
備份舊版本的nginx可執(zhí)行文件:
<pre class=”brush: bash; gutter: false;”>
sudo mv /usr/sbin/nginx /usr/sbin/nginx.old
</pre> -
把編譯好的nginx可執(zhí)行文件復(fù)制過去:
<pre class=”brush: bash; gutter: false;”>
sudo cp objs/nginx /usr/sbin/nginx
</pre> -
測(cè)試Nginx配置是否正確:
<pre class=”brush: bash; gutter: false;”>
sudo /usr/sbin/nginx -t
</pre>如果測(cè)試正確病梢,可以進(jìn)入下一步操作胃珍。
-
給舊版本的nginx主進(jìn)程發(fā)送USR2信號(hào):
<pre class=”brush: bash; gutter: false;”>
ubuntu@me:~/nginx-1.8.0$ ps -ef | grep nginx
root 9962 1 0 2014 ? 00:00:00 nginx: master process /usr/sbin/nginx
ubuntu 31321 9962 0 Apr23 ? 00:04:58 nginx: worker process
ubuntu 31322 9962 0 Apr23 ? 00:05:20 nginx: worker process
ubuntu 31323 9962 0 Apr23 ? 00:05:46 nginx: worker process
ubuntu 31324 9962 0 Apr23 ? 00:00:18 nginx: worker process
ubuntu@me:~/nginx-1.8.0$ sudo kill -USR2 9962
ubuntu@me:~/nginx-1.8.0$ ps -ef | grep nginx
root 9962 1 0 2014 ? 00:00:00 nginx: master process /usr/sbin/nginx
root 29149 9962 0 04:47 ? 00:00:00 nginx: master process /usr/sbin/nginx
ubuntu 29150 29149 0 04:47 ? 00:00:00 nginx: worker process
ubuntu 29151 29149 0 04:47 ? 00:00:00 nginx: worker process
ubuntu 29152 29149 0 04:47 ? 00:00:00 nginx: worker process
ubuntu 29153 29149 0 04:47 ? 00:00:00 nginx: worker process
ubuntu 31321 9962 0 Apr23 ? 00:04:58 nginx: worker process
ubuntu 31322 9962 0 Apr23 ? 00:05:20 nginx: worker process
ubuntu 31323 9962 0 Apr23 ? 00:05:46 nginx: worker process
ubuntu 31324 9962 0 Apr23 ? 00:00:18 nginx: worker process
</pre>可以看到,在發(fā)送USR2信號(hào)后蜓陌,新的nginx master進(jìn)程和worker進(jìn)程開始運(yùn)行觅彰。此時(shí),新nginx和舊nginx同時(shí)在工作钮热。
-
接下來填抬,給舊版本nginx主進(jìn)程發(fā)送WINCH信號(hào):
<pre class=”brush: bash; gutter: false;”>
ubuntu@me:~/nginx-1.8.0$ sudo kill -WINCH 9962
ubuntu@me:~/nginx-1.8.0$ ps -ef | grep nginx
root 9962 1 0 2014 ? 00:00:00 nginx: master process /usr/sbin/nginx
root 29149 9962 0 04:47 ? 00:00:00 nginx: master process /usr/sbin/nginx
ubuntu 29150 29149 0 04:47 ? 00:00:00 nginx: worker process
ubuntu 29151 29149 0 04:47 ? 00:00:00 nginx: worker process
ubuntu 29152 29149 0 04:47 ? 00:00:00 nginx: worker process
ubuntu 29153 29149 0 04:47 ? 00:00:00 nginx: worker process
</pre>這時(shí),可以看到舊nginx的worker進(jìn)程退出了隧期,不再處理新的請(qǐng)求飒责,新的請(qǐng)求都由新nginx處理。
-
接下來是平滑升級(jí)的最后一步仆潮,也就是給舊版本nginx主進(jìn)程發(fā)送QUIT信號(hào):
<pre class=”brush: bash; gutter: false;”>
ubuntu@me:~/nginx-1.8.0$ sudo kill -QUIT 9962
ubuntu@me:~/nginx-1.8.0$ ps -ef | grep nginx
root 29149 1 0 04:47 ? 00:00:00 nginx: master process /usr/sbin/nginx
ubuntu 29150 29149 0 04:47 ? 00:00:00 nginx: worker process
ubuntu 29151 29149 0 04:47 ? 00:00:00 nginx: worker process
ubuntu 29152 29149 0 04:47 ? 00:00:00 nginx: worker process
ubuntu 29153 29149 0 04:47 ? 00:00:00 nginx: worker process
</pre>好了宏蛉,至此舊nginx的主進(jìn)程也退出了。我們已成功平滑升級(jí)到新版nginx.
版本回退
如果在執(zhí)行上面的平滑升級(jí)過程中反悔了想回退性置,該怎么辦拾并?
- 給舊版本nginx主進(jìn)程發(fā)送HUP信號(hào)
- 給新版本nginx主進(jìn)程發(fā)送QUIT信號(hào)
- 從備份中還原nginx可執(zhí)行文件
升級(jí)過程中出問題
按照上面的升級(jí)步驟,筆者在ubuntu系統(tǒng)上成功將Nginx升級(jí)到1.8版本。但是在公司虛擬機(jī)CentOS 6.4上執(zhí)行升級(jí)操作卻沒有成功嗅义。問題在執(zhí)行第3步的時(shí)候个榕,檢查Nginx配置失敗,提示nginx.pm文件版本號(hào)不匹配芥喇。