探究Nginx中reload流程的原理真相
今天這篇文章主要來(lái)介紹下 Nginx 的 reload 流程。實(shí)際上在之前文章中,在更改了 nginx 配置文件時(shí),我們都會(huì)執(zhí)行 nginx -s reload 命令,我們執(zhí)行這條命令的原因是希望 nginx 不停止服務(wù)始終在處理新的請(qǐng)求的同時(shí)把 nginx 的配置文件平滑的把舊的 nginx.conf 配置更新為新的 nginx.conf 配置。
這樣一個(gè)功能對(duì)于 nginx 非常有必要,但是有時(shí)候我們會(huì)發(fā)現(xiàn)在執(zhí)行 nginx -s reload 命令后,worker 子進(jìn)程的數(shù)量會(huì)變多了,這是因?yàn)槔系呐渲眠\(yùn)行的 worker 進(jìn)程長(zhǎng)時(shí)間沒(méi)有退出,當(dāng)使用 stream 做四層反向代理的時(shí)候,可能這種場(chǎng)景會(huì)更多。
那么下面我們通過(guò)分析 nginx 的 reload 流程,來(lái)探究下 nginx 到底做了些什么?所謂優(yōu)雅的退出和立即退出有什么區(qū)別?
reload 流程

第一步在修改好 nginx 的配置文件 nginx.conf 后,向 master 進(jìn)程發(fā)送 HUP 信號(hào),這實(shí)際上和我們?cè)诿钚袌?zhí)行 nginx -s reload 命令效果是一樣的。
那么 master 進(jìn)程在收到 HUP 信號(hào)以后,會(huì)在第二步檢查我們的配置文件語(yǔ)法是否正確,也就是說(shuō)我們并不一定非要在 nginx -s reload 前執(zhí)行 nginx -t 檢驗(yàn)下語(yǔ)法是否正確,因?yàn)樵诘诙?nginx 的 master 進(jìn)程一定會(huì)執(zhí)行這個(gè)步驟。
在 nginx 的配置語(yǔ)法全部正確以后,master 進(jìn)程會(huì)打開新的監(jiān)聽端口,為什么要在 master 進(jìn)程中打開新的監(jiān)聽端口?因?yàn)槲覀兛赡茉?nginx.conf 中會(huì)引入新的例如 443 或者之前我們沒(méi)有打開的的監(jiān)聽端口,而所有 worker 進(jìn)程是 master 進(jìn)程 的子進(jìn)程,子進(jìn)程會(huì)繼承父進(jìn)程所有已經(jīng)打開的端口,這是 linux 操作系統(tǒng)定義的,所以第三步,我們 master 進(jìn)程打開了可能引入的新的監(jiān)聽端口。
接下來(lái) mster 進(jìn)程會(huì)用新的 nginx.conf 配置文件來(lái)啟動(dòng)新的 worker 子進(jìn)程,那么老的 worker 子進(jìn)程會(huì)怎么樣呢?
我們會(huì)在第五步在啟動(dòng)新的 worker 子進(jìn)程以后,由 master 進(jìn)程再向老 worker 子進(jìn)程發(fā)送 QUIT 信號(hào),QUIT 信號(hào)和 TERM,INT 信號(hào)是不一樣的,QUIT 信號(hào)是請(qǐng)優(yōu)雅地關(guān)閉子進(jìn)程,這時(shí)候需要關(guān)注順序,因?yàn)?nginx 需要保證平滑,所以要先啟動(dòng)新的 worker 子進(jìn)程,再向老的 worker 子進(jìn)程發(fā)送 QUIT 信號(hào)。
那么老的 master 子進(jìn)程收到 QUIT 信號(hào)后,首先關(guān)閉監(jiān)聽句柄,也就是說(shuō)這個(gè)時(shí)候新的連接只會(huì)到新的 worker 子進(jìn)程,所以雖然他們之間有時(shí)間差,但是時(shí)間是非??焖俚模敲搓P(guān)閉監(jiān)聽句柄后,處理完當(dāng)前連接后就結(jié)束進(jìn)程。
下面看 reload 不停機(jī)載入新配置的圖示。
reload 不停機(jī)載入新配置

