Nginx 配置全解析(一)

前言

        Nginx是一款高性能的HTTP和反向代理服務器。在互聯網早期,很多公司使用的都是Apache的HTTPD服務器,可是隨着互聯網業務的逐漸發展,Apache服務器在很多情況下滿足不了業務的需求。這時一直緊跟Apache腳步的Nginx逐漸發展了起來。Nginx以其卓越的性能,以及優秀的高併發量和反向代理,逐漸得到了越來越多互聯網公司的使用。 
        在國內的很多互聯網公司使用就是Nginx。其中還有很多像阿里這種大公司對Nginx進行了二次開發,使其更加適合自己的業務發展。
        但是並不是說Nginx能夠取代Apache,因爲Apache也有其適用的場景。我們看下面一組調查數據,或許能夠對互聯網服務器的發展有一個清晰的瞭解。

高併發網站使用的服務器佔比圖

各種服務器所佔用的主機數量

以上數據參考自 
https://news.netcraft.com/archives/2017/08/29/august-2017-web-server-survey.html

        從上面的數據中可以瞭解到,互聯網服務器還是有很多種類,Apache和Nginx只是在其中佔了比較大的比例,並且正按照不同的趨勢發展着。下面我們就來介紹一下Nginx的配置和使用。

安裝

        與Apache一樣,Nginx也可以自己手動編譯安裝,並制定自己需要的各種功能選項,這一點我們留在以後再講。

        CentOS 的官方安裝包中不包含Nginx的安裝包,所以我們需要從EPEL源裏面去安裝。CentOS 7 EPEL源中Nginx的版本是1.10.2.

        安裝成功之後,我們執行nginx -h 就可以查看基本的使用幫助。

[root@localhost ~]#nginx -hnginx version: nginx/1.10.2
Usage: nginx [-?hvVtTq] [-s signal] [-c filename] [-p prefix] [-g directives]

Options:
  -?,-h         : this help
  -v            : show version and exit
  -V            : show version and configure options then exit
  -t            : test configuration and exit
  -T            : test configuration, dump it and exit
  -q            : suppress non-error messages during configuration testing  -s signal     : send signal to a master process: stop, quit, reopen, reload  -p prefix     : set prefix path (default: /usr/share/nginx/)
  -c filename   : set configuration file (default: /etc/nginx/nginx.conf)
  -g directives : set global directives out of configuration file
Options:
  -?,-h         : 使用幫助  
  -v            : 顯示版本  
  -V            : 顯示版本和配置信息  
  -t            : 檢查配置文件是否錯誤  
  -T            : 檢查配置文件,並將服務發佈  
  -q            : suppress non-error messages during configuration testing  
  -s signal     : 根據 stop, quit, reopen, reload 管理服務進程  
  -p prefix     : 編譯時可以指定安裝路徑 (default: /usr/share/nginx/)
  -c filename   : 指定配置文件路徑 (default: /etc/nginx/nginx.conf)
  -g directives : 設置全局配置文件路徑

配置

        學習一門技術最好的辦法就是查看官方的文檔,這一點有時會好過市面上的大部分數據。Nginx是一個龐大的工程,需要學習的知識點多,所以我們就參考官方文檔,來進行學習。
        官方文檔地址 http://nginx.org/en/docs/

Nginx 配置結構

通過查看Nginx的默認配置文件,我們總結了下面這樣一種文件結構。

    ...              #全局塊

    events {         #events塊
    ...    }

    http      #http塊
    {
        ...   #http全局塊
        server        #server塊
        { 
            ...       #server全局塊
            location [PATTERN]   #location塊
            {
                ...            }
            location [PATTERN] 
            {
                ...            }
        }
        server  # 多個server就構建了多個虛擬主機
        {
        ...   # 針對這個server的基本配置
        }
        ...     #http全局塊
    }

        從結構中可以很清晰的看到,兩個大的佈局,分別是全局的主配置塊以及Http配置塊。這兩個模塊將會在日常的工作應用中進行大量的配置,接下來,我們也主要介紹這兩個模塊。

全局配置段常用的配置

        全局段的配置文件,從功能上來分,大體上可以分爲下面幾種,正常運行必備的配置,優化性能需要的配置事件驅動需要的配置,調試和定位的問題。接下來,從每個方面挑選一些比較重要的內容進行介紹。

一、正常運行必備的配置

