前言
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在不斷的切換。
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
二、定義路徑相關的配置
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其他模塊的配置和使用。
下面將學習過程中的示例配置文件附於下圖,可右鍵點擊在新的標籤頁中查看大圖。
個人博客地址:http://www.pojun.tech/ 歡迎訪問