嗨!分享就是關心!因此,咱們願意再跟你分享一點點知識。咱們準備了這個劃分爲三節的《Nginx教程》。若是你對 Nginx 已經有所瞭解,或者你但願瞭解更多,這個教程將會對你很是有幫助。html
咱們會告訴你 Nginx 是如何工做的,其背後的概念有哪些,以及如何優化它以提高應用程序的性能。還會告訴你如何安裝,如何啓動、運行。nginx
這個教程包括三節:正則表達式
基本概念 —— 這部分須要去了解 Nginx 的一些指令和使用場景,繼承模型,以及 Nginx 如何選擇 server 塊,location 的順序。編程
SSL 安裝 —— 如何配置服務器使用 HTTPS緩存
咱們的目標是建立一系列教程,讓你能夠輕鬆找到特定主題的正確配置,如 gzip、SSL 等,或者直接瀏覽一下那些配置。爲了得到最佳的學習體驗,咱們建議你在本身的機器上安裝 Nginx,並親手實戰一下。服務器
Nginx 最初是做爲一個 Web 服務器建立的,用於解決 C10k 的問題。做爲一個 Web 服務器,它能夠以驚人的速度爲您的數據服務。但 Nginx 不只僅是一個 Web 服務器,你還能夠將其用做反向代理,與較慢的上游服務器(如:Unicorn 或 Puma)輕鬆集成。你能夠適當地分配流量(負載均衡器)、流媒體、動態調整圖像大小、緩存內容等等。負載均衡
基本的 nginx 體系結構由 master 進程和其 worker 進程組成。master 讀取配置文件,並維護 worker 進程,而 worker 則會對請求進行實際處理。dom
要啓動 nginx,只需輸入:編程語言
[sudo] nginx
當你的 nginx 實例運行時,你能夠經過發送相應的信號來管理它:
[sudo] nginx -s signal
可用的信號:
stop – 快速關閉
quit – 優雅關閉 (等待 worker 線程完成處理)
reload – 重載配置文件
reopen – 從新打開日誌文件
nginx 的配置文件,默認的位置包括:
/etc/nginx/nginx.conf,
/usr/local/etc/nginx/nginx.conf,或
/usr/local/nginx/conf/nginx.conf
配置文件的由下面的部分構成:
指令 – 可選項,包含名稱和參數,以分號結尾
gzip on;
上下文 – 分塊,你能夠聲明指令 – 相似於編程語言中的做用域
worker_processes 2; # 全局上下文指令
http { # http 上下文
gzip on; # http 上下文中的指令
server { # server 上下文
listen 80; # server 上下文中的指令
}
}
指令類型
在多個上下文中使用相同的指令時,必需要當心,由於繼承模型不一樣時有着不一樣的指令。有三種類型的指令,每種都有本身的繼承模型。
普通指令
在每一個上下文僅有惟一值。並且,它只能在當前上下文中定義一次。子級上下文能夠覆蓋父級中的值,而且這個覆蓋值只在當前的子級上下文中有效。
gzip on;
gzip off; # 非法,不能在同一個上下文中指定同一普通指令2次
server {
location /downloads {
gzip off;
}
location /assets {
# gzip is on here
}
}
數組指令
在同一上下文中添加多條指令,將添加多個值,而不是徹底覆蓋。在子級上下文中定義指令將覆蓋給父級上下文中的值。
error_log /var/log/nginx/error.log;
error_log /var/log/nginx/error_notive.log notice;
error_log /var/log/nginx/error_debug.log debug;
server {
location /downloads {
# 下面的配置會覆蓋父級上下文中的指令
error_log /var/log/nginx/error_downloads.log;
}
}
行動指令
行動是改變事情的指令。根據模塊的須要,它繼承的行爲可能會有所不一樣。
例如 rewrite 指令,只要是匹配的都會執行:
server {
rewrite ^ /foobar;
location /foobar {
rewrite ^ /foo;
rewrite ^ /bar;
}
}
若是用戶想嘗試獲取 /sample:
server的rewrite將會執行,從 /sample rewrite 到 /foobar
location /foobar 會被匹配
location的第一個rewrite執行,從/foobar rewrite到/foo
location的第二個rewrite執行,從/foo rewrite到/bar
return 指令提供的是不一樣的行爲:
server {
location / {
return 200;
return 404;
}
}
在上述的狀況下,當即返回200。
處理請求
在 Nginx 內部,你能夠指定多個虛擬服務器,每一個虛擬服務器用 server{} 上下文描述。
server {
listen *:80 default_server;
server_name netguru.co;
return 200 "Hello from netguru.co";
}
server {
listen *:80;
server_name foo.co;
return 200 "Hello from foo.co";
}
server {
listen *:81;
server_name bar.co;
return 200 "Hello from bar.co";
}
這將告訴 Nginx 如何處理到來的請求。Nginx 將會首先經過檢查 listen 指令來測試哪個虛擬主機在監聽給定的 IP 端口組合。
而後,server_name 指令的值將檢測 Host 頭(存儲着主機域名)。
Nginx 將會按照下列順序選擇虛擬主機:
匹配sever_name指令的IP-端口主機
擁有default_server標記的IP-端口主機
首先定義的IP-端口主機
若是沒有匹配,拒絕鏈接。
例以下面的例子:
Request to foo.co:80 => "Hello from foo.co"
Request to www.foo.co:80 => "Hello from netguru.co"
Request to bar.co:80 => "Hello from netguru.co"
Request to bar.co:81 => "Hello from bar.co"
Request to foo.co:81 => "Hello from bar.co"
server_name 指令
server_name指令接受多個值。它還處理通配符匹配和正則表達式。
server_name netguru.co www.netguru.co; # exact match
server_name *.netguru.co; # wildcard matching
server_name netguru.*; # wildcard matching
server_name ~^[0-9]*.netguru.co$; # regexp matching
當有歧義時,nginx 將使用下面的命令:
確切的名字
最長的通配符名稱以星號開始,例如「* .example.org」。
最長的通配符名稱以星號結尾,例如「mail.**」
首先匹配正則表達式(按照配置文件中的順序)
Nginx 會存儲 3 個哈希表:確切的名字,以星號開始的通配符,和以星號結尾的通配符。若是結果不在任何表中,則將按順序進行正則表達式測試。
值得謹記的是
server_name .netguru.co;
是一個來自下面的縮寫
server_name netguru.co www.netguru.co *.netguru.co;
有一點不一樣,.netguru.co 存儲在第二張表,這意味着它比顯式聲明的慢一點。
listen 指令
在不少狀況下,可以找到 listen 指令,接受IP:端口值
listen 127.0.0.1:80;
listen 127.0.0.1; # by default port :80 is used
listen *:81;
listen 81; # by default all ips are used
listen [::]:80; # IPv6 addresses
listen [::1]; # IPv6 addresses
然而,還能夠指定 UNIX-domain 套接字。
listen unix:/var/run/nginx.sock;
你甚至可使用主機名
listen localhost:80;
listen netguru.co:80;
但請慎用,因爲主機可能沒法啓動 nginx,致使沒法綁定在特定的 TCP Socket。
最後,若是指令不存在,則使用 *:80。
最小化配置
有了這些知識 – 咱們應該可以建立並理解運行 nginx 所需的最低配置。
# /etc/nginx/nginx.conf
events {} # events context needs to be defined to consider config valid
http {
server {
listen 80;
server_name netguru.co www.netguru.co *.netguru.co;
return 200 "Hello";
}
}
root, location, 和 try_files 指令
root 指令
root 指令設置請求的根目錄,容許 nginx 將傳入請求映射到文件系統。
server {
listen 80;
server_name netguru.co;
root /var/www/netguru.co;
}
根據給定的請求,指定 nginx 服務器容許的內容
netguru.co:80/index.html # returns /var/www/netguru.co/index.html
netguru.co:80/foo/index.html # returns /var/www/netguru.co/foo/index.html
location 指令
location指令根據請求的 URI 來設置配置。
location [modifier] path
location /foo/ {
# ...
}
若是沒有指定修飾符,則路徑被視爲前綴,其後能夠跟隨任何東西。
以上例子將匹配
/foo
/fooo
/foo123
/foo/bar/index.html
...
此外,在給定的上下文中可使用多個 location 指令。
server {
listen 80;
server_name netguru.co;
root /var/www/netguru.co;
location / {
return 200 "root";
}
location /foo/ {
return 200 "foo";
}
}
netguru.co:80 / # => "root"
netguru.co:80 /foo # => "foo"
netguru.co:80 /foo123 # => "foo"
netguru.co:80 /bar # => "root"
Nginx 也提供了一些修飾符,可用於鏈接 location。這些修飾符將影響 location 模塊使用的地方,由於每一個修飾符都分配了優先級。
= - Exact match
^~ - Preferential match
~ && ~* - Regex match
no modifier - Prefix match
Nginx 會先檢查精確匹配。若是找不到,咱們會找優先級最高的。若是這個匹配依然失敗,正則表達式匹配將按照出現的順序進行測試。至少,最後一個前綴匹配將被使用。
location /match {
return 200 'Prefix match: matches everything that starting with /match';
}
location ~* /match[0-9] {
return 200 'Case insensitive regex match';
}
location ~ /MATCH[0-9] {
return 200 'Case sensitive regex match';
}
location ^~ /match0 {
return 200 'Preferential match';
}
location = /match {
return 200 'Exact match';
}
/match/ # => 'Exact match'
/match0 # => 'Preferential match'
/match1 # => 'Case insensitive regex match'
/MATCH1 # => 'Case sensitive regex match'
/match-abc # => 'Prefix match: matches everything that starting with /match'
try_files 指令
嘗試不一樣的路徑,找到一個路徑就返回。
try_files $uri index.html =404;
因此對於 /foo.html 請求,它將嘗試按如下順序返回文件:
$uri ( /foo.html )
index.html
若是什麼都沒找到則返回 404
有趣的是,若是咱們在服務器上下文中定義 try_files,而後定義匹配的全部請求的 location —— try_files 將不會執行。
這是由於在服務器上下文中定義的 try_files 是它的 pseudo-location,這是最不可能的位置。所以,定義 location/ 將比 pseudo-location 更具體。
server {
try_files $uri /index.html =404;
location / {
}
}
所以,你應該避免在 server 上下文中出現 try_files:
server {
location / {
try_files $uri /index.html =404;
}
}