系統基於
ubuntu server 14.04.4 amd64
安裝
第一步 下載並解壓Nginx壓縮包
從Nginx官網下載Nginx,或者在Linux上執行wget http://nginx.org/download/nginx-1.10.1.tar.gz
命令直接下載 解壓nginx-1.10.1.tar.gz
文件:
tar zxvf nginx-1.10.1.tar.gz
第二步 配置
cd nginx-1.10.1
./configure --prefix=/usr/local/nginx
注意: ① 如果之前沒有安裝C compiler(C 編譯器),這一步將報如下錯誤信息:
xueliang@dev:~/download/nginx-1.10.1$ ./configure --prefix=/usr/local/nginx checking for OS
- Linux 4.2.0-27-generic x86_64 checking for C compiler ... not found
./configure: error: C compiler cc is not found
xueliang@dev:~/download/nginx-1.10.1$
可以參考這篇文章安裝C compiler,然后繼續下面的操作
② 如果之前沒有安裝PCRE,這一步將報如下錯誤信息:
checking for PCRE library ... not found checking for PCRE library in /usr/local/ ... not found checking for PCRE library in /usr/include/pcre/ ... not found checking for PCRE library in /usr/pkg/ ... not found checking for PCRE library in /opt/local/ ... not found
./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=
option.
xueliang@dev:~/download/nginx-1.10.1$
可以參考這篇文章安裝PCRE,然后繼續下面的操作
③ 如果之前沒有安裝zlib,這一步將報如下錯誤信息:
checking for md5 in system md library ... not found checking for md5 in system md5 library ... not found checking for md5 in system OpenSSL crypto library ... not found checking for sha1 in system md library ... not found checking for sha1 in system OpenSSL crypto library ... not found checking for zlib library ... not found
./configure: error: the HTTP gzip module requires the zlib library. You can either disable the module by using --without-http_gzip_module option, or install the zlib library into the system, or build the zlib library statically from the source with nginx by using --with-zlib=
option.
xueliang@dev:~/download/nginx-1.10.1$
可以參考這篇文章安裝zlib,然后繼續下面的操作
也可以跳過此步,執行默認安裝,--prefix
的默認值為/usr/local/nginx
,Nginx官網對此有說明:Building nginx from Sources
第三步 編譯
make
第四步 完成安裝
sudo make install
平滑升級
當需要對正在運行的Nginx進行升級時,可以在不停止Nginx的情況下,使用新版本或者重編譯的可執行程序替換舊版本的可執行程序,這里我們從nginx-1.10.1
升級到nginx-1.11.1
。
第一步 備份舊版本
因為Nginx的升級,實質只是用新版本的可執行文件,替換舊版本的可執行程序,所以,對於備份,既可以只備份舊版本可執行文件,也可以打包備份整個舊版本安裝目錄,參考命令分別如下: 只備份舊版本可執行文件
sudo cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak
打包備份整個舊版本安裝目錄
sudo tar -cvf /usr/local/nginx.bak /usr/local/nginx
第二步 下載新版本並解壓Nginx壓縮包
對於新版本Nginx壓縮包的下載和解壓,可以參考本文關於Nginx的安裝部分的第一、二步。
第三步 使用舊版本配置參數,配置並編譯新版本Nginx
因為只是對Nginx進行升級,並不涉及配置參數的修改,所以,我們一般使用和舊版本相同的配置(當然你也可以使用全新的配置信息),來編譯新版本的Nginx,使用如下命令查看舊版本配置信息:
/usr/local/nginx/sbin/nginx -V
可以得到結果如下:
xueliang@dev:/download/nginx-1.11.1$ /usr/local/nginx/sbin/nginx -V nginx version: nginx/1.10.1 built by gcc 4.8.4 (Ubuntu 4.8.4-2ubuntu114.04.3) configure arguments: --prefix=/usr/local/nginx xueliang@dev:~/download/nginx-1.11.1$
其中 [configure arguments: --prefix=/usr/local/nginx] 這一行即為舊版本Nginx配置信息,這里可以看出,舊版本只是指定了安裝路徑,使用[configure arguments:]后面的參數信息,對新版本Nginx作相同配置,然后進行編譯:
./configure --prefix=/usr/local/nginx
第四步 編譯新版本Nginx可執行程序
make
第五步 用新版本Nginx可執行程序覆蓋舊版本可執行程序
在上一步的基礎上,執行一下命令即可:
sudo cp objs/nginx /usr/local/nginx/sbin/nginx
執行這條命令,可能會報以下異常,提示文件被占用:
xueliang@dev:/download/nginx-1.11.1$ sudo cp objs/nginx /usr/local/nginx/sbin/nginx cp: cannot create regular file ‘/usr/local/nginx/sbin/nginx’: Text file busy xueliang@dev:/download/nginx-1.11.1$
可以使用以下命令進行強制覆蓋:
sudo cp -rfp objs/nginx /usr/local/nginx/sbin/nginx
第六步 啟動新版本Nginx主進程
發送 USR2信號給舊版本主進程號:
kill -USR2 舊版本的Nginx主進程號
舊版本Nginx主進程接收到-USR2
信號,將重命名它的.pid
文件為.oldpid
,然后執行新版本的Nginx可執行程序,依次啟動新版本的主進程和工作進程:
<thead> <tr> <th align="right">PID</th> <th align="right">PPID</th> <th align="right">USER</th> <th align="right">%CPU</th> <th align="right">VSZ</th> <th align="right">WCHAN</th> <th>COMMAND</th> </tr> </thead> <tbody> <tr> <td align="right">33126</td> <td align="right">1</td> <td align="right">root</td> <td align="right">0.0</td> <td align="right">1164</td> <td align="right">pause</td> <td>nginx: master process /usr/local/nginx/sbin/nginx</td> </tr> <tr> <td align="right">33134</td> <td align="right">33126</td> <td align="right">nobody</td> <td align="right">0.0</td> <td align="right">1368</td> <td align="right">kqread</td> <td>nginx: worker process (nginx)</td> </tr> <tr> <td align="right">33135</td> <td align="right">33126</td> <td align="right">nobody</td> <td align="right">0.0</td> <td align="right">1380</td> <td align="right">kqread</td> <td>nginx: worker process (nginx)</td> </tr> <tr> <td align="right">33136</td> <td align="right">33126</td> <td align="right">nobody</td> <td align="right">0.0</td> <td align="right">1368</td> <td align="right">kqread</td> <td>nginx: worker process (nginx)</td> </tr> <tr> <td align="right">36264</td> <td align="right">33126</td> <td align="right">root</td> <td align="right">0.0</td> <td align="right">1148</td> <td align="right">pause</td> <td>nginx: master process /usr/local/nginx/sbin/nginx</td> </tr> <tr> <td align="right">36265</td> <td align="right">36264</td> <td align="right">nobody</td> <td align="right">0.0</td> <td align="right">1364</td> <td align="right">kqread</td> <td>nginx: worker process (nginx)</td> </tr> <tr> <td align="right">36266</td> <td align="right">36264</td> <td align="right">nobody</td> <td align="right">0.0</td> <td align="right">1364</td> <td align="right">kqread</td> <td>nginx: worker process (nginx)</td> </tr> <tr> <td align="right">36267</td> <td align="right">36264</td> <td align="right">nobody</td> <td align="right">0.0</td> <td align="right">1364</td> <td align="right">kqread</td> <td>nginx: worker process (nginx)</td> </tr> </tbody> </table>
第七步 從容關閉舊版本的工作進程
此時,新、舊版本的Nginx實例會同時運行,共同處理請求,如果此時給舊版本主進程發送
WINCH
信號,舊版本主進程將會給它的工作進程發送消息,請求它們從容關閉,此后,舊版本的工作進程開始逐步退出:
<thead> <tr> <th align="right">PID</th> <th align="right">PPID</th> <th align="right">USER</th> <th align="right">%CPU</th> <th align="right">VSZ</th> <th align="right">WCHAN</th> <th>COMMAND</th> </tr> </thead> <tbody> <tr> <td align="right">33126</td> <td align="right">1</td> <td align="right">root</td> <td align="right">0.0</td> <td align="right">1164</td> <td align="right">pause</td> <td>nginx: master process /usr/local/nginx/sbin/nginx</td> </tr> <tr> <td align="right">33135</td> <td align="right">33126</td> <td align="right">nobody</td> <td align="right">0.0</td> <td align="right">1380</td> <td align="right">kqread</td> <td>nginx: worker process is shutting down (nginx)</td> </tr> <tr> <td align="right">36264</td> <td align="right">33126</td> <td align="right">root</td> <td align="right">0.0</td> <td align="right">1148</td> <td align="right">pause</td> <td>nginx: master process /usr/local/nginx/sbin/nginx</td> </tr> <tr> <td align="right">36265</td> <td align="right">36264</td> <td align="right">nobody</td> <td align="right">0.0</td> <td align="right">1364</td> <td align="right">kqread</td> <td>nginx: worker process (nginx)</td> </tr> <tr> <td align="right">36266</td> <td align="right">36264</td> <td align="right">nobody</td> <td align="right">0.0</td> <td align="right">1364</td> <td align="right">kqread</td> <td>nginx: worker process (nginx)</td> </tr> <tr> <td align="right">36267</td> <td align="right">36264</td> <td align="right">nobody</td> <td align="right">0.0</td> <td align="right">1364</td> <td align="right">kqread</td> <td>nginx: worker process (nginx)</td> </tr> </tbody> </table>
從容關閉舊版本的工作進程命令:
kill -WINCH 舊版本的Nginx主進程號
第八步 從容關閉舊版本的主進程,完成Nginx的升級
經過一段時間后,舊的工作進程(work process)處理完了所有已連接的請求后退出,僅由新版本的工作進程來處理新的請求了:
<thead> <tr> <th align="right">PID</th> <th align="right">PPID</th> <th align="right">USER</th> <th align="right">%CPU</th> <th align="right">VSZ</th> <th align="right">WCHAN</th> <th>COMMAND</th> </tr> </thead> <tbody> <tr> <td align="right">33126</td> <td align="right">1</td> <td align="right">root</td> <td align="right">0.0</td> <td align="right">1164</td> <td align="right">pause</td> <td>nginx: master process /usr/local/nginx/sbin/nginx</td> </tr> <tr> <td align="right">36264</td> <td align="right">33126</td> <td align="right">root</td> <td align="right">0.0</td> <td align="right">1148</td> <td align="right">pause</td> <td>nginx: master process /usr/local/nginx/sbin/nginx</td> </tr> <tr> <td align="right">36265</td> <td align="right">36264</td> <td align="right">nobody</td> <td align="right">0.0</td> <td align="right">1364</td> <td align="right">kqread</td> <td>nginx: worker process (nginx)</td> </tr> <tr> <td align="right">36266</td> <td align="right">36264</td> <td align="right">nobody</td> <td align="right">0.0</td> <td align="right">1364</td> <td align="right">kqread</td> <td>nginx: worker process (nginx)</td> </tr> <tr> <td align="right">36267</td> <td align="right">36264</td> <td align="right">nobody</td> <td align="right">0.0</td> <td align="right">1364</td> <td align="right">kqread</td> <td>nginx: worker process (nginx)</td> </tr> </tbody> </table>
應該注意的是,此時,舊版本的主進程還尚未關閉它監聽的套接字,如果有需要,你仍可以恢復舊版本工作進程。如果由於某些原因,新版本的可執行文件運行情況不理想,下面有幾種方案可供參考:
- 給舊版本主進程發送
HUP
信號。舊版本主進程將在不重新讀取配置信息的情況下,重新開啟工作進程。然后,通過給新版本主進程發送QUIT
信號,所有新版本的進程將會從容關閉。- 給新版本主進程發送
TERM
信號。然后,他將會給它的工作進程發送消息,要求它們立即退出,緊接着,這些工作進程就會立即退出。(如果因為某些原因,新版本進程沒有退出,應該給新版本主進程發送KILL
信號,強制新版本主進程退出。)新版本主進程退出的同時,舊版本主進程將會自動啟動它的工作進程。 新版本主進程退出后,舊版本主進程將會移除名字以.oldpid
結尾的文件,恢復為它的.pid
文件。 如果升級成功,應該給舊版本主進程發送QUIT
信號,使其退出,只保留新版本進程:
<thead> <tr> <th align="right">PID</th> <th align="right">PPID</th> <th align="right">USER</th> <th align="right">%CPU</th> <th align="right">VSZ</th> <th align="right">WCHAN</th> <th>COMMAND</th> </tr> </thead> <tbody> <tr> <td align="right">36264</td> <td align="right">33126</td> <td align="right">root</td> <td align="right">0.0</td> <td align="right">1148</td> <td align="right">pause</td> <td>nginx: master process /usr/local/nginx/sbin/nginx</td> </tr> <tr> <td align="right">36265</td> <td align="right">36264</td> <td align="right">nobody</td> <td align="right">0.0</td> <td align="right">1364</td> <td align="right">kqread</td> <td>nginx: worker process (nginx)</td> </tr> <tr> <td align="right">36266</td> <td align="right">36264</td> <td align="right">nobody</td> <td align="right">0.0</td> <td align="right">1364</td> <td align="right">kqread</td> <td>nginx: worker process (nginx)</td> </tr> <tr> <td align="right">36267</td> <td align="right">36264</td> <td align="right">nobody</td> <td align="right">0.0</td> <td align="right">1364</td> <td align="right">kqread</td> <td>nginx: worker process (nginx)</td> </tr> </tbody> </table>
添加模塊
剛接觸Nginx時,只知道Nginx的功能是分模塊的,並不清楚有些模塊默認是不參與到構建中去的,比如
ngx_http_ssl_module
模塊,是用來支持https
協議的,默認情況下是沒有構建到Nginx中的。 隨着業務不斷擴展,如果需要Nginx支持某些模塊,而這些模塊默認不在Nginx的構建計划中,構建Nginx時,又沒有指定加入這些模塊,該怎么辦呢?是否能夠給已經運行的Nginx動態添加這些模塊呢?答案是肯定的! 給運行中的Nginx動態添加模塊的方案,與上面提到的平滑升級Nginx的方案很類似。下面我們來看一下如何給運行中的Nginx添加ngx_http_ssl_module
模塊。第一步 查看運行中的Nginx版本,並下載、解壓對應版本的壓縮包
查看Nginx版本:
/usr/local/nginx/sbin/nginx -v
結果:
xueliang@dev:$ /usr/local/nginx/sbin/nginx -v nginx version: nginx/1.11.1 xueliang@dev:$
或者:
/usr/local/nginx/sbin/nginx -V
結果:
xueliang@dev:$ /usr/local/nginx/sbin/nginx -V nginx version: nginx/1.11.1 built by gcc 4.8.4 (Ubuntu 4.8.4-2ubuntu114.04.3) configure arguments: --prefix=/usr/local/nginx xueliang@dev:~$
這里可以看出,正在運行的Nginx版本為
1.11.1
,參照安裝Nginx部分,下載並解壓對應版本的Nginx第二步 編譯Nginx,同時加入需要模塊配置
參考平滑升級的第三步,查看運行中的Nginx的配置參數,並在最后追加
-with-http_ssl_module
。 如:原配置信息為--prefix=/usr/local/nginx
,則新配置信息為--prefix=/usr/local/nginx --with_http_ssl_module
,配置Nginx執行的命令如下:./configure --prefix=/usr/local/nginx --with_http_ssl_module
第三步 平滑重啟Nginx,完成動態模塊添加
這一步可以參考平滑升級的第四至八步
原文鏈接:http://xueliang.org/article/detail/20160615172540639