master 進(jìn)程上原先有四個(gè)綠色的 worker 子進(jìn)程,它們使用了老的配置,當(dāng)我們更改了 nginx.conf 配置文件后,向 master 發(fā)送 SIGHUP 信號(hào)或者執(zhí)行 reload 命令, 然后 master 會(huì)用新的配置文件啟動(dòng)四個(gè)新的黃色 worker 子進(jìn)程,此時(shí)是四個(gè)老的綠色 worker 子進(jìn)程和四個(gè)新的黃色的 worker 子進(jìn)程是并存的。那么老的 worker 子進(jìn)程在正常的情況下會(huì)在處理已經(jīng)建立好的連接上的請(qǐng)求之后關(guān)閉這個(gè)連接,哪怕這個(gè)連接是 keeplive 請(qǐng)求也會(huì)正常關(guān)閉。
但是異常情況,如果有一些請(qǐng)求出現(xiàn)問(wèn)題,客戶端長(zhǎng)時(shí)間無(wú)法處理,那么就會(huì)導(dǎo)致這個(gè)請(qǐng)求長(zhǎng)時(shí)間停留在這個(gè) worker 子進(jìn)程當(dāng)中,那么這個(gè) worker 子進(jìn)程會(huì)長(zhǎng)時(shí)間存在,因?yàn)樾碌倪B接已經(jīng)跑在黃色的 worker 子進(jìn)程中,所以影響并不會(huì)很大,唯一會(huì)影響的就是綠色的 worker 子進(jìn)程會(huì)長(zhǎng)時(shí)間存在,但也只影響已存在的連接,不會(huì)影響新的連接。
我們有什么辦法處理呢?在新版本中提供了一個(gè)新的配置 worker_shutdown_timeout,也就是說(shuō)最長(zhǎng)等待多長(zhǎng)時(shí)間,這樣 master 進(jìn)程啟動(dòng)新的黃色 worker 進(jìn)程之后,如果老的 worker 進(jìn)程一直沒(méi)有退出,時(shí)間到了之后會(huì)強(qiáng)制把老的 worker 進(jìn)程退出掉。
總結(jié)
本文主要講解了 Nginx 平滑升級(jí)新的配置文件的流程,在我們了解了優(yōu)雅關(guān)閉 worker 子進(jìn)程和啟動(dòng)新配置的 worker 子進(jìn)程流程間的關(guān)系后,我們可以更好地處理罕見的異常場(chǎng)景。
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Nginx中default_server指令問(wèn)題詳解
nginx 的 default_server 指令可以定義默認(rèn)的 server 出處理一些沒(méi)有成功匹配 server_name 的請(qǐng)求,下面這篇文章主要給大家介紹了關(guān)于Nginx中default_server指令問(wèn)題的相關(guān)資料,需要的朋友可以參考下2022-12-12
使用nginx正向代理實(shí)現(xiàn)訪問(wèn)外網(wǎng)
這篇文章主要介紹了使用nginx正向代理實(shí)現(xiàn)讓內(nèi)網(wǎng)主機(jī)通過(guò)外網(wǎng)主機(jī)訪問(wèn)外網(wǎng),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-12-12
如何利用map實(shí)現(xiàn)Nginx允許多個(gè)域名跨域
這篇文章主要給大家介紹了關(guān)于如何利用map實(shí)現(xiàn)Nginx允許多個(gè)域名跨域的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10
Nginx學(xué)習(xí)筆記之事件驅(qū)動(dòng)框架處理流程
Nginx對(duì)請(qǐng)求的處理是通過(guò)事件觸發(fā)的,模塊作為事件消費(fèi)者,只能被事件收集、分發(fā)器調(diào)用。在Nginx中,接收到一個(gè)請(qǐng)求時(shí),不會(huì)產(chǎn)生一個(gè)單獨(dú)的進(jìn)程來(lái)處理該請(qǐng)求,而是由事件收集、分發(fā)器(進(jìn)程)調(diào)用某個(gè)模塊,由模塊處理請(qǐng)求,處理完后再返回到事件收集、分發(fā)器2014-07-07
Nginx Lua 根據(jù)參數(shù)請(qǐng)求轉(zhuǎn)發(fā)的實(shí)現(xiàn)
本文介紹了如何使用Nginx和Lua腳本實(shí)現(xiàn)基于參數(shù)的請(qǐng)求轉(zhuǎn)發(fā),文章詳細(xì)說(shuō)明了配置方法,并提供了示例代碼,幫助讀者理解如何通過(guò)NginxLua模塊根據(jù)請(qǐng)求參數(shù)將流量轉(zhuǎn)發(fā)到不同后端服務(wù),這種方法有助于實(shí)現(xiàn)靈活的負(fù)載均衡和動(dòng)態(tài)內(nèi)容處理2022-05-05

