平穩切換nginx版本

来源:http://www.cnblogs.com/f-ck-need-u/archive/2017/10/12/7658111.html
-Advertisement-
Play Games

在說明如何穩定安全地升級、降級已經在運行中的nginx之前,需要先瞭解nginx支持的幾種信號。以下幾種是主進程可以接收的信號,註意worker進程也可以接收一些信號,但和主進程的信號處理機制有些不一樣,且主進程支持的信號worker進程不一定支持。具體可見man nginx。 graceful s ...


在說明如何穩定安全地升級、降級已經在運行中的nginx之前,需要先瞭解nginx支持的幾種信號。以下幾種是主進程可以接收的信號,註意worker進程也可以接收一些信號,但和主進程的信號處理機制有些不一樣,且主進程支持的信號worker進程不一定支持。具體可見man nginx。

SIGINT, SIGTERM  立即殺掉nginx主(即所有進程)
SIGQUIT          graceful stop主進程
SIGWINCH         graceful stop所有的worker進程
SIGHUP           reload配置文件,並使老的worker進程graceful stop
SIGUSR1          重新打開日誌文件(Reopen log files)
SIGUSR2          線上切換nginx可執行程式(Upgrade the nginx executable on the fly)

graceful stop的行為是:(1)進程不再監聽、接受新的請求;(2)進程繼續處理正在處理的請求,但處理完成後銷毀。

1. 升級

如果想對一個已運行的nginx實例進行版本升級,或者因為重新編譯了一個版本而替換舊版本,可以考慮按照以下一系列過程來平穩、安全地升級。當然,如果直接停止服務不會產生多大影響,直接停掉再啟動新版本nginx實例更方便簡單。

  • 1.將新版本的nginx命令路徑替換掉舊的nginx命令。

通常,對於編譯安裝的nginx來說,採用軟鏈接的方式比較便捷。例如舊版本的安裝路徑為/usr/local/nginx-1.12.0,為其建立一個軟鏈接/usr/local/nginx,如果有新版本/usr/local/nginx-1.12.1,只需修改軟鏈接/usr/local/nginx的指向目標為/usr/local/nginx-1.12.1即可。這樣/usr/local/nginx/sbin/nginx就會隨著軟鏈接的指向改變而指向新nginx程式。

  • 2.對舊nginx實例的主進程發送USR2信號。
kill -USR2 `cat /var/run/nginx/nginx.pid`

該信號提示nginx舊的主進程要升級,並執行新的nginx程式。例如步驟1中,舊的nginx主進程為/usr/local/nginx/sbin/nginx,但其指向的是/usr/local/nginx-1.12.0/sbin/nginx,發送該信號後仍將執行/usr/local/nginx/sbin/nginx,但此時因為軟鏈接目標已改變,使得此時啟動的nginx已經是/usr/local/nginx-1.12.1/sbin/nginx程式。

[root@xuexi ~]# ps aux | egrep '(ngin[x]|PI[D])'
USER        PID %CPU %MEM    VSZ   RSS TTY  STAT START   TIME COMMAND
root     103753  0.0  0.3 122720  7360 ?    S    17:01   0:00 nginx: master process /usr/sbin/nginx
nginx    103754  0.0  0.1 125248  3520 ?    S    17:01   0:00 nginx: worker process
nginx    103755  0.0  0.1 125248  3520 ?    S    17:01   0:00 nginx: worker process
nginx    103756  0.0  0.1 125248  3520 ?    S    17:01   0:00 nginx: worker process
nginx    103757  0.0  0.1 125248  3520 ?    S    17:01   0:00 nginx: worker process
root     103919  0.0  0.3 122720  7364 ?    S    17:44   0:00 nginx: master process /usr/sbin/nginx
nginx    103920  0.0  0.1 125248  3524 ?    S    17:44   0:00 nginx: worker process
nginx    103921  0.0  0.1 125248  3524 ?    S    17:44   0:00 nginx: worker process
nginx    103922  0.0  0.1 125248  3524 ?    S    17:44   0:00 nginx: worker process
nginx    103923  0.0  0.1 125248  3524 ?    S    17:44   0:00 nginx: worker process

此外,發送該信號後將會切換pid文件,舊的pid文件被重命名為nginx.pid.oldbin,記錄的是舊的nginx主進程pid值,新的pid文件為nginx.pid,記錄的是新啟動的nginx的主進程pid值。

[root@xuexi ~]# ls /var/run/nginx*     
/var/run/nginx.pid  /var/run/nginx.pid.oldbin
  • 3.graceful stop舊的主進程號。
kill -QUIT `cat /var/run/nginx/nginx.pid.oldbin`

向舊的主進程號發送QUIT信號,該信號將使得主進程以graceful的方式關閉。這將使得舊的主進程、舊的worker進程不再接受任何新請求,但卻會把正在處理過程中的請求處理完畢,然後被銷毀退出。

  • 4.更穩妥的方式是先讓worker進程graceful stop,在新版本的nginx實例運行一小段時間後如果正常工作,再graceful stop舊的主進程。
kill -WINCH `cat /var/run/nginx/nginx.pid.oldbin`
# a period of time goes, graceful stop old master nginx
kill -QUIT `cat /var/run/nginx/nginx.pid.oldbin`

在發送WINCH信號給舊的主進程後,舊的worker進程將逐漸退出,但舊的主進程卻會保留不退出。

