第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

首頁 慕課教程 Nginx 入門教程 Nginx 入門教程 20 Nginx 的基礎(chǔ)架構(gòu)解析(上)

Nginx 的基礎(chǔ)架構(gòu)解析(上)

1. Nginx 的進(jìn)程模型

前面介紹 Nginx 時(shí)有介紹過 Nginx 的進(jìn)程模型。Nginx 啟動(dòng)時(shí)首先啟動(dòng)一個(gè) Master 進(jìn)程,然后由 Master 進(jìn)程啟動(dòng)一個(gè)或者多個(gè) Worker 子進(jìn)程。Master 進(jìn)程主要完成配置讀取,通過發(fā)送信號(hào)控制 Worker 進(jìn)程的啟動(dòng)和停止等,而 Worker 子進(jìn)程是用來處理客戶端發(fā)來的 Http 請(qǐng)求,且Worker進(jìn)程之間會(huì)通過共享內(nèi)存進(jìn)行通信。

1.1 worker 進(jìn)程處理請(qǐng)求過程

假設(shè) Nginx 啟動(dòng)了多個(gè) Worker 進(jìn)程,并且在 Master 進(jìn)程中通過 socket 套接字監(jiān)聽80端口。
這些 Worker 進(jìn)程 fork 自 Master 進(jìn)程,然后每個(gè)worker進(jìn)程都可以去 accept 這個(gè)監(jiān)聽的 socket。 當(dāng)一個(gè)連接進(jìn)來后,所有在 accept 在這個(gè) socket 上面的進(jìn)程,都會(huì)收到消息,但是只有一個(gè)進(jìn)程可以 accept 這個(gè)連接,其它的則 accept 失敗,這便是所謂的驚群現(xiàn)象。Nginx 處理這種情況的方式就是加鎖。有了鎖之后,在同一時(shí)刻,就只會(huì)有一個(gè) Worker 進(jìn)程在 accpet 連接,這樣就不會(huì)有驚群問題了。在 Worker 進(jìn)程拿到 Http 請(qǐng)求后,就開始按照前面介紹的 11個(gè)階段處理該 Http 請(qǐng)求,最后返回響應(yīng)結(jié)果并斷開連接。

1.2 Nginx 命令行的處理流程

最早我們學(xué)習(xí)了 Nginx 命令行操作,這些命令行操作都是給 Master 進(jìn)程發(fā)信號(hào),然后再由 Master 進(jìn)程發(fā)送信號(hào)給 Worker 進(jìn)程,從而達(dá)到控制 Worker 進(jìn)程的目標(biāo)。我們以 Nginx 的熱部署命令./nginx -s reload 來描述 Nginx 命令行的執(zhí)行流程。具體過程如下:

  • 首先 Master 進(jìn)程會(huì)檢查 nginx.conf 文件是否存在語法錯(cuò)誤,并從中找到 nginx.pid 配置路徑(沒有配置會(huì)使用默認(rèn)值)

  • reload 參數(shù)表示向 Master 進(jìn)程發(fā)送 HUP 信號(hào)。Nginx 會(huì)根據(jù)會(huì)保存在 nginx.pid 文件中的值找到 Master 進(jìn)程的 pid。如果 Nginx 進(jìn)程沒有啟動(dòng),則沒有該 nginx.pid 文件,命令行會(huì)報(bào)錯(cuò);

# 在 Nginx 的配置文件中配置 nginx.pid 的保存路徑
[root@server sbin]# ./nginx -s reload
nginx: [error] open() "/root/nginx/logs/nginx.pid" failed (2: No such file or directory)
  • Master 進(jìn)程打開新的監(jiān)聽端口;

  • Master 進(jìn)程用新配置啟動(dòng)新的 Worker 進(jìn)程。新的 Worker 進(jìn)程起來后,開始接收 Http 請(qǐng)求并處理,此時(shí)老的 Worker進(jìn)程會(huì)停止接受 Http 請(qǐng)求;

  • Master 進(jìn)程會(huì)向老的 Worker進(jìn)程發(fā)送 QUIT 信號(hào);

  • 老的 Worker 進(jìn)程關(guān)閉監(jiān)聽句柄,處理完正在進(jìn)行的請(qǐng)求后結(jié)束進(jìn)程。

Nginx 命令行中 -s 參數(shù)的每個(gè)值都對(duì)應(yīng)這一個(gè)信號(hào)。因此,我們也可以直接對(duì) Master 進(jìn)程發(fā)生相應(yīng)信號(hào)達(dá)到同樣的目的。