1、進程運行時的用戶
通過查看官方文檔說明,管理user的語法結構如下。

Syntax:	    user user [group];
Default:	user nobody nobody;
Context:	main
  • Synatx: 說明語法的使用

  • Default: 如果沒有指定的話,默認是nobody用戶。如果沒有明確地指定組,默認是與用戶同名的組。

  • Context: 指明該語法能夠配置在哪裏,這裏只能是 主代碼塊。

2、指定存儲nginx主進程PID的文件路徑

Syntax:	    pid file; # 指定主進程文件路徑
Default:	pid nginx.pid;
Context:	main

3、動態加載模塊的配置文件

 include /usr/share/nginx/modules/*.conf;

二、優化性能需要的配置

1、 woker進程的數量

Syntax:	    worker_processes number | auto;
Default:	worker_processes 1;
Context:	main

        指定woker進程的數量,通常指定爲當前CPU的物理核心數。但是如果不是很瞭解這其中的運行機制的話,設置爲auto也是一個不錯的選擇,Nginx版本從1.3.8開始支持auto選項。

2、將woker進程與CPU進行綁定
Nginx 可以指定哪些CPU可以來處理worker進程。默認不指定。語法如下。

Syntax:	worker_cpu_affinity cpumask ...;
        worker_cpu_affinity auto [cpumask];
Default:	—
Context:	main

我們以下面的官方示例來進行介紹。

2進程,2核cpu

worker_processes    2; # 一共有2個work進程
worker_cpu_affinity 01 10;

01 表示啓用第一個CPU內核,02表示開啓第二個CPU內核。

4個進程,4核CPU

worker_processes    4; # 一共有四個work進程
worker_cpu_affinity 0001 0010 0100 1000;

0001表示啓用第一個內核,0010表示啓用第二個內核,以此類推。
如果只開啓了兩個進程,想要平分4核CPU,該怎麼做

worker_processes    2; # 一共有2個work進程
worker_cpu_affinity 0101 1010;

            0101 表示開啓第一個和第三個CPU內核,1010表示第二個和第四個CPU內核。通過上面的幾個示例,我們大體上應該明白,有幾個CPU核心就有幾位二進制數,每一位二進制數在對應的位置上分別表示相應CPU核心的開關。 2核是01,10,4核是0001,0010… 8核是 00000001,00000010 …. 所謂的開關也是相對的概念,CPU核心關閉了,只是不再處理Nginx的進程,系統的其他進程還是會去處理。

實現後的效果如下圖所示。從圖中可以看到,兩個worker進程的CPU在不斷的切換。

CPU核心切換

3、指定worker進程優先級

Syntax:	worker_priority number;
Default:	worker_priority 0;
Context:	main

設定worker進程的優先級。進程優先級的範圍是[-20,20].

4、woker進程可以打開的最大的文件數量

Syntax:	worker_rlimit_nofile number;
Default:	—
Context:	main

        直接修改配置文件,就可以指定worker進程能夠打開的最大的文件數量。不用重新啓動主進程。

三、事件驅動相關的配置

        事件驅動的相關配置都是寫在 event{ .... } 代碼塊中的,很容易區分。接下來介紹幾個常用的配置。

1、每個worker進程所能夠打開的最大併發連接數數量

Syntax:	worker_connections number;
Default:	worker_connections 512;
Context:	events

        可以指定每個worker進程的的最大併發連接數。當然,在指定數量的時候應該根據實際情況來指定,因爲操作系統的Socket數量一共就65536個。

2、指明併發鏈接請求的方法

Syntax:	use method;
Default:	—
Context:	events

        併發鏈接的請求的方法有很多種。例如poll,epoll,select,等等很多種形式。Nginx模式使用最有效的方式。

3、是否讓每個進程輪流處理請求

Syntax:	accept_mutex on | off;
Default:	accept_mutex off;
Context:	events

        處理新的連接請求的方法;on指由各個worker輪流處理新請求,Off指每個新請求的到達都會通知(喚醒)所有的worker進程,但只有一個進程可獲得連接,但是會影響性能,默認on

四、調試和定位的問題

1、是否以守護進程的方式運行Nginx

Syntax:	daemon on | off;
Default:	daemon on;
Context:	main

        守護進程指的是,進程默認在後臺運行。Nginx默認是以守護進程的形式運行程序。一般用戶開發調試等應用場景中。

2、是否以master/worker模型運行nginx

Syntax:	master_process on | off;
Default:	master_process on;
Context:	main

        Nginx默認啓動worker進程。如果master_process 開啓,則進程列表中將不會有worker進程。

3、指定默認的日誌級別

Syntax:	error_log file [level];
Default:	error_log logs/error.log error;
Context:	main, http, mail, stream, server, location

在實際的使用中,可以根據自己的實際情況進行相應的級別調整。

關於全局配置段的相關配置還可以參考官方文檔http://nginx.org/en/docs/ngx_core_module.html#example

http的配置結構

        在前的介紹中,我們已經介紹過,關於httpd的配置都必須寫在server{....} 代碼塊中。 
Nginx的Http配置主要位於ngx_http_core_module模塊中。

一、設置監聽端口以及相關屬性

1、監聽端口

        通常,我們知道TCP默認訪問的是80端口,但是我們也可以手動指定核配置這個端口,並指定以什麼樣的形式來監聽。

Syntax:	listen address[:port] [default_server] [ssl] [http2 | spdy] [proxy_protocol] 
        [setfib=number] [fastopen=number] [backlog=number] [rcvbuf=size] [sndbuf=size] 
        [accept_filter=filter] [deferred] [bind] [ipv6only=on|off] [reuseport] 
        [so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt]];listen port [default_server] 
        [ssl] [http2 | spdy] [proxy_protocol] [setfib=number] [fastopen=number] 
        [backlog=number] [rcvbuf=size] [sndbuf=size] [accept_filter=filter] [deferred] 
        [bind] [ipv6only=on|off] [reuseport] [so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt]];
        listen unix:path [default_server] [ssl] [http2 | spdy] [proxy_protocol] [backlog=number] 
        [rcvbuf=size] [sndbuf=size] [accept_filter=filter] [deferred] [bind] 
        [so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt]];
Default:	listen *:80 | *:8000;
Context:	server

這條命令太酸爽,我們主要介紹其中幾個比較重要的幾個配置。

  • default_server 設定爲默認虛擬主機

  • ssl 限制僅能夠通過ssl連接提供服務

  • backlog=number 超過併發連接數後,新請求進入後援隊列的長度,超出限制就加入等待隊列。

  • rcvbuf=size 接收緩衝區大小

  • sndbuf=size 發送緩衝區大小

2、ServerName

        ServerName 指的是我們通過域名來訪問的時候的地址。而且還可以設置爲泛域名解析。

Syntax:	server_name name ...;
Default:	server_name "";
Context:	server

 虛擬主機後面的主機名稱可以跟多個由空白字符分隔的字符串
支持*通配任意長度的任意字符。例如 server_name *.taobao.com www.taobao.*

3、設置TCP是否延遲發送

Syntax:	tcp_nodelay on | off;
Default:	tcp_nodelay on;
Context:	http, server, location

        在keepalived模式下的連接是否啓用TCP_NODELAY選項,當爲off時,延遲發送,合併多個請求後再發送默認On時,不延遲發送

4、是否顯示服務器版本

當用戶訪問web服務時,是否在響應報文的首部顯示Nginx的版本。 默認是ON。

Syntax:	server_tokens on | off | build | string;
Default:	server_tokens on;
Context:	http, server, location

http://ot2trm1s2.bkt.clouddn.com/Linux/2017-10-25-linux-pro-command-4/server_tokens.png

二、定義路徑相關的配置

5、Location配置

我們先來看一下官方網站給出的示例。

location = / {
    [ configuration A ]
    }
    
location / {
    [ configuration B ]
    }
    
location /documents/ {
    [ configuration C ]
    }
    
location ^~ /images/ {
    [ configuration D ]
    }
    
location ~* \.(gif|jpg|jpeg)$ {
    [ configuration E ]
    }

       location代碼塊的語法可以歸結爲 location [ = | ~ | ~* | ^~ ] uri { ... },在一個server中location配置段可存在多個,用於實現從uri到文件系統的路徑映射;ngnix會根據用戶請求的URI來檢查定義的所有 location,並找出一個最佳匹配,而後應用其配置。
在指定location的過程中,使用了不同的符號,是具有不同的匹配規則的。
= : 表示對 uri 精確匹配。
^~:對URI的最左邊部分做匹配檢查,不區分字符大小寫
~:對URI做正則表達式模式匹配,區分字符大小寫
~*:對URI做正則表達式模式匹配,不區分字符大小寫
不帶符號:匹配起始於此uri的所有的uri
匹配優先級從高到低:=, ^~, ~/~*, 不帶符號

6、alias path 別名路徑
通過定義一個別名路徑來替換特定的目錄。

Syntax:	alias path;
Default:	—
Context:	location

下面來看一個例子。

server {        # 基於ip的虛擬主機配置
        listen   172.18.2.77:81;
        root      /app/site2;
                
        location /images {
           root  /app/website;  #當我們訪問 http://172.18.2.77:81/images的時候實際上
                                #訪問的卻是 /app/website/images/ 路徑
        }

        location /blog {
            
            alias /app/website1 ; # 當我們訪問 http://172.18.2.77:81/blog 的時候
                                # 實際上訪問的內容 卻變成了/app/website1路徑下的資源
        }
    }

        從上面的例子中,可以看出,alias是將uri全部替換掉,而root也只替換了uri的部分內容,二者還是有所區別的。

7、指定錯誤頁面

        在訪問互聯網資源的過程中,很容易遇見404頁面,而一些成熟的web服務會將錯誤頁面重定向到指定的頁面上,接下來來配置一下這個頁面。

Syntax:	error_page code ... [=[response]] uri;
Default:	—
Context:	http, server, location, if in location
error_page 404             /404.html;

# 當出現錯誤的時候,直接跳轉到404頁面,但是返回給客戶端的是200狀態碼。
error_page 404      =200   /404.html;
error_page 500 502 503 504 /50x.html;

順序檢查文件是否存在

        按順序檢查文件是否存在,返回第一個找到的文件或文件夾(結尾加斜線表示爲文件夾),如果所有的文件或文件夾都找不到,會進行一個內部重定向到最後一個參數。只有最後一個參數可以引起一個內部重定向,之前的參數只設置內部URI的指向。最後一個參數是回退URI且必須存在,否則會出現內部500錯誤。

Syntax:	try_files file ... uri;
        try_files file ... =code;Default:	—
Context:	server, location

 可以參考下面的示例,其中$uri表示系統中的變量,可以查看官方文檔瞭解。

location /images/ { 
    try_files $uri /images/default.gif; 
    }
location / { 
    try_files $uri $uri/index.html $uri.html =404; 
    }

三、定義客戶端請求的相關配置

1、設置keepalive超時時間 

        客戶端訪問web服務的時候,可以允許客戶端以長鏈接的形式訪問資源,定義超時時間。設置爲0表示,禁止長鏈接。

Syntax:	keepalive_timeout timeout [header_timeout];
Default:	keepalive_timeout 75s;
Context:	http, server, location

2、長連接上資源的請求數量
在一次長連接上所允許請求的資源的最大數量。默認的大小是100

Syntax:	keepalive_requests number;
Default:	keepalive_requests 100;
Context:	http, server, location

3、限制響應給客戶端的傳輸速率
限制響應給客戶端的傳輸速率,單位是bytes/second,默認值爲0表示不限制。

Syntax:	limit_rate rate;
Default:	limit_rate 0;
Context:	http, server, location, if in location

4、限制客戶端使用除了指定的請求方法之外的其它方法
limit_except method ... { ... },僅用於location,可以限制客戶端使用除了指定的請求方法之外的其它方法,常見的method:GET, HEAD, POST, PUT, DELETE,MKCOL, COPY, MOVE, OPTIONS, PROPFIND,PROPPATCH, LOCK, UNLOCK, PATCH。

Syntax:	limit_except method ... { ... }
Default:	—
Context:	location

看一下下面的這個例子

limit_except GET {
    allow 192.168.1.0/24;
    deny all;
    }

這裏的作用是除了GET和HEAD 之外其它方法僅允許192.168.1.0/24網段主機使用。

總結

        截止此處,我們已經介紹了Nginx的一些基本配置,這些配置都是基於 ngx_http_core_module 中的配置,還可以查看官方文檔瞭解,http://nginx.org/en/docs/http/ngx_http_core_module.html 。 
同時,在接下來的其他模塊中,我們再接着介紹Nginx其他模塊的配置和使用。

下面將學習過程中的示例配置文件附於下圖,可右鍵點擊在新的標籤頁中查看大圖。

Nginx%E9%85%8D%E7%BD%AE%E7%A4%BA%E4%BE%8

個人博客地址:http://www.pojun.tech/ 歡迎訪問

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章