亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 網站 > Nginx > 正文

nginx信號集案例詳解

2024-08-30 12:29:17
字體:
來源:轉載
供稿:網友

之前工作時候,一臺引流測試機器的一個 ngx_lua 服務突然出現了一些 HTTP/500 響應,從錯誤日志打印的堆棧來看,是不久前新發布的版本里添加的一個 Lua table 不存在,而有代碼向其進行索引導致的。這令人百思不得其解,如果是版本回退導致的,那么為什么使用這個 Lua table 的代碼沒有被回退,偏偏定義這個 table 的代碼被回退了呢?

經過排查發現,當時 nginx 剛剛完成熱更新操作,舊的 master 進程還存在,因為要準備機器重啟,先切掉了引流流量(但有些請求還在),同時系統觸發了 nginx -s stop,這才導致了這個問題。

場景復現

下面我將使用一個原生的 nginx,在我的安裝了 fedora26 的虛擬機上復現這個過程,我使用的 nginx 版本是目前最新的 1.13.4

首先啟動 nginx

nginx,信號集

可以看到 master 和 worker 都已經在運行。

接著我們向 master 發送一個 SIGUSR2 信號,當 nginx 核心收到這個信號后,就會觸發熱更新。

nginx,信號集

可以看到新的 master 和該 master fork 出來的 worker 已經在運行了,此時我們接著向舊 master 發送一個 SIGWINCH 信號,舊 master 收到這個信號后,會向它的 worker 發送 SIGQUIT,于是舊 master 的 worker 進程就會退出:

nginx,信號集

此時只剩下舊的 master,新的 master 和新 master 的 worker 在運行,這和當時線上運行的情況類似。

接著我們使用 stop 命令:

nginx,信號集

我們會發現,新的 master 和它的 worker 都已經退出,而舊的 master 還在運行,并產生了 worker 出來。這就是當時線上的情況了。

事實上,這個現象和 nginx 自身的設計有關:當舊的 master 準備產生 fork 新的 master 之前,它會把 nginx.pid 這個文件重命名為 nginx.pid.oldbin,然后再由 fork 出來的新的 master 去創建新的 nginx.pid,這個文件將會記錄新 master 的 pid。nginx 認為熱更新完成之后,舊 master 的使命幾乎已經結束,之后它隨時會退出,因此之后的操作都應該由新 master 接管。當然,在舊 master 沒有退出的情況下通過向新 master 發送 SIGUSR2 企圖再次熱更新是無效的,新 master 只會忽略掉這個信號然后繼續它自己的工作。

問題分析

更不巧的是,我們上面提到的這個 Lua table,定義它的 Lua 文件早在運行 init_by_lua 這個 hook 的時候,就已經被 LuaJIT 加載到內存并編譯成字節碼了,那么顯然舊的 master 必然沒有這個 Lua table,因為它加載那部分 Lua 代碼是舊版本的。

而索引該 table 的 Lua 代碼并沒有在 init_by_lua 的時候使用到,這些代碼都是在 worker 進程里被加載起來的,這時候項目目錄里的代碼都是最新的,所以 worker 進程加載的都是最新的代碼,如果這些 worker 進程處理到相關的請求,就會出現 Lua 運行時錯誤,外部表現則是對應的 HTTP 500。

吸收了這個教訓之后,我們需要更加合理地關閉我們的 nginx 服務。 所以一個更加合理的 nginx 服務啟動關閉腳本是必需的,網上流傳的一些腳本并沒有對這個現象做處理,我們更應該參考 NGINX 官方提供的腳本。

nginx,信號集

這段代碼引自 NGINX 官方的 /etc/init.d/nginx 。

nginx 信號集

接下來我們來全面梳理下 nginx 信號集,這里不會涉及到源碼細節,感興趣的同學可以自行閱讀相關源碼。

我們有兩種方式來向 master 進程發送信號,一種是通過 nginx -s signal 來操作,另一種是通過 kill 命令手動發送。

第一種方式的原理是,產生一個新進程,該進程通過 nginx.pid 文件得到 master 進程的 pid,然后把對應的信號發送到 master,之后退出,這種進程被稱為 signaller。

第二種方式要求我們了解 nginx -s signal 到真實信號的映射。下表是它們的映射關系:

operation signal
reload SIGHUP
reopen SIGUSR1
stop SIGTERM
quit SIGQUIT
hot update SIGUSR2 & SIGWINCH & SIGQUIT
stop vs quit

stop 發送 SIGTERM 信號,表示要求強制退出,quit 發送 SIGQUIT,表示優雅地退出。 具體區別在于,worker 進程在收到 SIGQUIT 消息(注意不是直接發送信號,所以這里用消息替代)后,會關閉監聽的套接字,關閉當前空閑的連接(可以被搶占的連接),然后提前處理所有的定時器事件,最后退出。沒有特殊情況,都應該使用 quit 而不是 stop。

reload

