Nginx的代碼是由一個核心和一系列的模塊組成, 核心主要用於提供Web Server的基本功能,以及Web和Mail反向代理的功能;還用於啓用網絡協議,建立必要的運行時環境以及確保不一樣的模塊之間平滑地進行交互。不過,大多跟協議相關的功能和某應用特有的功能都是由nginx的模塊實現的。這些功能模塊大體能夠分爲事件模塊、階段性處理器、輸出過濾器、變量處理器、協議、upstream和負載均衡幾個類別,這些共同組成了nginx的http功能。事件模塊主要用於提供OS獨立的(不一樣操做系統的事件機制有所不一樣)事件通知機制如kqueue或epoll等。協議模塊則負責實現nginx經過http、tls/ssl、smtp、pop3以及imap與對應的客戶端創建會話。javascript
Nginx的核心模塊爲Main和Events,此外還包括標準HTTP模塊、可選HTTP模塊和郵件模塊,其還能夠支持諸多第三方模塊。Main用於配置錯誤日誌、進程及權限等相關的參數,Events用於配置IO模型,如epoll、kqueue、select或poll等,它們是必備模塊。php
Nginx的主配置文件由幾個段組成,這個段一般也被稱爲nginx的上下文,每一個段的定義格式以下所示。須要注意的是,其每個指令都必須使用分號(;)結束,不然爲語法錯誤。css
<section> {html
<directive><parameters>;java
}nginx
user username [groupname]; 指定運行worker進程的用戶和組 web
worker_processes 4; worker進程的個數;一般其數值應該爲CPU的物理核心數減1,默認爲4正則表達式
error_log /path/to/error_log level [ debug | info | notice | warn | error | crit | alert | emerg ]; 錯誤日誌文件及其級別,默認爲error級別,錯誤日誌在全局級別,訪問日誌在虛擬主機級別,調試時可使用debug級別,但要求在編譯時必須使用–with-debug啓用debug功能;算法
pid /path/to/pidfile_name; 指定nginx的pid文件apache
nginx安裝完成後,全局塊默認只有這幾個配置。
events {
use epoll;定義使用的事件驅動模型,建議讓nginx自動選擇,默認使用epoll
worker_connections 1024;每一個worker可以併發響應最大請求數,默認爲1024
}
nginx 在events只配置此兩個選項;
下面介紹 http 塊的配置,http塊的配置比較多,用法也比較靈活,如下是比較經常使用的配置。
http {
.....
server{
......
location {
......
}
}
server{
......
location {
......
}
}
}
nginx和httpd虛擬主機使用的實現同樣,都有基於端口,IP,域名的虛擬機主機。要爲nginx配置虛擬主機,只需在http塊中額外定義一個server塊。
1,配置基於端口的虛擬主機時,只需修改listen中的端口號。
http{
server {
listen80;
server_name a.com;
。。。。。。
}
server {
listen8080;
server_name b.org;
。。。。。。
}
}
2,配置基於域名的虛擬主機
http{
server {
listen80;
server_name a.com;
。。。。。。
}
server {
listen80;
server_name b.org;
。。。。。。
}
}
3,配置基於IP的虛擬主機
http{
server {
listen192.168.1.110:80;
server_name a.com;
。。。。。。
}
server {
listen192.168.1.111:80;
server_name b.org;
。。。。。。
}
}
自上而下進行檢查,能夠在 http, server, location, limit_except 中配置,與httpd中的配置相似。
語法:allow|denyaddress | CIDR | unix:| all;
location /{
root /usr/html ;
indexindex.html index.htm;
allow172.16.100.8;
allow 192.168.0.0/16;
allow 10.1.1.0/16;
denyall;
}
此配置是爲了禁止外人訪問特定頁面時進行的限制,須要藉助於httpd的htpasswd建立密碼文件。
語法:auth_basic string| off;
auth_basic_user_file file;
例:
location /server {
root/usr/html ;
access_log off; #訪問日誌
auth_basic "amdin area";#認證時的說明
auth_basic_user_file /etc/nginx/.htpasswd; #密碼文件所在位置
}
此模塊爲了便於用戶下載站的文件等,相似於ftp的功能,本站的ftp依是如此。
location /{
root html/ftp;
allow all;
autoindex on; #激活/關閉自動索引
autoindex_exact_size on; #設定索引時文件大小的單位(B,KB, MB 或 GB)
autoindex_localtime on; #開啓以本地時間來顯示文件時間的功能。默認爲關(GMT時間)
}
防盜鏈是爲了防止別的網站盜用本身網站的圖片視頻等資源,並給本身網站的服務器形成額外的負擔。nginx使用valid_referers 指令進行配置防盜鏈規則。
(1) 定義合規的引用
valid_referers none | blocked | server_names | string …;
none : 檢測referer頭域不存在的狀況
blocked:檢測referer頭域的值被防火牆或者代理服務器刪除或者假裝的狀況。這種狀況下該頭域的值不以http或者https開頭。
server_names : 設置一個或多個URL,可使用統配符 * 。
(2) 拒毫不合規的引用
if ($invalid_referer){
rewrite ^/.*$ http://www.b.org/403.html
}
示例:
location ~* \.(gif|jpg|png|swf|flv|rar|zip)$
{
root /usr/html/htdocs;
valid_referers none blocked server_names *.yangliheng.com;
if($invalid_referer){
rewrite ^/ http://www.yangliheng.com/wp-content/uploads/2016/01/QQ圖片20160131111643.png;
}
}
rewrite用於實現URI的重寫,須要pcre的支持。
rewrite指令執行順序:
1.執行server塊的rewrite指令(這裏的塊指的是server關鍵字後{}包圍的區域,其它xx塊相似)
2.執行location匹配
3.執行選定的location中的rewrite指令
若是其中某步URI被重寫,則從新循環執行1-3,直到找到真實存在的文件
若是循環超過10次,則返回500 Internal Server Error錯誤.
rewrite regex replacement [flag];
location /{
root /www/b.org; #每次被rewrite匹配並結束後,都要從新發送請求並再次到location中進行匹配,如有break則直接響應,再也不發送新請求
rewrite ^/images/(.*)$ /imgs/$1 last;
}
請求順序:http://www.b.org/images/a.jpg –> http://www.b.org/imgs/a.jpg
last: 一旦被當前規則匹配並重寫後當即中止檢查後續的其它rewrite的規則,然後經過重寫後的規則從新發起請求;
break: 一旦被當前規則匹配並重寫後當即中止後續的其它rewrite的規則,然後繼續由nginx進行後續操做;
redirect: 返回302臨時重定向;
permanent: 返回301永久重定向;
location /download/ {
rewrite ^(/download/.*)/media/(.*)\..*$ $1/media/$2.mp3 break;
}
此處若爲last,則nginx最多循環10次,超出以後會返回500錯誤;
注意:通常將rewrite寫在location中時都使用break標誌,或者將rewrite寫在if上下文中;
rewrite_log on|off; 是否把重寫過程記錄在錯誤日誌中;默認爲notice級別;默認爲off;
return code;用於結束rewrite規則,而且爲客戶返回狀態碼;可使用的狀態碼有204, 400, 402-406, 500-504等;
server_status是nginx內建的一個狀態頁,用以瞭解nginx的狀態。
location /status {
stub_status on;
access_log off;
auth_basic "amdin area";
auth_basic_user_file /etc/nginx/.htpasswd;
allow 192.168.0.0/16;
deny all;
}
Active connections: 2
server accepts handled requests
237811 172308 244762
Reading: 0 Writing: 1 Waiting: 1
其意義分別爲:
active connections – 活躍的鏈接數量
accepts:接受鏈接數;handled:已經創建的鏈接數;requests :經過創建的鏈接處理的請求的總數;
Reading:正在接受的新鏈接數;Writing:響應數據到客戶端的數量;Waiting:長鏈接中處於活動狀態的個數
nginx 將響應報文發送至客戶端以前能夠啓用壓縮功能,這可以有效地節約帶寬,並提升響應至客戶端的速度。一般編譯nginx默認會附帶gzip壓縮的功能,所以,能夠直接啓用之。
http {
gzip on;
gzip_min_length 1024; #響應也數據上限
gzip_buffers 416k; #緩存空間大小
gzip_comp_level 2; #定義壓縮等級,默認爲6,壓縮比越大,效率越低
gzip_types text/plain application/x-javascript application/xml text/css; #壓縮文件類型
gzip_vary on; #啓用壓縮標識
gzip_static on; #靜態壓縮
}
gzip_proxied指令能夠定義對客戶端請求哪類對象啓用壓縮功能,如「expired」表示對因爲使用了expire首部定義而沒法緩存的對象啓用壓縮功能,其它可接受的值還有「no-cache」、「no-store」、「private」、「no_last_modified」、「no_etag」和「auth」等,而「off」則表示關閉壓縮功能。
Nginx經過proxy模塊實現反向代理功能。在做爲web反向代理服務器時,nginx負責接收客戶請求,並可以根據URI、客戶端參數或其它的處理邏輯將用戶請求調度至上游服務器上(upstream server)。nginx在實現反向代理功能時的最重要指令爲proxy_pass,它可以將location定義的某URI代理至指定的上游服務器(組)上。以下面的示例中,location的/uri將被替換爲上游服務器上的/newuri。
location /uri {
proxy_pass http://www.yangliheng.com:8080/newuri;
}
不過,這種處理機制中有兩個例外。一個是若是location的URI是經過模式匹配定義的,其URI將直接被傳遞至上游服務器,而不能爲其指定轉換的另外一個URI。例以下面示例中的/forum將被代理爲http://www.yangliheng.com/forum。
location ~^/forum {
proxy_pass http://www.yangliheng.com;
proxy_set_header X-Real-IP $remote_addr;
}
將URI傳遞給後端服務器後,後端服務器日誌中記錄的訪問IP爲代理服務器的IP,要在後端服務器中記錄真實IP,須要修改日誌記錄格式,將%h改成 %{X-Real-IP}i ,i表示引用某個參數的值
#LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
LogFormat"%{X-Real-IP}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
第二個例外是,若是在loation中使用的URL重定向,那麼nginx將使用重定向後的URI處理請求,而再也不考慮上游服務器上定義的URI。以下面所示的例子中,傳送給上游服務器的URI爲/index.php?page=,而不是/index。
location /{
rewrite /(.*)$ /index.php?page=$1 break;
proxy_pass http://localhost:8080/index;
}
proxy模塊的指令
proxy模塊的可用配置指令很是多,它們分別用於定義proxy模塊工做時的諸多屬性,如鏈接超時時長、代理時使用http協議版本等。下面對經常使用的指令作一個簡單說明。
proxy_connect_timeout:nginx將一個請求發送至upstream server以前等待的最大時長;
proxy_cookie_domain:將upstream server經過Set-Cookie首部設定的domain屬性修改成指定的值,其值能夠爲一個字符串、正則表達式的模式或一個引用的變量;
proxy_cookie_path: 將upstream server經過Set-Cookie首部設定的path屬性修改成指定的值,其值能夠爲一個字符串、正則表達式的模式或一個引用的變量;
proxy_hide_header:設定發送給客戶端的報文中須要隱藏的首部;
proxy_pass:指定將請求代理至upstream server的URL路徑;
proxy_set_header:將發送至upsream server的報文的某首部進行重寫;
proxy_redirect:重寫location並刷新從upstream server收到的報文的首部;
proxy_send_timeout:在鏈接斷開以前兩次發送至upstream server的寫操做的最大間隔時長;
proxy_read_timeout:在鏈接斷開以前兩次從接收upstream server接收讀操做的最大間隔時長;
實例1:
server{
......
location /server/{
.......
proxy_pass http://192.168.1.111;
}
}
server{
......
location /server/{
.......
proxy_pass http://192.168.1.111/loc/;
}
}
對於這兩個配置,當客戶端請求http://www.yangliheng.com/server/時,第一個因爲proxy_pass的URL中不包含uri,因此請求被轉發到http://192.168.1.111/server/;可是第二個proxy_pass的URL中包含了uri 「/loc/」,因此請求會被轉發到http://192.168.1.111/loc/。因此,在使用proxy_pass指令時,若是不想改變原地址中的URI,就不要再URL中配置URI。
實例2:
server{
......
location /server/{
.......
#配置1 proxy_pass http://192.168.1.111;
#配置2 proxy_pass http://192.168.1.111/;
}
}
當客戶端清求URL爲http://www.yangliheng.com/server/時,因爲配置的URL未包含URI,nginx服務器不會改變原地址URI;當使用配置2時,因爲配置的URL包含URI「/」,nginx服務器會將原地址的URI替換爲「/」。
與proxy模塊結合使用的模塊中,最經常使用的當屬upstream模塊。upstream模塊可定義一個新的上下文,它包含了一組upstream服務器,這些服務器可能被賦予了不一樣的權重、不一樣的類型甚至能夠基於維護等緣由被標記爲down。
upstream模塊的負載均衡算法主要有三種,輪調(round-robin)、ip哈希(ip_hash)和最少鏈接(least_conn)三種。
ip_hash:基於客戶端IP地址完成請求的分發,它能夠保證來自於同一個客戶端的請求始終被轉發至同一個upstream服務器;
keepalive:每一個worker進程爲發送到upstream服務器的鏈接所緩存的個數;
least_conn:最少鏈接調度算法;
server:定義一個upstream服務器的地址,還可包括一系列可選參數,如:
weight:權重;
max_fails:最大失敗鏈接次數,失敗鏈接的超時時長由fail_timeout指定;
fail_timeout:等待請求的目標服務器發送響應的時長;
backup:用於fallback的目的,全部服務均故障時才啓動此服務器;
down:手動標記其再也不處理任何請求;
例,使用upstream並定義error頁面,當upstream中的後端服務器都fail時,則返回到127.0.0.1:8080下。
upstream webservs{
server 192.168.1.116 weight=1 max_fails=2 fail_timeout=2;
server 192.168.1.109 weight=1 max_fails=2 fail_timeout=2;
server 127.0.0.1:8080 backup;
}
server {
listen 8080;
server_name localhost;
location /{
root /web/errorpage;
index index.html;
}
}
爲了保持session信息讓同一客戶端定向到同一服務器,使用ip_hash算法,在ip_hash狀況下不讓使用backup,也不能定義weight。可是使用ip_hash會破壞負載均衡的效果。
upstream webservs{
ip_hash;
server 192.168.1.116 max_fails=2 fail_timeout=2;
server 192.168.1.109 max_fails=2 fail_timeout=2;
#server 127.0.0.1:8080 backup;
}
此外,upstream模塊也能爲非http類的應用實現負載均衡,以下面的示例定義了nginx爲memcached服務實現負載均衡之目的。
upstream memcachesrvs {
server 172.16.100.6:11211;
server 172.16.100.7:11211;
}
server {
location /{
set $memcached_key "$uri?$args";
memcached_pass memcachesrvs;
error_page 404=@fallback;
}
location @fallback{
proxy_pass http://127.0.0.1:8080;
}
}
在location中使用if語句能夠實現條件判斷,其一般有一個return語句,且通常與有着last或break標記的rewrite規則一同使用。但其也能夠按須要使用在多種場景下,須要注意的是,不當的使用可能會致使不可預料的後果。
location /{
if($request_method ==「PUT」){
proxy_pass http://upload.yangliheng.com:8080;
}
if($request_uri ~"\.(jpg|gif|jpeg|png)$"){
proxy_pass http://imageservers;
break;
}
}
upstream imageservers {
server 172.16.100.8:80 weight 2;
server 172.16.100.9:80 weight 3;
}
if語句中的判斷條件
正則表達式匹配:
==: 等值比較;
~:與指定正則表達式模式匹配時返回「真」,判斷匹配與否時區分字符大小寫;
~*:與指定正則表達式模式匹配時返回「真」,判斷匹配與否時不區分字符大小寫;
!~:與指定正則表達式模式不匹配時返回「真」,判斷匹配與否時區分字符大小寫;
!~*:與指定正則表達式模式不匹配時返回「真」,判斷匹配與否時不區分字符大小寫;
文件及目錄匹配判斷:
-f, !-f:判斷指定的路徑是否爲存在且爲文件;
-d, !-d:判斷指定的路徑是否爲存在且爲目錄;
-e, !-e:判斷指定的路徑是否存在,文件或目錄都可;
-x, !-x:判斷指定路徑的文件是否存在且可執行;
nginx在默認狀況下在將其響應給客戶端以前會盡量地接收來upstream服務器的響應報文,它會將這些響應報文存暫存於本地並儘可能一次性地響應給客戶端。然而,在來自於客戶端的請求或來自upsteam服務器的響應過多時,nginx會試圖將之存儲於本地磁盤中,這將大大下降nginx的性能。所以,在有着更多可用內存的場景中,應該將用於暫存這些報文的緩衝區調大至一個合理的值。
proxy_buffer_size size:設定用於暫存來自於upsteam服務器的第一個響應報文的緩衝區大小;
proxy_buffering on|off:啓用緩衝upstream服務器的響應報文,不然,若是proxy_max_temp_file_size指令的值爲0,來自upstream服務器的響應報文在接收到的那一刻將同步發送至客戶端;通常狀況下,啓用proxy_buffering並將proxy_max_temp_file_size設定爲0可以啓用緩存響應報文的功能,並可以避免將其緩存至磁盤中;
proxy_buffers 8 4k|8k:用於緩衝來自upstream服務器的響應報文的緩衝區大小;
nginx作爲反向代理時,可以未來自upstream的響應緩存至本地,並在後續的客戶端請求一樣內容時直接從本地構造響應報文。
proxy_cache zone|off:定義一個用於緩存的共享內存區域,其可被多個地方調用;緩存將聽從upstream服務器的響應報文首部中關於緩存的設定,如 「Expires」、」Cache-Control: no-cache」、 「Cache-Control: max-age=XXX」、」private」和」no-store」 等,但nginx在緩存時不會考慮響應報文的」Vary」首部。爲了確保私有信息不被緩存,全部關於用戶的私有信息能夠upstream上經過」no-cache」 or 「max-age=0″來實現,也可在nginx設定
proxy_cache_key:設定在存儲及檢索緩存時用於「鍵」的字符串,可使用變量爲其值,但使用不當時有可能會爲同一個內容緩存屢次;另外,將用戶私有信息用於鍵能夠避免將用戶的私有信息返回給其它用戶;
proxy_cache_lock:啓用此項,可在緩存未命令中阻止多個相同的請求同時發往upstream,其生效範圍爲worker級別;
proxy_cache_lock_timeout:proxy_cache_lock功能的鎖定時長;
proxy_cache_min_uses:某響應報文被緩存以前至少應該被請求的次數;
proxy_cache_path:定義一個用於保存緩存響應報文的目錄,及一個保存緩存對象的鍵及響應元數據的共享內存區域(keys_zone=name:size),其可選參數有:
levels:每級子目錄名稱的長度,有效值爲1或2,每級之間使用冒號分隔,最多爲3級;
inactive:非活動緩存項從緩存中剔除以前的最大緩存時長;
max_size:緩存空間大小的上限,當須要緩存的對象超出此空間限定時,緩存管理器將基於LRU算法對其進行清理;
loader_files:緩存加載器(cache_loader)的每次工做過程最多爲多少個文件加載元數據;
loader_sleep:緩存加載器的每次迭代工做以後的睡眠時長;
loader_threashold:緩存加載器的最大睡眠時長;
例如: proxy_cache_path /data/nginx/cache/one levels=1 keys_zone=one:10m;
proxy_cache_use_stale:在沒法聯繫到upstream服務器時的哪一種情形下(如error、timeout或http_500等)讓nginx使用本地緩存的過時的緩存對象直接響應客戶端請求;其格式爲:
proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 | http_504 | http_404 | off
proxy_cache_valid [ code …] time:用於爲不一樣的響應設定不一樣時長的有效緩存時長,例如:proxy_cache_valid 200 302 10m;
proxy_cache_methods [GET HEAD POST]:爲哪些請求方法啓用緩存功能;
proxy_cache_bypass string:設定在哪一種情形下,nginx將不從緩存中取數據;例如:
proxy_cache_bypass $cookie_nocache $arg_nocache $arg_comment;
proxy_cache_bypass $http_pragma $http_authorization;
例:
http{
。。。。。。
upstream websrvs {
server 172.16.100.11 weight=1;
server 172.16.100.12 weight=1;
server 127.0.0.1:8080 backup;
}
proxy_cache_path /nginx/cache/first levels=1:2 keys_zone=first:20m max_size=1G;
add_header X-Cache"$upstream_cache_status from $server_addr";#顯示緩存從哪一個服務器命中
location /{
proxy_pass http://webservs;
proxy_set_header X-Real-IP $remote_addr;
proxy_cache first;
proxy_cache_valid 20010m;
proxy_cache_valid any 1m;
}
}
nginx的限速功能經過limit_zone、limit_conn和limit_rate指令進行配置。首先須要在http上下文配置一個limit_zone,而後在須要的地方使用limit_conn和limit_rate 進行限速設置。下面是一個簡單的例子。
http {
limit_conn_zone $binary_remote_addr zone=perip:10m;
server {
location /downloads/{
limit_conn perip1;
limit_rate 50k;
}
}
}
說明:
limit_zone:語法格式「limit_req_zone $variable zone=name:size rate=rate;」,實現針對每一個IP定義一個存儲session狀態的容器。這個示例中定義了一個名叫first的10m大小的容器,這個名字會在後面的limit_conn中使用。
limit_conn first 1; 限制在first中記錄狀態的每一個IP只能發起一個併發鏈接。
limit_rate 50k; 對每一個鏈接限速50k. 注意,這裏是對鏈接限速,而不是對IP限速。若是一個IP容許三個併發鏈接,那麼這個IP就是限速爲limit_rate×3,在設置的時候要根據本身的須要作設置調整,要否則會達不到本身但願的目的。
限制鏈接數的配置以下所示。
limit_conn_zone $binary_remote_addr zone=perip:10m;
limit_conn_zone $server_name zone=perserver:10m;
server {
...
limit_conn perip 10;
limit_conn perserver 100;
}
使用nginx實現讀寫分離時,nginx做爲代理服務器,將文件上傳至upstream中特定的服務器,upstream 端的服務器使用httpd,而且須要啓用dav功能。
配置nginx端:
http{
......
location /{
proxy_pass http://webservs;
if($request_method ="PUT"){
proxy_pass http://192.168.1.109;
}
}
}
在容許上傳的服務器的Directory中啓用上傳功能:
LoadModule dav_module modules/mod_dav.so
LoadModule dav_fs_module modules/mod_dav_fs.so #這兩個模塊須要啓用,默認爲啓用
<Directory"/var/www/html">
Dav on #啓用上傳
......
</Directory>
[root@localhost html]# service httpd reload
[root@localhost html]# chown -R apache.apache /var/www/html/
[root@localhost html]# curl -T /etc/issue 192.168.1.117 #上傳文件
%Total %Received%Xferd AverageSpeed Time Time Time Current
Dload Upload Total Spent Left Speed
0 47 0 0 0 0 0 0--:--:----:--:----:--:-- 0<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>201Created</title>
</head><body>
<h1>Created</h1>
<p>Resource /issue has been created.</p>
<hr />
<address>Apache/2.2.15(CentOS)Server at webservs Port80</address>
</body></html>
100 301 127 254 0 47 4527 837--:--:----:--:----:--:-- 4618
而後使用rsync+inotify或者sersync+inotify同步upstream中的其餘服務器。