Nginx 的配置指令


我們已經了解了 Nginx 的基本命令和架構原理,下面該到最讓人頭疼也是最不容易理解的部分了,那就是 nginx.conf 這個配置文件,下面從 Nginx 的指令開始,一步步來講解 Nginx 的配置。

Nginx 指令

先來看一個典型的 Nginx 配置文件示例。

main
http {
	upstream { … }
	split_clients {…}
	map {…}
	geo {…}
	server {
		if () {…}
		location {
			limit_except {…}
		}
		location {
			location {
			}
		}
	}
	server {
	}
}

從上面可以看到,這個配置文件中包含了多個指令塊,有些指令塊還是重復的,那么這在 Nginx 中是一個什么樣的規則?接下來會慢慢介紹。

指令塊的嵌套

在 Nginx 配置文件中,指令塊是可以互相嵌套的,例如上面的示例,http 塊中可以包含多個 server 塊,server 塊中還會包含多個 location 塊,每一個塊中都有相應的指令。

而每一個指令都有 Context 上下文,也就是生效的環境,這在 Nginx 的官方文檔中說的很清楚,例如下面的兩條指令,Context 中都表明了各自可以生效的環境,access_log 指令可以在多個上下文中生效:

Syntax:  access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];
		     access_log off;
Default: access_log logs/access.log combined; 
Context: http, server, location, if in location, limit_except

Syntax:  log_format name [escape=default|json|none] string ...;
Default: log_format combined "..."; 
Context: http

指令的合並

在 Nginx 中,指令分為兩種,一種是值指令,一種是動作類指令:

  • 值指令:存儲配置項的值,是用來配置某一個配置項的
    • 可以合並
    • 示例
      • root
      • access_log
      • gzip
  • 動作類指令:指定行為動作,往往表示接下來要做一件事情
    • 不可以合並
    • 示例
      • rewrit
      • proxy_pass
    • 生效階段
      • server_rewrite 階段
      • rewrite 階段
      • content 階段

這里面的示例以及生效階段,后面都還會詳細講,這里可以不用過多關注,既然指令分為兩種,那么就有不同的繼承規則,下面就來說一下。

值指令的繼承規則

例如下面的配置文件,這里面在 server 塊和 location 塊中都配置了 root 指令,Nginx 的繼承規則如下:

  • 子配置不存在時,直接使用父配置塊的指令
  • 子配置存在時,覆蓋父配置塊
server {
	listen 8080;
	root /home/geek/nginx/html;
	access_log logs/geek.access.log main;
	location /test {
		root /home/geek/nginx/test;
		access_log logs/access.test.log main;
	}
	location /dlib {
		alias dlib/;
	}
	location / {
	}

根據上面這兩條規則,第一個 location 使用自家的 root 指令,后面兩個 location 則使用 server 塊的 root 指令。這和編程語言中變量的作用域也是類似的,作用域更小的變量優先級往往更高,Nginx 的指令也是一樣。

文檔中沒有的指令如何判斷生效范圍

對於很多第三方模塊,很可能文檔並不完善,這時候需要通過源碼來查看指令的生效范圍。需要明確下面幾個問題:

  1. 指令在哪個塊下生效?
  2. 指令允許出現在哪些塊下?

這兩個問題是在源碼中定義的,例如:

static ngx_command_t  ngx_http_core_commands[] = {

    { ngx_string("variables_hash_max_size"),
      NGX_HTTP_MAIN_CONF|NGX_CONF_TAKE1,
      ngx_conf_set_num_slot,
      NGX_HTTP_MAIN_CONF_OFFSET,
      offsetof(ngx_http_core_main_conf_t, variables_hash_max_size),
      NULL },
    ......

從上面第三行可以看到,variables_hash_max_size 指令是在 main 塊下生效的。

還會有兩個回調方法:

  • 在 server 塊生效,從 http 向 server 合並
    • char *(*merge_srv_conf)(ngx_conf_t*cf, void *prev, void *conf);
  • 向 location 合並
    • char *(*merge_loc_conf)(ngx_conf_t*cf, void *prev, void *conf);

例如:

static ngx_http_module_t  ngx_http_core_module_ctx = {
    ngx_http_core_preconfiguration,        /* preconfiguration */
    ngx_http_core_postconfiguration,       /* postconfiguration */

    ngx_http_core_create_main_conf,        /* create main configuration */
    ngx_http_core_init_main_conf,          /* init main configuration */

    ngx_http_core_create_srv_conf,         /* create server configuration */
    ngx_http_core_merge_srv_conf,          /* merge server configuration */

    ngx_http_core_create_loc_conf,         /* create location configuration */
    ngx_http_core_merge_loc_conf           /* merge location configuration */
};

ngx_http_module_t 這個結構體里面,定義了很多回調方法,最后一個 ngx_http_core_merge_loc_conf 方法,就是制定合並規則的。這個方法定義了兩個參數,一個是父配置,一個是子配置:

static char *ngx_http_core_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
{
    ngx_http_core_loc_conf_t *prev = parent;
    ngx_http_core_loc_conf_t *conf = child;

    ngx_uint_t        i;
    ngx_hash_key_t   *type;
    ngx_hash_init_t   types_hash;

    if (conf->root.data == NULL) {
......

這個方法表明了從父配置向子配置合並。

listen 指令的用法

listen 指令在 server 塊中生效,用來配置監聽哪些端口,由這些端口來處理請求。listen 指令的配置如下:

如示例所示,listen 指令可以監聽的類型有多種,可以配置監聽地址和端口,也可以是僅地址和僅端口,還可以僅監聽 IPv6 等等。

究竟是哪個 server 來處理請求

server_name 指令的用法

一個指令:server_name

server_name 指令是用來配置究竟是哪個 server 來處理我們的請求的。有時候,一個 server_name 中可能會有多個域名,這時候是如何選擇的呢?

  1. server_name 指令后可以跟多個域名,第一個是主域名,多個域名之間空格分隔
  2. 泛域名:僅支持在最前或最后加 *,例如:server_name *.taohui.tech
  3. 正則表達式匹配:server_name www.taohui.tech ~^www\d+\.taohui\.tech$;

當 server_name 指令后有多個域名時,會有一個 server_name_in_redirect 的配置,這個配置默認關閉,它使用來控制域名重定向的,也就是這個配置開啟之后,請求過來會重定向到主域名訪問。

Syntax  server_name_in_redirect on | off;
Default server_name_in_redirect off; 
Context http, server, location
  1. 還可以用正則表達式創建變量

    • # 使用 $1/$2 的方式引用變量
      server { 
      	server_name ~^(www\.)?(.+)$; 
      	location / { root /sites/$2; } 
      }
      
    • # 還可以通過加一個 ?<> 的方式來命名變量
      server { 
      	server_name ~^(www\.)?(?<domain>.+)$;
      	location / { root /sites/$domain; } 
      }
      
  2. 特殊的配置規則

    • .test.tech 可以匹配 test.tech *.test.tech
    • _ 匹配所有域名請求
    • "" 匹配沒有傳遞 host 頭部的請求

server 匹配的順序

  1. 精確匹配(與順序無關)
  2. * 在前的泛域名(與順序無關)
  3. * 在后的泛域名(與順序無關)
  4. 按文件中的順序匹配正則表達式域名
  5. default server
    • 第 1 個
    • listen 指定 default

這里面 default server 有兩種指定方式,假如沒有配置 default server,那么第一個 server 塊就會成為 default server,如果 listen 中配置了 default,那么就會由配置的塊進行處理。

關注公眾號回復 Nginx 領取知識圖譜

關注公眾號回復 Nginx 領取知識圖譜


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM