| Nginx學(xué)習(xí):核心模塊Core對于 Nginx 的學(xué)習(xí)來說,其實(shí)最基礎(chǔ)的就是學(xué)習(xí)配置文件中的各種不同配置項(xiàng)。如果想要深入的理解 Nginx ,那就要去研究它的源碼,但是就像之前說過的,C 的水平以及整體的計(jì)算機(jī)基礎(chǔ)知識的水平還不足以支撐我達(dá)到可以分析 Nginx 源碼的程度。 因此,咱們就是對各種配置的學(xué)習(xí)。 在 Nginx 中,各種功能其實(shí)是以各種模塊來提供的,比如最重要的包括核心模塊、事件模塊、HTTP模塊以及Email模塊,其中 HTTP 模塊又是重中之重。將來如果你學(xué)習(xí)或者使用到 OpenResty 的話,其實(shí)你也會發(fā)現(xiàn),它就是一個 Nginx 的超集,提供了更為豐富的模塊功能。 今天,就先來學(xué)習(xí) Nginx 核心模塊中的部分配置。一些可能比較常見的并且重要的配置,咱們實(shí)際動手配一下,看看效果。而另外一些可能不那么常見的,就簡單以我的理解來解釋下是干啥用的。畢竟整個 Nginx 中,配置項(xiàng)還是不少的,一個一個的調(diào)試,一個一個的詳細(xì)研究,可能真的是要花上不少時間的,咱們的主要目標(biāo)還是以應(yīng)用為主嘛。 核心模塊是可以在整個 conf 配置文件中全局配置的一些參數(shù),一般來說,可能會放到全局的 nginx.conf 文件最開頭的部分。當(dāng)然,放在其它配置文件中也沒啥問題,不過需要注意,不要放到別的子模塊中,還是要強(qiáng)調(diào),修改之后一定要  用戶用戶配置實(shí)際上就是 Nginx 的工作進(jìn)程(子進(jìn)程),是由哪個用戶來啟動的。這里又是牽涉到 Linux 的用戶及權(quán)限管理了。通常,主進(jìn)程可能會使用 root 或者某個指定的用戶來啟動,而子進(jìn)程,則會選擇大家非常常用的 www 用戶。沒錯,就算是使用 Apache ,大家也喜歡用這個用戶名的用戶來運(yùn)行。 同理,我們的應(yīng)用程序目錄盡量也是 www 用戶和用戶組的。這樣,對于系統(tǒng)的安全來說,就有了相當(dāng)高的保障。 可以指定用戶,也可以同時指定用戶組。我們先來看看當(dāng)前我的電腦上,是使用哪個用戶來運(yùn)行的。 我這里是 Mac 電腦,501 是你默認(rèn)登錄的那個用戶,使用 Linux 的話 ps 出來的內(nèi)容會直接顯示用戶,不過咱們也可以直接看下 501 是誰。 很明顯,這個用戶就是我登錄的這個用戶名。好了,接下來我們修改一下,在配置文件中將用戶設(shè)置為 www ,如果你的系統(tǒng)中沒有添加過這個用戶,就先添加一下。 好了,再次啟動,這時我們需要使用 root 來啟動,如果你還是像原來那樣使用 501 這個登錄用戶啟動的話,會報出警告信息。 大概的意思就是用戶這個配置啟用后,需要讓主進(jìn)程運(yùn)行在超級用戶的權(quán)限下,也就是 root 用戶。因此,我們需要 sudo 一下再啟動 nginx 。 這下看出來效果了吧,子進(jìn)程的運(yùn)行用戶是 70 ,正是當(dāng)前系統(tǒng)中的 www 用戶。如果你是使用的某些面板或者一鍵安裝工具,那可以直接去看一下,一般它們也都是這樣運(yùn)行的,子進(jìn)程全部放在 www 用戶下去運(yùn)行。 工作進(jìn)程不知道大家有沒有了解過,Nginx 是多線程還是多進(jìn)程的?其實(shí)它是多進(jìn)程的,默認(rèn)并沒有什么多線程?,F(xiàn)在,先來看一下怎么配置進(jìn)程相關(guān)的內(nèi)容。 之前在測試中,我們就已經(jīng)看到啟動起來的 Nginx 有一個主進(jìn)程,一個子進(jìn)程。這個子進(jìn)程就是一個工作進(jìn)程。而主進(jìn)程負(fù)責(zé)管理所有的子進(jìn)程,就像我們在 Swoole 中學(xué)習(xí)過的那個進(jìn)程工作模式。 對于進(jìn)程數(shù)量,建議配置是和 CPU 的核數(shù)相當(dāng),或者稍微少一點(diǎn),可以通過下面這個選項(xiàng)來配置。 可以寫具體的數(shù)量,也可以選擇 auto 。當(dāng)你的服務(wù)器上還有其它的應(yīng)用時,可以比核數(shù)少一兩個,也就是讓出一兩個 CPU 給其它程序使用。 現(xiàn)在咱們把它配置成 2 ,然后再重啟一下 Nginx 看看效果。 是不是出現(xiàn)兩個工作進(jìn)程了,這個配置就是這么簡單。當(dāng)然你也可以配置成 auto 試試效果。 worker_cpu_affinity上面這個配置是用于綁定 CPU 的,是的,你沒看錯,就是我們指定了幾個工作進(jìn)程,就可以把這些進(jìn)程綁定到指定的 CPU 上。不過,CPU 的信息需要用二進(jìn)制來寫,比如第一個 CPU 就寫 0001 ,第二個 CPU 就寫 0010 這樣。 像這樣寫,就是綁定到第三和第四個 CPU 上。不過我本機(jī)的電腦不支持,需要 FreeBSD 或者原生 Linux 系統(tǒng),大家可以用 Linux 環(huán)境嘗試一下。怎么測試效果呢?其實(shí)它是為了解決多個進(jìn)程一直使用一個 CPU 核的問題,也就是均勻分?jǐn)?CPU 給不同的工作進(jìn)程,需要使用壓力測試工具進(jìn)行測試,然后 top 查看 CPU 各個核的負(fù)載情況,如果比較平均,就是產(chǎn)生效果了。 這樣綁定 CPU 有什么好處呢?一是減少 CPU 切換帶來的損耗,二是能夠充分利用 CPU 自身的多級緩存,提高緩存命中率。 好吧,還是搭個虛擬機(jī)吧,后面的示例我們轉(zhuǎn)到虛擬機(jī)上去學(xué)習(xí),版本是 1.23.0 。 worker_priority這個配置用于定義工作進(jìn)行的優(yōu)先級,和 Linux 中 nice 的效果是一樣的。 number 參數(shù)的取值范圍是 -20 到 20 ,越小優(yōu)先級越高。比如我們設(shè)置成 -10 ,然后通過 top 命令查看。 看到 NI 這一列變成 -10 了吧。至于 Linux 中,進(jìn)程優(yōu)先級具體的作用,大家可以自行查閱下相關(guān)的資料。 進(jìn)程其它配置進(jìn)程相關(guān)的配置項(xiàng)中,還有幾個配置項(xiàng),不過平常我們不太會去配置它們,一起了解一下吧。 首先是如果進(jìn)程出現(xiàn)問題了,就會記錄一個 core 文件, 
 最后這個其實(shí)從名字就可以看出來了,它是在 shutdown 之后超時的時間。什么意思呢?比如說我們  調(diào)試在 Nginx 的核心模塊中,提供了調(diào)試相關(guān)的配置,僅有三個,其中一個還和進(jìn)程有關(guān)。 第一個是后臺運(yùn)行,默認(rèn)它就是開啟的,我們可以把它設(shè)置成 off ,這樣如果命令行運(yùn)行 Nginx 的話,就會一直掛在那里,而且不像 Redis 之類的有輸出,所以這個平常我們也是用不到的啦。 
 最后一個和進(jìn)程有關(guān),關(guān)閉后它會讓 Nginx 程序不 fork 子進(jìn)程,只使用一個進(jìn)程運(yùn)行。 我們先來看看,當(dāng)前我們有三個進(jìn)程,一個主進(jìn)程和兩個工作進(jìn)程。 然后將  現(xiàn)在就只有一個進(jìn)程在運(yùn)行了。很明顯,線上也是不能這么玩的,這三個配置如果沒有特殊需求,還是別踫它們比較好。這個配置不能通過 reload 重載,需要完全關(guān)閉再重啟。 錯誤日志在核心模塊的日志中,其實(shí)只有一個  它的配置非常簡單,給個記錄文件的路徑和文件名,然后就是記錄的日志等級。等級包括 debug, info, notice, warn, error, crit, alert, emerg 這些,從低到高記錄的信息越來越少,問題也越來越嚴(yán)重,具體就不解釋了,相信大家都明白。默認(rèn)情況下是 error 這個級別,另外,如果使用 debug 的話,需要 Nginx 在編譯安裝的時候也要加上  另外在編譯時,我們還可以直接指定一個全局的錯誤日志,這樣你就會看到在默認(rèn)的配置文件中,很多情況下都只有三個注釋掉的 error_log 配置。這是因?yàn)樵诰幾g的時候也可以指定一個默認(rèn)的錯誤日志。 然后我們可以再試試修改它的記錄級別,并且新增加一個記錄的日志。 新增加的這個日志名稱為 error_debug.log ,目錄就是當(dāng)前運(yùn)行程序的目錄下面的 logs 目錄。這個位置就是我們安裝后的 Nginx 的運(yùn)行目錄,如果是 Linux ,大部分會安裝到 /usr/local/nginx 下,如果是 Mac 使用 brew 的話,一般會在 /usr/local/Cellar/nginx/版本號/ 這個目錄下面。其實(shí)它就是  另外要注意的是,使用 debug 這個日志級別,需要 Nginx 在編譯安裝時要有 --with-debug 這個參數(shù)。 前面說過,這個配置可以全局配置,也可以在 http、server、location 下面單獨(dú)配置,還可以在后面我們學(xué)習(xí)的 mail 和 stream 中配置。一般來說,全局會有一個總的錯誤日志記錄文件,同時,大部分情況下也都會在 server 下面根據(jù)不同的虛擬站點(diǎn)配置不同的錯誤日志文件。畢竟所有站點(diǎn)的錯誤信息都記錄在一個文件中還是比較混亂的。至于 location 下面,如果有特殊需求,也可以考慮單獨(dú)建立一個日志文件。 文件加載文件加載就是加載外部的配置文件,在默認(rèn)的配置文件中其實(shí)就有很多地方用到了。 在默認(rèn)的配置文件中,你可能會看到這些。 第一個一般都是有的,它是加載一些 MIME 類型信息的,具體的這個 mime.types 文件里面寫得是啥,大家自己去看一下就知道了,后面我們也會學(xué)習(xí)到。第二個一般是在 server 中,也就是服務(wù)器相關(guān)的配置中,用來指定一些 FastCGI 相關(guān)配置的。第三個則是加載一些獨(dú)立配置文件,也就是我們通常會將虛擬主機(jī)分開成不同的配置文件進(jìn)行保存,這里就是指定加載整個目錄中的全部配置文件了。如果你是完全自己重新安裝的 Nginx ,在默認(rèn)的配置文件中沒有看到后面兩個也沒關(guān)系,它們確實(shí)是經(jīng)常見到并且非常有用的。另外,通過  接下來我們就簡單地試試,還是拿上面的錯誤日志來測試,先建立一個 err.conf 文件,里面就是 error_log 去記錄一個新的日志文件。 接著,在主配置文件中,include 進(jìn)來。 然后  除了加載文件之外,還有一個加載外部模塊文件的配置項(xiàng)。 這個是用于加載外部一些 Nginx 模塊的,將來用到的時候再說吧,它和 include 其實(shí)也是類似的,但是它加載的不是純文件的配置信息,而是指定的模塊,就像我們?yōu)?PHP 安裝擴(kuò)展后也要在 php.ini 中添加  其它好了,接下來就是一些其它相關(guān)的配置參數(shù)了。我們簡單的學(xué)習(xí)一下就好。 lock_file這個配置主要是用來指定互斥鎖文件,如果是在 i386, amd64, sparc64, and ppc64 這些 CPU 架構(gòu)下使用 gcc, Intel C++, 或 SunPro C++ 編譯構(gòu)建的 Nginx ,會使用原子指令來實(shí)現(xiàn)互斥鎖,否則的話,就需要配置這個參數(shù),通過一個文件來實(shí)現(xiàn)互斥鎖的功能。(了解一下就好,至少你得明白互斥鎖是干嘛的) pcre_jit這個配置項(xiàng)的名字有點(diǎn)意思啊,它是 正則 + JIT ,合起來就是對于正則表達(dá)式的即時編譯支持,如果開啟的話,可以提升正則表達(dá)式的處理速度。從 Nginx 1.1.12 之后的版本開始支持,需要在編譯安裝 Nginx 的時候加上 --with-pcre-jit 參數(shù)。 pid不多解釋了,指定進(jìn)程通信文件 pid 文件的存放位置。也可以在編譯時通過 --pid-path 直接指定,同樣是通過  ssl_engine用于指定 OpenSSL 使用的引擎。 一般也不需要配置,它會找當(dāng)前操作系統(tǒng)中安裝的 OpenSSL 所使用的引擎。 thread_pool指定線程池的名稱、數(shù)量和最大等待隊(duì)列數(shù)量。用于多線程讀取和發(fā)送文件,而不阻塞工作進(jìn)程。 默認(rèn)的配置是: 從 Nginx 1.7.11 后開始支持配置的,暫時來看是使用多線程來進(jìn)行 IO 處理的,具體作用將來如果學(xué)習(xí)到相關(guān)的內(nèi)容了再深入的學(xué)習(xí)。 timer_resolution每次內(nèi)核事件調(diào)用返回時,都會使用 gettimeday() 來更新 Nginx 緩存時鐘;timer_resolution 用于定義每隔多久才會由 gettimeday() 更新一次緩存時鐘;在 x86-64 系統(tǒng)上,gettimeday() 代價已經(jīng)很小,可以忽略此配置。 嗯,意思就是平常可以不用配置這個選項(xiàng)。說實(shí)話,平常還真沒見過。 env默認(rèn)情況下,Nginx 會刪除從其父進(jìn)程繼承的所有環(huán)境變量,但 TZ 變量除外。使用這個配置指令可以允許保留一些繼承變量、更改其值或創(chuàng)建新的環(huán)境變量。 它的使用有一些限制,文檔中具體的內(nèi)容也沒看太懂,網(wǎng)上找的資料也不多,所以咱們也別瞎配了。它可能不是你想像的那樣可以配置通用的全局環(huán)境變量的哦。 如果有用過的小伙伴,可以留言或者提供一些學(xué)習(xí)資料哈! 配置文件單位在配置文件中,有許多單位信息需要我們提前了解一下。 第一個就是容量單位,容量可以用千字節(jié)(k,K)和兆字節(jié)(m,M)來描述,比如“8k”,“1m”。 如果沒有指定單位,容量以字節(jié)為單位。和 Redis 配置文件中的基本一樣。 另一個就是時間單位。 
 具體到配置項(xiàng)上,就比如之后我們要學(xué)的 client_body_timeout ,它的默認(rèn)值就是 60s ,代表 60 秒。另外還有 client_body_buffer_size ,它的默認(rèn)值就是 8k 或 16k ,代表的就上面千字節(jié)。 作用域在 Nginx 的配置文件中,有很多配置指令是可以配置在多個模塊級別中的。比如說最常見的 root 配置,它可以放在 http,server,location 這些模塊區(qū)域中。和編程語言類似,它是根據(jù)模塊級別來確定優(yōu)先級的。比如說我們在 http 上配置了 root ,server 和 location 中沒有配置的話,那么就會走全局的這個 http 下面的 root ,而如果同時在 server 中配置了,那么如果訪問當(dāng)前這個 server ,就會走這個 server 模塊中配置的那個 root 。 也就是說,根據(jù)模塊層級,最底層的模塊的優(yōu)先級最高,如果下層沒有配置,就會走上層的配置。這個在后面的所有文章中都是通用的,所以在核心模塊這里先提一嘴。 總結(jié)今天學(xué)習(xí)的內(nèi)容主要是用戶權(quán)限、進(jìn)程以及錯誤日志配置相關(guān)的一些核心配置方面的內(nèi)容。這部分的內(nèi)容不復(fù)雜,但是有一些配置項(xiàng)確實(shí)資料很少,或許也只是在一些特殊情況下才會用到,所以大部分人都沒怎么接觸過。后面的許多配置其實(shí)也有類似的情況,因此,咱們的學(xué)習(xí)也主要就是學(xué)習(xí)常用的那些配置,而不常見的就盡已所能的根據(jù)文檔翻譯一下。 核心模塊其實(shí)還有一部分,就是事件模塊,這個我們單獨(dú)再開一篇文章進(jìn)行學(xué)習(xí),下回見。 參考文檔: http:///en/docs/ngx_core_module.html | 
|  |