本篇的上篇 Nginx 源碼分析:從模塊到配置(上),建議閱讀本篇前先閱讀上篇。html
Nginx
的架構高度模塊化。每一個模塊各司其職,組合在一塊兒完成特定的功能。nginx
Nginx
經過configure
決定哪些模塊被安裝。全部安裝的模塊在編譯階段靜態生成,其指針被統一放入ngx_modules
數組中,供全局使用。segmentfault
每一個模塊由如下幾部分構成:數組
ngx_module_t
結構體:表明模塊自己,其指針被放入ngx_modules
數組中。ngx_<module name>_conf_t
結構體:用來表示模塊的配置內容,其中部分紅員能夠經過配置文件進行配置。ngx_<module name>_module_t
結構體:模塊上下文,保存了一組操做,Nginx
初始化階段調用這些操做,初始化ngx_<module name>_conf_t
中的成員。ngx_command_t
結構體數組:該數組中每一項ngx_command_t
對應配置文件中一條指令。Nginx
的模塊雖然有不少。可是基本類型只有5種:CORF、CONF、EVNT、HTTP、MAIL
架構
#define NGX_CORE_MODULE 0x45524F43 /* "CORE" */ #define NGX_CONF_MODULE 0x464E4F43 /* "CONF" */ #define NGX_EVENT_MODULE 0x544E5645 /* "EVNT" */ #define NGX_HTTP_MODULE 0x50545448 /* "HTTP" */ #define NGX_MAIL_MODULE 0x4C49414D /* "MAIL" */
每種類型對應一種ngx_<module name>_module_t
上下文結構體。Nginx
在初始化(主要在ngx_init_cycle
函數中)時根據不一樣的模塊類型,調用不一樣的上下文中的操做,完成其配置內容的初始化。模塊化
雖然模塊類型只有5種,可是模塊數量能夠有不少,每一個模塊都針對自身有特定的配置內容,這些配置內容中,能夠被放到配置文件nginx.conf
中的,被包裝成了一條條ngx_command_t
指令。這些指令的內容決定了nginx.conf
中能夠寫入的操做指令。函數
Nginx
初始化時解析nginx.conf
配置文件,找到對應的ngx_command_t
。調用該ngx_command_t
中的函數,該函數最終初始化模塊對應的ngx_<module name>_conf_t
結構體,完成配置。源碼分析
這就是模塊和配置之間的關係。post
談到Nginx
的配置,首先想到的確定是配置文件nginx.conf
。ui
衆所周知,nginx.conf
配置文件的結構由一條條Nginx
配置指令構成(官方文檔)。Nginx
配置指令能夠分爲兩種:簡單指令和塊指令。
例如:
worker_processes 1;
就是一條簡單指令events { ... }
就是一條塊指令若是,一個塊指令中含有其餘指令,那麼稱這個塊指令爲上下文(注意區別模塊中的上下文概念)。
例如:
events { use epoll; worker_connections 1024; }
events
是塊指令,因爲events
中包含有指令(簡單指令或塊指令)。所以稱events
爲events上下文。
常見的上下文還有:http上下文、server上下文、location上下文。整個nginx.conf
文件稱爲main上下文
前面提到過:Nginx
配置文件中的一條指令對應一個ngx_command_t
結構體。所以,分析源碼中的配置指令,就是分析ngx_command_t
結構體。
ngx_command_t
結構體定義:
struct ngx_command_s { ngx_str_t name; ngx_uint_t type; char *(*set)(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); ngx_uint_t conf; ngx_uint_t offset; void *post; };
各成員含義以下:
name
:本條指令的名字,例如worker_processes 1;
對應的ngx_command_s.name
就是worker_processes
。
set
:函數指針,因此set
用來表示,當Nginx
解析配置文件,碰到指令時,該執行怎樣的操做。而該操做自己,天然是用來設置本模塊所對應的ngx_<module name>_conf_t
結構體。
conf
:這個變量只在NGX_HTTP_MODULE
類型的模塊的ngx_command_t
使用。這個變量和今天討論的話題關係不大。暫不討論。
offset
:這個變量用來標記ngx_<module name>_conf_t
中某成員變量的偏移量,純粹是爲使用方便。
type
:配置指令屬性的集合。例如,worker_processes
這條指令對應的type
定義爲:
NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE1
其中,各個宏定義以下:
#define NGX_MAIN_CONF 0x01000000 #define NGX_DIRECT_CONF 0x00010000 #define NGX_CONF_TAKE1 0x00000002
NGX_MAIN_CONF
是指,該指令用於main上下文。NGX_DIRECT_CONF
是指,該指令是用於main上下文的簡單指令。NGX_CONF_TAKE1
是指,該指令後跟一個參數,例如worker_processes 1;
的1
就是指後面跟一個參數,這個參數的數目由NGX_CONF_TAKE1
指定。相似用來定義指令類型的宏還有不少,具體能夠參考源碼中各個模塊中ngx_command_t
的設置。
Nginx
默認是之後臺的形式運行的,這種運行形式被稱爲daemon
,固然,在調試的時候,爲了方便,通常是關掉daemon
這種運行形式。
在配置文件中經過daemon
指令來打開或關閉。官方文檔對daemon
指令說明以下:
Syntax: daemon on | off; Default: daemon on; Context: main
在源碼中(core\nginx.c
),daemon
指令對應的ngx_command_t
結構體以下:
{ngx_string("daemon"), // 指令的名字daemon NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_FLAG, // 指令的類型 ngx_conf_set_flag_slot, // 指令對應的操做 0, offsetof(ngx_core_conf_t, daemon), NULL }
其中,NGX_MAIN_CONF
指,daemon
指令的上下文爲main上下文。NGX_DIRECT_CONF
指,daemon
指令是一條能夠直接寫在main上下文的簡單指令。NGX_CONF_FLAG
指,daemon
指令是一個開關指令,接收on | off
做爲指令參數。
Nginx
能夠在配置文件中經過user
指令指定運行時所在的用戶及用戶組。官方文檔對user
指令的說明以下:
Syntax: user user [group]; Default: user nobody nobody; Context: main
在源碼中(core\nginx.c
),user
對應的ngx_command_t
結構體定義以下:
{ ngx_string("user"), NGX_MAIN_CONF|NGX_DIRECT_CONF|NGX_CONF_TAKE12, ngx_set_user, 0, 0, NULL },
其中NGX_MAIN_CONF
及NGX_DIRECT_CONF
的含義與daemon
指令的含義相同。NGX_CONF_TAKE12
是指該指令接收1個或兩個參數,即Syntax: user user [group];
Nginx
中能夠指定採用的事件監聽機制類型,好比select、poll、epoll
等。
這個指定操做在events
指令中完成。這裏events
指令爲塊指令。
官方文檔對events
指令的定義以下:
Syntax: events { ... } Default: — Context: main
在源碼中(event\ngx_event.c
),events
指令對應的ngx_command_t
結構體定義以下:
{ ngx_string("events"), NGX_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_NOARGS, ngx_events_block, 0, 0, NULL }
其中,NGX_MAIN_CONF
的含義與daemon
指令相同。NGX_CONF_BLOCK
是指,這是一條塊指令。NGX_CONF_NOARGS
是指,該指令不接受參數。
總結
以上三條指令可以很清楚的說明,在Nginx
源碼中是如何組織和管理配置文件中使用的配置指令的。
對於其餘指令,能夠直接閱讀源碼中該指令的定義。源碼就是最好的文檔。
因爲Nginx
是高度模塊化的,於是,對Nginx
的配置必定是對模塊的配置。
Nginx
的每條配置指令對應某模塊中的一條ngx_command_t
定義。
每條ngx_command_t
必定操做了其所在模塊的ngx_<module name>_conf_t
結構體中某些項。
Nginx
初始化時,首先解析配置文件,而後執行對應指令的ngx_command_t
中的操做函數,設置ngx_<module name>_conf_t
中的某些項,完成配置工做。
而後,Nginx
根據這些配置,執行啓動流程,進而開始工做。
到此爲止。本篇結束。