# pid表示Nginx的主進(jìn)程id號(hào)
# kill -s 信號(hào) pid

2. Nginx的事件驅(qū)動(dòng)模型

2.1 事件驅(qū)動(dòng)模型

事件驅(qū)動(dòng)模型是實(shí)現(xiàn)異步非阻塞的一個(gè)手段。對(duì)于 web 服務(wù)器來說,客戶端 A 的請(qǐng)求連接到服務(wù)端時(shí),服務(wù)端的某個(gè)進(jìn)程(Nginx 的 worker 進(jìn)程)會(huì)處理該請(qǐng)求,此進(jìn)程在沒有返回給客戶端 A 結(jié)果時(shí),它又去處理了客戶端 B 的請(qǐng)求。服務(wù)端把客戶端 A 以及客戶端 B 發(fā)來的請(qǐng)求作為事件交給了"事件收集器",而"事件收集器"再把收集到的事件交由"事件發(fā)送器"發(fā)送給"事件處理器"進(jìn)行處理。最后"事件處理器"處理完該事件后,通知服務(wù)端進(jìn)程,服務(wù)端進(jìn)程再把結(jié)果返回給客戶端A、客戶端B。在這個(gè)過程中,服務(wù)端進(jìn)程做的事情屬于用戶級(jí)別的,而事件處理這部分工作屬于內(nèi)核級(jí)別的。也就是說這個(gè)事件驅(qū)動(dòng)模型是需要操作系統(tǒng)內(nèi)核來作為支撐的。

2.2 Nginx的事件驅(qū)動(dòng)模型介紹

Nginx 的事件驅(qū)動(dòng)模型,支持 select、poll、epoll、rtsig、kqueue、/dev/poll、eventport 等。
最常用的是前三種,特別是 epoll 模型,這也是 Nginx 中的默認(rèn)配置。可以說 epoll 模型成就了 Nginx 的高性能和高并發(fā)特性。

  • select模型:
    • 創(chuàng)建所關(guān)注事件的描述符集合,對(duì)于一個(gè)描述符,可以關(guān)注其上面的讀(Read)事件、寫(Write)事件以及異常發(fā)生(Exception)事件。
      在select模型中,要?jiǎng)?chuàng)建這3類事件描述符集合。
    • 調(diào)用底層提供的select()函數(shù),等待事件發(fā)生。
    • 輪詢所有事件描述符集合中的每一個(gè)事件描述符,檢查是否有相應(yīng)的事件發(fā)生,如果有就進(jìn)行處理。
  • poll模型:
    • poll模型是Linux平臺(tái)上的事件驅(qū)動(dòng)模型,在Linux2.1.23中引入的,Windows平臺(tái)不支持該模型。
    • poll模型和select模型工作方式基本相同,區(qū)別在于,select模型創(chuàng)建了3個(gè)描述符集合,而poll模型只創(chuàng)建一個(gè)描述符集合。
  • epoll模型:
    • epoll模型屬于poll模型的變種,在Linux2.5.44中引入。epoll比poll更加高效,原因在于它不需要輪詢整個(gè)描述符集合,而是Linux內(nèi)核會(huì)關(guān)注事件集合,當(dāng)有變動(dòng)時(shí),內(nèi)核會(huì)發(fā)來通知。
    • 正式這種異步,非阻塞、IO多路復(fù)用的事件驅(qū)動(dòng)模型,才使得 Nginx 有很高的運(yùn)行效率。

3. 案例

3.1 Nginx 進(jìn)程模型實(shí)驗(yàn)

按照前面的講解,我們測試給 Nginx 的 Master 進(jìn)程直接發(fā)送信號(hào),并觀察進(jìn)程情況:

# 確認(rèn)沒有 Nginx 進(jìn)程
[root@server sbin]# ps -ef | grep nginx
root     10603 10137  0 14:23 pts/2    00:00:00 grep --color=auto nginx
# 啟動(dòng) Nginx 
[root@server sbin]# ./nginx
# 可以看到 Nginx 啟動(dòng)的進(jìn)程
[root@server sbin]# ps -ef | grep nginx
root     10640     1  0 14:23 ?        00:00:00 nginx: master process ./nginx
root     10642 10640  0 14:23 ?        00:00:00 nginx: worker process
root     10643 10640  0 14:23 ?        00:00:00 nginx: worker process
root     10644 10640  0 14:23 ?        00:00:00 nginx: cache manager process
root     10645 10640  0 14:23 ?        00:00:00 nginx: cache loader process