master 進程收到 SIGHUP 后,會重新進行配置文件解析、共享內存申請,等一系列其他的工作,然后產生一批新的 worker 進程,最后向舊的 worker 進程發送 SIGQUIT 對應的消息,最終無縫實現了重啟操作。

reopen

master 進程收到 SIGUSR1 后,會重新打開所有已經打開的文件(比如日志),然后向每個 worker 進程發送 SIGUSR1 信息,worker 進程收到信號后,會執行同樣的操作。reopen 可用于日志切割,比如 NGINX 官方就提供了一個方案:

nginx,信號集

這里 sleep 1 是必須的,因為在 master 進程向 worker 進程發送 SIGUSR1 消息到 worker 進程真正重新打開 access.log 之間,有一段時間窗口,此時 worker 進程還是向文件 access.log.0 里寫入日志的。通過 sleep 1s,保證了 access.log.0 日志信息的完整性(如果沒有 sleep 而直接進行壓縮,很有可能出現日志丟失的情況)。

hot update

某些時候我們需要進行二進制熱更新,nginx 在設計的時候就包含了這種功能,不過無法通過 nginx 提供的命令行完成,我們需要手動發送信號。

通過上面的問題復現,大家應該已經了解到如何進行熱更新了,我們首先需要給當前的 master 進程發送 SIGUSR2,之后 master 會重命名 nginx.pid 到 nginx.pid.oldbin,然后 fork 一個新的進程,新進程會通過 execve 這個系統調用,使用新的 nginx ELF 文件替換當前的進程映像,成為新的 master 進程。新 master 進程起來之后,就會進行配置文件解析等操作,然后 fork 出新的 worker 進程開始工作。

接著我們向舊的 master 發送 SIGWINCH 信號,然后舊的 master 進程則會向它的 worker 進程發送 SIGQUIT 信息,從而使得 worker 進程退出。向 master 進程發送 SIGWINCH 和 SIGQUIT 都會使得 worker 進程退出,但是前者不會使得 master 進程也退出。

最后,如果我們覺得舊的 master 進程使命完成,就可以向它發送 SIGQUIT 信號,讓其退出了。

worker 進程如何處理來自 master 的信號消息

實際上,master 進程再向 worker 進程通訊,不是使用 kill 函數,而是使用了通過管道實現的 nginx channel,master 進程向管道一端寫入信息(比如信號信息),worker 進程則從另外一端收取信息,nginx channel 事件,在 worker 進程剛剛起來的時候,就被加入事件調度器中(比如 epoll,kqueue),所以當有數據從 master 發來時,即可被事件調度器通知到。

nginx 這么設計是有理由的,作為一個優秀的反向代理服務器,nginx 追求的就是極致的高性能,而 signal handler 會中斷 worker 進程的運行,使得所有的事件都被暫停一個時間窗口,這對性能是有一定損失的。

很多人可能會認為當 master 進程向 worker 進程發送信息之后,worker 進程立刻會有對應操作回應,然而 worker 進程是非常繁忙的,它不斷地處理著網絡事件和定時器事件,當調用 nginx channel 事件的 handler 之后,nginx 僅僅只是處理了一些標志位。真正執行這些動作是在一輪事件調度完成之后。所以這之間存在一個時間窗口,尤其是業務復雜且流量巨大的時候,這個窗口就有可能被放大,這也就是為什么 NGINX 官方提供的日志切割方案里要求 sleep 1s 的原因。

當然,我們也可以繞過 master 進程,直接向 worker 進程發送信號,worker 可以處理的信號有

signal effect
SIGINT 強制退出
SIGTERM 強制退出
SIGQUIT 優雅退出
SIGUSR1 重新打開文件

總結

nginx 信號操作在日常運維中是最常見的,也是非常重要的,這個環節如果出現失誤則可能造成業務異常,帶來損失。所以理清楚 nginx 信號集是非常必要的,能幫助我們更好地處理這些工作。

另外,通過這次的經驗教訓和對 nginx 信號集的認知,我們認為以下幾點是比較重要的:

慎用 nginx -s stop,盡可能使用 nginx -s quit

熱更新之后,如果確定業務沒問題,盡可能讓舊的 master 進程退出

關鍵性的信號操作完成后,等待一段時間,避免時間窗口的影響