[root@xuexi ~]# ps aux | egrep '(ngin[x]|PI[D])'
USER        PID %CPU %MEM    VSZ   RSS TTY   STAT START   TIME COMMAND
root     103753  0.0  0.3 122720  7432 ?     S    17:01   0:00 nginx: master process /usr/sbin/nginx
root     103919  0.0  0.3 122720  7364 ?     S    17:44   0:00 nginx: master process /usr/sbin/nginx
nginx    103920  0.0  0.1 125248  3524 ?     S    17:44   0:00 nginx: worker process
nginx    103921  0.0  0.1 125248  3524 ?     S    17:44   0:00 nginx: worker process
nginx    103922  0.0  0.1 125248  3524 ?     S    17:44   0:00 nginx: worker process
nginx    103923  0.0  0.1 125248  3524 ?     S    17:44   0:00 nginx: worker process

如果發現新版本的nginx實例不滿意,可以直接向舊主進程號發送HUP信號,這樣舊的主進程就會重新讀取配置文件並fork新的worker進程,再將新的主進程號殺掉(可以graceful stop),就可以還原為舊版本的nginx實例。

2. 降級

上面第4步其實就是最安全的降級方式。即:

kill -HUP `cat /var/run/nginx/nginx.pid.oldbin`
kill -QUIT `cat /var/run/nginx/nginx.pid`

但如果舊的主進程號已經被殺掉了,目前只有新版本的nginx實例在運行,那麼只需以升級的步驟進行降級即可。即:

kill -USR2 `cat /var/run/nginx/nginx.pid`
kill -QUIT `cat /var/run/nginx/nginx.pid.oldbin`

3.一鍵升級腳本

以下是升級的腳本。

#!/bin/sh
#
# Legacy action script for "service nginx upgrade"

# Source function library.
[ -f /etc/rc.d/init.d/functions ] && . /etc/rc.d/init.d/functions

if [ -f /etc/sysconfig/nginx ]; then
    . /etc/sysconfig/nginx
fi

prefix=/usr/local/nginx
prog=nginx
nginx=$prefix/sbin/nginx
conffile=$prefix/conf/nginx.conf
pidfile=/var/run/nginx.pid
SLEEPSEC=${SLEEPSEC:-1}
UPGRADEWAITLOOPS=${UPGRADEWAITLOOPS:-5}

oldbinpidfile=${pidfile}.oldbin

# 配置文件語法檢查
${nginx} -t -c ${conffile} -q || return 6
echo -n $"Starting new master $prog: "
# 發送USR2信號升級nginx可執行程式
killproc -p ${pidfile} ${prog} -USR2
echo

for i in `/usr/bin/seq $UPGRADEWAITLOOPS`; do
    /bin/sleep $SLEEPSEC
    if [ -f ${oldbinpidfile} -a -f ${pidfile} ]; then
        echo -n $"Graceful shutdown of old $prog: "
        # graceful stop舊主nginx主進程
        killproc -p ${oldbinpidfile} ${prog} -QUIT
        echo
        exit 0
    fi
done

echo $"Upgrade failed!"
exit 1

回到Linux系列文章大綱:http://www.cnblogs.com/f-ck-need-u/p/7048359.html

回到網站架構系列文章大綱:http://www.cnblogs.com/f-ck-need-u/p/7576137.html

回到資料庫系列文章大綱:http://www.cnblogs.com/f-ck-need-u/p/7586194.html

轉載請註明出處:http://www.cnblogs.com/f-ck-need-u/p/7658111.html

註:若您覺得這篇文章還不錯請點擊右下角推薦,您的支持能激發作者更大的寫作熱情,非常感謝!


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 更新時間: Linux Usage 緣起:最近將系統更換為Linux,雖然之前有用過,但只是當作嘗試,未當為主系統,這次下定決心以它為主系統,懶得去糾結使用win的一種不道德感及不爽感,游戲及娛樂與人與己無益,放棄 https://mirrors.tuna.tsinghua.edu.cn/linux ...
  • 一.背景: arm linux的內核版本是3.13.0 二.準備工作 添加alsa驅動到內核中,也就是在編譯內核的時候加入以下選項: 接下來就重新編譯內核即可 三.交叉編譯alsa-lib和alsa-utils (alsa-utils是一系列的音頻設備控制工具,而alsa-lib是alsa-util ...
  • MongoDB資料庫基本用法 用戶相關 1、添加一個用戶 2、資料庫認證、安全模式 db.auth("userName", "123123"); 3、顯示當前所有用戶 show users; 4、刪除用戶 db.removeUser("userName"); show dbs:顯示資料庫列表 sho ...
  • fileclear.sh task.crontab task.null.crontab是一個沒有內容的空文件 開啟定時任務 停止定時任務 crontab [-u username] [-l|-e|-r] 參數: -u: 只有root才能進行這個任務,也即幫其他用戶新建/刪除crontab工作調度; ...
  • linux內核提供了一個container_of()巨集,可以根據結構體某個成員的地址找到父結構的地址。 而在Nginx也是效仿採用一樣的巨集獲取父結構地址。 ...
  • nginx可以在不停止服務的情況下,升級更新自己的bin文件,那這些是怎麼實現的呢,讓我們看一下nginx的源碼 ...
  • 前言:DNS,耳熟能詳的東西,內容太多,小編也不太好講清,只能寫幾個實驗詳解,供大家參考。 一、簡單介紹 1、DNS:通過主機名,最終得到該主機名對應的IP地址的過程叫做功能變數名稱解析(或主機名解析)。 埠號:53/udp, 53/tcp 2、等級 根域 :世界有13個ip地址管理,有10個在美國,1個 ...
  • 能在Linux中運行的文本編輯器很多,每個人喜歡的也不一樣。各種不同的Linux發行版一定會內置Vi編輯器,其它編輯器可能不會內置,需要自己安裝。所以必須學會Vi的使用,以應對在新的Linux環境。Vim編輯器是Vi編輯器的升級版,功能比Vi強大,並且相容Vi的操作。所以我就直接學習Vim編輯器。( ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...