可以看到 Nginx 啟動(dòng)了 Master 進(jìn)程(pid=10640),后由 Master 進(jìn)程 fork 除了兩個(gè) Worker 進(jìn)程和兩個(gè) Cache 進(jìn)程,他們的父進(jìn)程 id 均為10640。現(xiàn)在做如下幾個(gè)操作:

  • 關(guān)閉進(jìn)程號(hào)等于10642的 Worker 進(jìn)程
[root@server sbin]# sudo kill -SIGTERM 10642
[root@server sbin]# ps -ef | grep nginx
root     10640     1  0 14:23 ?        00:00:00 nginx: master process ./nginx
root     10643 10640  0 14:23 ?        00:00:00 nginx: worker process
root     10644 10640  0 14:23 ?        00:00:00 nginx: cache manager process
root     10869 10640  0 14:32 ?        00:00:00 nginx: worker process
root     10939 10137  0 14:32 pts/2    00:00:00 grep --color=auto nginx

可以看到原先的 Worker 進(jìn)程被殺死后,Nginx 的主進(jìn)程又立馬拉起來一個(gè)新的 Worker 進(jìn)程提供服務(wù)。這說明 Nginx 是非??煽康模灰?Master 進(jìn)程還在就會(huì)保證 Worker 進(jìn)程持續(xù)存在并提供服務(wù)。

  • 向主進(jìn)程發(fā)送 SIGHUP 信號(hào),等價(jià)于 -s reload 操作??梢钥吹匠?Master 進(jìn)程外,所有其他進(jìn)程已經(jīng)是新啟動(dòng)的進(jìn)程了。
[root@server sbin]# sudo kill -SIGHUP 10640
[root@server sbin]# ps -ef | grep nginx
root     10640     1  0 14:23 ?        00:00:00 nginx: master process ./nginx
root     11059 10640  0 14:37 ?        00:00:00 nginx: worker process
root     11060 10640  0 14:37 ?        00:00:00 nginx: worker process
root     11061 10640  0 14:37 ?        00:00:00 nginx: cache manager process
root     11098 10137  0 14:37 pts/2    00:00:00 grep --color=auto nginx
  • 向主進(jìn)程發(fā)生 SIGTERM 信號(hào),等價(jià)于 -s stop 操作,即停止 Nginx 服務(wù),關(guān)閉所有進(jìn)程
[root@server sbin]# sudo kill -SIGTERM 10640
[root@server sbin]# ps -ef | grep nginx
root     11267 10137  0 14:43 pts/2    00:00:00 grep --color=auto nginx
  • 向主進(jìn)程發(fā)生 USR1 信號(hào),等價(jià)于 -s repoen 操作,即重新打開日志文件
[root@server sbin]# ./nginx

[root@server sbin]# ps -ef | grep nginx
root     11408     1  0 14:48 ?        00:00:00 nginx: master process ./nginx
root     11410 11408  0 14:48 ?        00:00:00 nginx: worker process
root     11411 11408  0 14:48 ?        00:00:00 nginx: worker process
root     11412 11408  0 14:48 ?        00:00:00 nginx: cache manager process
root     11413 11408  0 14:48 ?        00:00:00 nginx: cache loader process
root     11484 10137  0 14:49 pts/2    00:00:00 grep --color=auto nginx

[root@server sbin]# ll ../logs/access.log 
-rw-r--r-- 1 root root 384349 Feb 11 14:26 ../logs/access.log

[root@server sbin]# rm -rf ../logs/access.log 

[root@server sbin]# ll ../logs/access.log 
ls: cannot access ../logs/access.log: No such file or directory

[root@server sbin]# kill -USR1 11408
[root@server sbin]# ll ../logs/access.log 
-rw-r--r-- 1 root root 0 Feb 11 14:50 ../logs/access.log

可以看到,在移除 Nginx 的 access.log 日志后,在向 Nginx 主進(jìn)程發(fā)送 USR1 信號(hào),Nginx 會(huì)重新生成一個(gè)新的 access.log 日志。

4. 小結(jié)

本節(jié)主要介紹 Nginx 的進(jìn)程模型以及介紹了 Master 和 Worker 之間的通信過程。此外,我們介紹了 Nginx 的事件驅(qū)動(dòng)模型。異步、多路IO復(fù)用、非阻塞等特點(diǎn)早就了 Nginx 的高性能。接下來,我們完成了 Nginx 進(jìn)程模型的幾個(gè)實(shí)驗(yàn),直觀體檢 Nginx 的進(jìn)程模型。下一節(jié)將重點(diǎn)介紹 Nginx 模塊相關(guān)的內(nèi)容,并手動(dòng)實(shí)現(xiàn)一個(gè)簡單的 http 模塊。