不要直接向 worker 進程發送信號

 

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
日韩欧美福利视频| 亚洲欧美另类自拍| 欧美性感美女h网站在线观看免费| 欧美日韩电影在线观看| 欧美激情网友自拍| 91麻豆国产精品| 国产一区视频在线播放| 国产91在线播放| 欧美壮男野外gaytube| 日韩av免费看| 欧洲亚洲免费视频| 成人免费在线视频网址| 国产精品视频资源| 欧美日韩中文字幕综合视频| 91精品国产91久久久久久吃药| 欧美另类精品xxxx孕妇| 日韩电影大全免费观看2023年上| 欧美电影免费观看大全| 国产玖玖精品视频| 亚洲国产精品成人va在线观看| 成人深夜直播免费观看| 日韩有码在线电影| 亚洲国产三级网| 国产日韩欧美夫妻视频在线观看| 欧美日韩国产二区| 色综合久久88色综合天天看泰| 国产性猛交xxxx免费看久久| 成人欧美一区二区三区在线湿哒哒| 欧美日韩美女在线| 欧美激情视频一区二区| zzijzzij亚洲日本成熟少妇| 欧美电影免费看| 成人免费观看49www在线观看| 亚洲人成77777在线观看网| 视频直播国产精品| 亚洲精品视频在线播放| 亚洲图片欧美午夜| 国产精品一区二区久久久| 久久久久国产精品免费网站| 国产成人精品视频| 亚洲色图激情小说| 亚洲国产精品va在看黑人| 日韩一区二区三区国产| 伊人一区二区三区久久精品| 欧美精品在线免费观看| 国产美女精品视频| 国产精品三级久久久久久电影| 国产99久久精品一区二区 夜夜躁日日躁| 庆余年2免费日韩剧观看大牛| 久久五月天色综合| 国产成人精品国内自产拍免费看| 日本久久精品视频| 国产日韩欧美在线| 亚洲r级在线观看| 国产精品日韩电影| 国产精品免费观看在线| 国产一区二区美女视频| 国产精品91免费在线| 亚洲综合最新在线| 在线精品91av| 国产精品十八以下禁看| 亚洲精品成a人在线观看| 中文字幕国产日韩| 一本一道久久a久久精品逆3p| 红桃av永久久久| 欧美日韩国产一中文字不卡| 国内精品久久影院| 国外成人在线直播| 国产一区红桃视频| 久久免费高清视频| 精品国产欧美成人夜夜嗨| 精品久久久久久亚洲精品| 97涩涩爰在线观看亚洲| 伊人久久久久久久久久| 日韩美女在线看| 在线看国产精品| 久久天天躁狠狠躁老女人| 国产成人综合av| 国产视频精品xxxx| 欧美国产一区二区三区| 久久夜色撩人精品| 亚洲3p在线观看| 国产热re99久久6国产精品| 992tv成人免费视频| 中文字幕一区日韩电影| 国产精品久久久久高潮| 亚洲第一区中文99精品| 亚洲美女自拍视频| 久久精品国产欧美亚洲人人爽| 中文字幕欧美在线| 自拍偷拍亚洲一区| 国产精品热视频| 国产精品96久久久久久| 亚洲精品国产综合久久| 自拍偷拍亚洲区| 亚洲黄色www| 98精品国产自产在线观看| 欧美国产日韩免费| 精品magnet| 日韩精品免费在线观看| 91精品国产自产在线观看永久| 欧美极品在线播放| 久久国产精品久久久久久久久久| 国产精品av网站| 国产日本欧美一区二区三区| 色综合老司机第九色激情| 亚洲激情自拍图| 欧美性猛交xxxx富婆| 欧美在线播放视频| 91在线看www| 奇米四色中文综合久久| 亚洲精品女av网站| 国产不卡精品视男人的天堂| 久久久影视精品| 精品久久久久久久久久久久久| 国产精品视频永久免费播放| 欧美黄色片在线观看| 国产成人在线视频| 久久久久这里只有精品| 中文字幕不卡在线视频极品| 亚洲精品电影网站| 国产精品私拍pans大尺度在线| 日韩男女性生活视频| 亚洲第一区第一页| 亚洲91精品在线观看| 欧美日韩一二三四五区| 国产精品久久久久福利| 国产成人精品一区二区三区| 51ⅴ精品国产91久久久久久| 久久久综合av| 欧美在线视频在线播放完整版免费观看| 亚洲va国产va天堂va久久| 精品五月天久久| 在线视频欧美日韩精品| 国产一区二中文字幕在线看| 亚洲美女www午夜| 国产精品视频男人的天堂| 成人国产亚洲精品a区天堂华泰| 久久夜精品va视频免费观看| 亚洲偷熟乱区亚洲香蕉av| 亚洲综合国产精品| 亚洲裸体xxxx| 国产视频久久久| 亚洲精品一区中文| 久久免费国产视频| 777午夜精品福利在线观看| 国产精品黄色影片导航在线观看| 欧美成人一二三| 亚洲黄色av女优在线观看| 亚洲一区二区自拍| 91久久国产综合久久91精品网站| 国产成人综合精品在线| 欧美成人激情在线| 久久精品国产一区二区电影| 久热精品视频在线免费观看| 97国产精品久久| 午夜精品一区二区三区在线视| 国产一区二区三区免费视频| 91国内揄拍国内精品对白| 日韩中文字幕不卡视频| 亚洲国产精品视频在线观看| 国产精品美女在线| 日韩欧美一区二区三区久久| 欧美激情一二区|