# 4 Nginx相關配置
### 4.1 重啟Nginx
```bash
#sudo /usr/local/sbin/nginx -s reload
```
### 4.2 關閉Nginx
```bash
?????快速停止服務
#sudo /usr/local/sbin/nginx -s stop
???
優雅停止服務
#sudo /usr/local/sbin/nginx -s quit #kill -s SIGQUIT pid_master
#kill -s SIGWINCH pid_master
```
###4.3 Nginx進程之間關系
一個master進程來管理多個work進程.
work進程數量和CPU的核數相同(進程間切換的代價最小)
### 4.4 Nginx配置通用語法
**塊配置項**
```bash
塊配置項由一個塊配置項名和一對大括號組成. 比如
events {
use epoll;
}
nginx.conf中的events,http,server,location,upstream等都是塊配置項 塊配置項可以嵌套,內嵌塊直接繼承外層塊.
```
**塊配置項的語法格式**
```bash
基本格式:
配置項名 配置項值1 配置項值2 ...;
配置項目必須是nginx的某一模塊想要處理的,否則判定為非法配置項名. 配置項值可以是數字,字符串包括正則表達式,可能有多個值. 每行配置的末尾以分好';'結束
```
**配置項的單位**
```bash
以'#'字符開始 的一行視為注釋
#pid logs/nginx.pid
指定空間大小 單位包括 K k 千字節(KB),M m 兆字節(MB)
gzip_buffers 4 8k;
client_max_body_size 64M;
指定時間大小 單位包括 ms,s,s,m,h,d,w,M,y; expires 10m;#有效期為10s
```
**配置項中使用變量**
```bash
$varname 比如:
log_format main '$remote_addr - $remote_user'
```
### 4.5 Nginx服務基本配置
```bash
Nginx服務在運行時,至少需要加載幾個核心模塊和一個事件類模塊. 這些模塊所支持的配置統稱為基本配置.
主要分為4大類:
1用于調試定位為題的配置項
2正常運行的必備配置項
3優化性能的配置項
4事件類配置項
```
### **用以調試和定位問題的配置塊 **
是否以守護進程方式運行
```bash
daemon on|off;
默認為on
如果調試階段 可以設置為off 以 前臺進程方式運行 這樣便于跟蹤調試Nginx
```
是否以master/worker方式工作
```bash
master_process on | off;
默認為on
如果調試階段 可以設置為off 以 master進程自身來響應請求 這樣便于跟蹤調試Nginx
```
**errorr日志的設置**
```bash
error_log /path/file level;
#第一個項為設置為error日志的路徑和文件名
#第二項為等級 有debug,info,notice,warn,error,crit,alert,emerg 默認為 logs/error.log error;
當第一項設置為 /dev/null 表示忽略任何日志
當設置為 stderr 這樣錯誤日志會輸出到標準錯誤文件中.
第二項的等級 自左向右依次增加.
最后應該保證輸出日志的硬盤空間應當足夠使用
**設置成debug模式的時候,需要在configure時 加上--with-debug 參數
```
**僅對指定的客戶端輸出debug級別的日志**
```bash
debug_connection IP[/port]
由于該配置屬于事件類配置,需要放置在events{...}才有效 例如:
events{
debug_connection 192.168.1.100;
debug_connection 192.168.1.100/24;
}
僅對以上設置的IP才設置成debug級別的日志,其他請求沿用error_log 配置的級別
```
**限制coredump核心轉儲文件的大小**
```bash
worker_rlimit_core_size size;
以size來限制coredump文件的大小.
```
**指定coredump文件的位置**
```bash
working_directory path;
path指定coredump文件的位置
需要保證path路徑有足夠的寫入權限和足夠的使用空間.
```
###正常運行配置項
**引入其他配置文件**
```php
include /path/file;
include配置項可以將其他配置文件引入到當前的nginx.conf文件中,參數可以是絕對路徑和相對(conf/)路徑
include mine.types;
include vhost/*.conf
```
**pid文件的位置**
```bash
pid path/file
logs/nginx/pid
保存master進程ID的pid文件夾的存放路徑
應該確保nginx在相應的目錄中有創建pid文件的權限.
```
**Nginx worker進程運行的用戶和用戶組
**
```bash
user username [groupname];
user nobody nobody;
user用于設置master進程啟動后,fork出的worker子進程運行在哪個用戶和用戶組下.
當設置username沒有設置groupname,則默認username與groupname相同.
```
**指定worker進程可以打開的最大文件句柄描述符個數**
```bash
worker_rlimit_nofile limit_num;
設置一個worker進程可以打開的最大文件句柄數.(應該大于最大連接數)
```
**限制信號隊列長度**
```bash
worker_rlimit_sigpending limit_num;
設置每個用戶發往Nginx信號隊列的大小.多的將丟棄
```
### 優化性能配置項
**Nginx worker進程的個數**
```bash
worker_process number;
默認為1
worker進程的數量直接影響性能.合適的worker進程數量和業務息息相關.
worker進程是單線程的進程,如果確認各模塊中不會出現阻塞調用那么number設置為cpu的核數
如果有可能出現阻塞調用,number設置的比cpu核數大一點.
多worker進程可以充分利用多核系統架構,如果worker進程相比CPU數量太多會增加進程間切換的消耗.
```
**綁定Nginx worker進程到指定的CPU內核**
```bash
**僅對Linux有效
worker_cpu_affinity cpumask[cpumask...]
可防止多個進程搶占同一核心
worker_processes 4;
worker_cpu_affinity 1000 0100 0010 0001;
worker_processes 2;
worker_cpu_affinity 10 01;
```
**系統調用getimeofday()的執行頻率**
```bash
默認 timer_resolution t;
例如 timer_resolution 100ms;表示至少每100ms才調用一次gettimeofday()
目前大多數內核中,花銷只是一次vsyscall()僅對共享內存頁中的數據做訪問.一般可以不適用這個配置
```
### 事件類配置項
**是否打開accept鎖**
```bash
accept是Nginx負載均衡鎖.這把鎖可以讓多個work進程輪流,有序的與新的客戶端建立TCP連接.
默認是打開的.
如果配置關閉,建立TCP連接耗時會更短.但是多個worker之間負載不會均衡.
```
**lock文件的路徑**
```bash
lock_file path/file
默認 logs/nginx.lock
accept鎖可能需要這個lock文件,如果accept鎖配置關閉那么lock_file配置無效
如果accept鎖配置打開且由于操作系統和編譯器等因素導致Nginx不支持原子鎖,將利用文件鎖實現accept.
```
**使用accept鎖后到真正建立連接之間的延遲時間**
```bash
accept_mutex_delay numberms;
默認500ms;
一個worker進程試圖獲取到accept鎖失敗,經過number ms時間再次試圖獲取accept鎖.
```
**批量建立連接**
```bash
multi_accept [on|off]
默認off
當時間模型通知有新連接時,盡量對本次調度中客戶端發起的TCP請求都建立連接.
```
**選擇事件模型**
```bash
use [kqueue | rtsig epoll | /dev/poll | select |poll |eventport]
默認 Nginx會自動選擇最適合的事件模型.
對于Linux來說,可以供選擇的時間驅動模型有select,poll,epoll的三種.
```
**每個worker的最大連接數**
```bash
worker_connection number;
定義每個worker進程可以同時處理的最大連接數
```
### 使用HTTP核心模塊配置一個靜態WEB服務器
```bash
所有的HTTP配置項都必須直屬于http塊,server塊,location塊,upstream塊,if塊.
直屬于指的是配置項直接所屬的大括號對應的設置塊
```
**虛擬主機與請求的分發**
```bash
由于IP有限,存在多個主機域名對應同一個IP地址的情況.在nginx.conf中可以通過server塊 來設置server_name定義虛擬主機.
每個server塊就是一個虛擬主機,只處理與之相應的主機域名請求,
這樣一套服務器上的Nginx就能以不同的方式處理不同的域名的HTTP請求了.
```
**監聽端口**
```bash
listen address:port[default | default_server |[backlog=num |revbuf=size
| sndbuf=size| accept_filter=filter |deferred|bind|ipv6only=[on|off] |ssl]]
```
默認listen 80
在listen之后可以只加IP地址,端口,或者主機名
```bash
isten 127.0.0.1:8000;
listen localhost;
listen 8000;
listen *:8000;
listen 443 default_server ssl;
```
```bash
default 將所在的server塊作為整個WEB服務的默認server塊;如果所有的server都沒設置這個參數, nginx.conf第一個server作為默認塊.
當一個請求無法匹配配置文件的任一主機名就會選用默認虛擬主機. default_server 同上
backlog=num 表示TCP中backlog隊列的大小,默認為-1表示不設置. TCP三次握手過程中進程還沒有處理監聽句柄,backlog用以放置這個新連接, 如果隊列已滿,新客戶端3次握手建立連接失敗
deferred 設置這個參數后,通過三次握手之后內核不會在建立連接時處理,而是等發來數據的時候處理連接.
bind 綁定當前地址:端口
ssl 在當前監聽的端口上建立的連接必須給予SSL協議
```
**主機名稱**
```bash
server_name name[...];
默認 server_name "";
server_name之后可以跟多個主機名稱
eg: server_name www.wowpai.top download.wowpai.top;
在開始處理HTTP請求時,Nginx會取出header頭中的host,與server中每個server_name進行比較, 如果多個server塊都匹配需要按照優先級來選擇處理的server塊.
首先選擇所有字符完全匹配的server_name www.wowpai.top
其次選擇通配符在前面的server_name *.wowpai.top
其次選擇通配符在后面的server_name www.wowpai.*
最后選擇使用正則匹配的server_name ~^\.wowpai\.top$
如果以上都不能匹配將按照以下的server塊:
優先選擇在listen配置項后加入[default |default_server]的server塊 找到匹配listen端口的第一個server塊
如果server_name后面跟著字符串 server_name ""表示匹配沒有Host這個HTTP頭部的請求
Nginx使用server_name配置項針對特定Host域名的請求提供不同的服務以實現虛擬主機的功能.
```
**server_names_hash_bucket_size**
```bash
server_names_hash_bucket_size size;
默認 server_names_hash_bucket_size 32|64|128;
可配置塊 http server location
為提高查找相應的server_name的能力,Nginx使用散列表來存儲. size設置了每個散列塊占用的字節數.
```
**server_names_hash_max_size**
```bash
server_names_hash_max_size size;
默認 server_names_hash_max_size 512;
可配置塊 http serverlocation
server_names_hash_max_size 影響散列表的沖突率,server_names_hash_max_size越大,沖突率越低,檢索速度越快.
```
**重定向主機名稱的處理**
```bash
server_name_in_redirect on|off;
默認 on
該配置需要配合server_name 使用.在使用on打開的時候,表示在重定向請求時會使用server_name里面配置的
第一個主機名代替原來的請求中的Host頭部.
當使用off關閉時,表示在重定向請求時使用請求本身的Host頭部.
```
### **location**
```bash
location [=|~|~* |^~| @ ] | /uri/ {}
可配置塊 server
location會嘗試根據用戶請求中的URI來匹配上面的/uri表達式,如果可以[匹配就選擇location{}塊中的配置來處理用戶請求.
location的匹配規則:
= 表示把URI作為字符 以便與參數中的uri做完全匹配
location = /{
#只有當用戶請求/時 才會調用該location下的配置
}
~ 表示匹配URI時字母大小寫敏感的
~* 表示匹配URI時忽略字母大小寫 后面可以跟上正則表達式
location ~* \.(gif|jpg|jpeg){
#匹配這三種圖片的資源請求
}
^~ 表示匹配URI只需要前半部分uri參數匹配即可
location ^~ /images/{
#以/images/開始的請求都會匹配上
}
@ 表示僅用于Nginx服務內部請求之間的重定向,帶有@的location不直接處理用戶請求
沒有匹配的URI應該得到一個響應,
location /{
#前面所有的匹配都未成功就意味著會被這個location 匹配-----捕獲
}
**location匹配的存在一定的優先級:先精確匹配然后模糊匹配,最后匹配/
```
**文件路徑定義**
**1 以root設置資源路徑
**
```bash
root path;
默認 root html;
配置項: http server location if
location /download/ {
root /opt/web/html/;
}
如果請求的URI是/download/index/test.html,那么WEB服務器應該返回的是服務器上
???/opt/web/html/download/index/test.html
```
**2 以alias設置資源路徑
**
```bash
alias path;
配置塊:location
alias也是用來設置資源路徑的.與root的不同點在于如何解讀緊跟location后面的參數. 這將會致使alias與root以不同的方式將用戶的請求映射到真正的磁盤文件上.
如果請求的URI是 /conf/nginx.conf,實際上訪問文件在/usr/local/nginx/conf/nginx.conf
location /conf{
alias /usr/local/nginx/conf/;
}
location /conf{
root /usr/local/nginx/;
}
使用alias時在URI向實際文件映射的過程中,已經把location后配置的/conf這部分字符串丟棄掉. 最終映射成path/nginx.conf文件
而root則不一樣 最終直接映射成 path/conf/nginx.conf
```
**3 設置首頁**
```bash
index file ...;
默認 index index.html;
配置塊 http server
location location /{
root html;
index index.html index.htm index.php;
}
優先返回index.php,沒有的話返回index.htm,如果還沒有,再嘗試放回index.html
```
**4 根據HTTP返回碼重定向**
```bash
rror_page code[code ...] [= | = answer-code] uri|@name_location
配置塊 http server location if
如果某個請求返回錯誤碼時匹配上了error_page中設置的code,則重定向到新的URI中. 雖然重定向了URI,但返回的錯誤碼還是和原來的相同.可以通過'='來改變返回的錯誤碼
error_page 404 =200 /empty.html
如果不修改 URI,只是想讓這樣的請求重定向到另一個location中處理
location /{
error_page 404 @failback;
}
location @failback{
proxy_pass http://127.0.0.1:8081;
}
```
**5 是否允許定義error_page
**
```bash
recursive_error_pages [on|off];
默認recursive_error_pages off;
配置塊 http server location
確定是否允許定義error_page
```
**try_files**
```bash
try_files path1 [path2] uri;
配置塊 server location
try_files 后面可以跟上多個path,且最后一定要跟上uri
按照順序遍歷每個path,如果可以有效的讀取就直接返回這個path并結束請求. 否則繼續向后遍歷,最后就重定向到uri上
location /{
#try_files $uri $uri/ /$uri.html $uri/index.html @other;
try_files $uri $uri/ /error/php?c=404 =404;
}
location @other{
proxy_pass http://backend;
}
```
** 對客戶端請求的限制 **
按HTTP方法名限制用戶請求
```bash
limit_execpt method ...{
...
}
配置塊 location
方法名有 PUT HEAD POST DELETE MKCOL COPY MOVE OPTIONS PROPFIND PROPPATCH LOCK UNLOCK PATCH
limit GET{
allow 192.168.1.110/32;
deny all;
}
禁止GET 和HEAD方法,其他方法允許
```
HTTP請求包體的最大值
```bash
client_max_body_size size;
默認 client_max_body_size 1m;
配置塊 http server location
用戶打算上傳一個超過10G的文件,發超過定義client_max_size的值,回復錯誤
```
對請求的限速
```bash
imit_rate speed;
limit_rate 0;
配置塊 http server location if 限制客戶端請求限制每秒的傳輸的字節數.0表示不限制
server{
if ( $slow)
{
set $limit_rate 4k;
}
}
```