Nginx("engine x")是一個IMAP/POP3/SMTP代理服務器,也是一個高性能的 HTTP 和 反向代理服務器,但如今大多數狀況下都是用來作靜態web服務器和反向代理服務器,在做爲反向代理服務器的時候,Nginx能夠對後端的real server作負載均衡,基於應用層的負載均衡,可是他僅支持一些常見的協議,如:http ,mysql, ftp, smtp.javascript
相較apache來講,Nginx在靜態web,反向代理,性能,高併發等功能上比apache要強大,可是apache在穩定性,動態網站的方面比Nginx優秀.隨着互聯網的規模愈來愈大,apache已經解決不了C10k(併發訪問量超過10k)的問題了,因此出現了新的應用程序,就如Nginx,目前Nginx的穩定版是1.4.*系列.css
Nginx的特性:html
基本功能:java
靜態資源的web服務器,能緩存打開的文件描述符node
能夠作反向代理服務器,緩存,負載均衡mysql
支持FastCGInginx
靜態模塊化機制,非DSO機制,支持多種過濾器,如gzip,SSI和圖像大小調整等web
支持SSL正則表達式
擴展功能:算法
支持基於名稱和IP作虛擬主機
支持keepalive
支持平滑的升級,平滑的配置文件更新
支持定製訪問日誌,支持日誌緩存以提升性能
支持url rewrite
支持路徑別名
支持基於IP和用戶認證
支持速率限制,併發限制
Nginx的基本架構
Nginx會啓動一個master進程和多個worker線程/進程,每一個worker進程能夠響應多個請求,啓動的worker數量能夠自行設置,通常而言,設置的worker數量應該比cpu的核心數少一到兩個,如24個核心的cpu,應該設置22-23個worker進程數,Nginx是基於事件驅動:kqueue,epoll(Linux),/dev/poll,也支持消息通知機制:select,poll,rt signals;支持sendfile:服務器響應請求時,由內核直接響應,而不用通過用戶空間.支持文件AIO,異步IO,支持mmap,內存映射.
Nginx的模塊,這裏只介紹http模塊
Nginx是高度模塊化的程序,其中包含Nginx的核心模塊(編譯時默認都安裝),http的標準模塊以及http的可選模塊
Nginx的核心模塊配置內別
核心段
1: #user nobody; #以哪一個用戶的身份運行worker進程,2: worker_processes 1; #啓動的worker的數量,性能優化關鍵點3:4: #error_log logs/error.log; #錯誤日誌文件及其級別;默認爲error級別;調試時可使用debug級別,但要求在編譯時必須使用--with-debug啓用debug功能;5: #error_log logs/error.log notice; #同上,可是級別爲notice
6: #error_log logs/error.log info; #同上,可是級別爲 info
7:8: #pid logs/nginx.pid; #指定Nginx的pid文件9:10:11: events { #12: worker_connections 1024; #worker進程的個數;一般其數值應該爲CPU的物理核心數減1或減2;Nginx的最大併發數爲worker_processes*worker_connections13: }14: ----------------------如下都是默認不存在的配置-------------------------15: -------性能優化相關-------16:17: worker_rlimit_nofile 9999; #指定一個worker進程所可以打開的最大文件句柄數,可使用ulimit -n查看單個文件能夠打開的最大句柄數,(socket鏈接也算在裏面)。系統默認值1024,此值需大於等於worker_connections,可是若是是代理服務器,此值應大於等於worker_connections的兩倍18: worker_rlimit_sigpending 12; #設定每一個用戶可以發往worker進程的信號的數量19: worker_cpu_affinity cpumask; #與上面的worker_processes有關,讓worker運行在指定的cpu上,若有4顆cpu,4個process,那就分別是0001,0010,0100,1000,表示第0,1,2,3顆cpu,性能優化關鍵點20: ssl_engine ssldevice; #在存在ssl硬件加速器的服務器上,指定所使用的ssl硬件加速設備;21: timer_resolution t; #每次內核事件調用返回時,都會使用gettimeofday()來更新nginx緩存時鐘;timer_resolution用於定義每隔多久纔會由gettimeofday()更新一次緩存時鐘;x86-64系統上,gettimeofday()代價已經很小,能夠忽略此配置;22: worker_priority number; #worker的優先級,值越小,優先級越高,對於性能的加強也是很關鍵的(-20,20),默認是0,對系統的性能加強很關鍵23: -------事件相關-----------24: 須要定義在 events { } 裏面25: accept_mutex [on|off]; #是否打開Ningx的負載均衡鎖;此鎖可以讓多個worker進輪流地、序列化地與新的客戶端創建鏈接;而一般當一個worker進程的負載達到其上限的7/8,master就儘量再也不將請求調度此worker;默認爲on
26: lock_file /path/to/lock_file; #這是accept_mutex的鎖文件,若是accept_mutex爲off,這項就沒用了
27: accept_mutex_delay #ms; #在accept鎖模式中,一個worker進程爲取得accept鎖的等待時長;若是某worker進程在某次試圖取得鎖時失敗了,至少要等待#ms才能再一次請求鎖;默認是500毫秒28: multi_accept on|off; #是否容許worker一次性地響應多個用戶請求;默認爲Off,一個鏈接一個鏈接的創建;
29: use [epoll|rtsig|select|poll]; #定義使用的事件模型,建議讓nginx自動選擇;在Linux中通常(默認)都選擇epoll
30: ------用於調試、定位問題--31: 只在調試時使用32: daemon on|off; #是否讓ningx運行後臺;默認爲on,調試時能夠設置爲off,使得全部信息去接輸出控制檯;
33: master_process on|off; #是否以master/worker模式運行nginx;默認爲on;調試時可設置off以方便追蹤;
http段
1: ----主要有三段:http段,server段,location段-------2: http {3: include mime.types;4: default_type application/octet-stream;5:6: #log_format main '$remote_addr - $remote_user [$time_local] "$request" '
7: # '$status $body_bytes_sent "$http_referer" '
8: # '"$http_user_agent" "$http_x_forwarded_for"';
9:10: #access_log logs/access.log main;11:12: sendfile on;
13: #tcp_nopush on;
14:15: #keepalive_timeout 0;16: keepalive_timeout 65;17:18: #gzip on;
19:20: server { #定義虛擬主機21: listen 80; #監聽的端口listen address[:port];listen port22: server_name localhost; #定義基於主機名或IP的虛擬主機,可跟多個主機名23: server_name_hash_bucket_size #快速主機名查找使用hash主機名24:25: #charset koi8-r;26:27: #access_log logs/host.access.log main;28:29: location / {30: root html; #設置web資源的路徑,能夠放在http,server和location中31: index index.html index.htm; #定義默認主頁,自左向右匹配32: }33:34: #error_page 404 [=200] /404.html; #錯誤頁面重定向,[=200表示請求狀態碼也編程200]35: # redirect server error pages to the static page /50x.html36: #37: error_page 500 502 503 504 /50x.html;38: location = /50x.html {39: root html;40: }41: }42: -----詳細說明-------43: listen #僅能在server段44: listen address[:port];45: listen port46: default_server:定義此server爲http中默認的server;若是全部的server中沒有任何一個listen使用此參數,那麼第一個server即爲默認server;47: rcvbuf=SIZE: 接收緩衝大小;48: sndbuf=SIZE: 發送緩衝大小;49: ssl: https server;50: server_name [...];51: server_name能夠跟多個主機名,名稱中可使用通配符和正則表達式(一般以~開頭);當nginx收到一個請求時,會取出其首部的server的值,然後跟衆server_name進行比較;比較方式:52: (1) 先作精確匹配;www.magedu.com53: (2) 左側通配符匹配;*.magedu.com54: (3) 右側通配符匹配;www.abc.com, www.*55: (4) 正則表達式匹配: ~^.*\.magedu\.com$56: server_name_hash_bucket_size 32|64|128;57: 爲了實現快速主機查找,nginx使用hash表來保存主機名;系統默認沒有此項,也不是過重要58: ---------如下均爲location中的參數------59: location [ = | ~ | ~* | ^~ ] uri { ... } 只能在server和location中,一個server中能夠有多個location60: location @name { ... }61: 功能:容許根據用戶請求的URI來匹配指定的各location以進行訪問配置;匹配到時,將被location塊中的配置所處理;好比:http://www.magedu.com/images/logo.gif /images/logo.gif/就是URI62: =:精確匹配;優先級最高63: ~:正則表達式模式匹配,匹配時區分字符大小寫64: ~*:正則表達式模式匹配,匹配時忽略字符大小寫65: ^~: URI前半部分匹配,不檢查正則表達式66: 讓咱們用一個例子解釋上面的說法:67: location = / {68: [ configuration A ]69: }70:71: location / {72: [ configuration B ]73: }74:75: location /documents/ {76: [ configuration C ]77: }78:79: location ^~ /images/ {80: [ configuration D ]81: }82:83: location ~* \.(gif|jpg|jpeg)$ {84: [ configuration E ]85: }86: 請求「/」匹配配置A, 請求「/index.html」匹配配置B, 請求「/documents/document.html」匹配配置C, 請求「/images/1.gif」匹配配置D, 請求「/documents/1.jpg」匹配配置E。87:88: 1.alias path
89: 只能用於location中,用於路徑別名;90: location /i/ {91: alias /data/w3/images/;
92: }93: 「訪問/i/top.gif時」將由/data/w3/images/top.gif文件來響應。94: 2.try_files path1 [path2 ...] uri;自左至右嘗試讀取由path所指定路徑,在第一次找到即中止並返回;若是全部path均不存在,則返回最後一個uri;95: location ~* ^/documents/(.*)$ {96: root /www/htdocs;97: try_files $uri /docu/$1 /temp.html;98: }
網絡鏈接相關的設置
1: keepalive_timeout time; #保持鏈接的超時時長;默認爲75秒;能夠定義在http, server, location中2: keepalive_requests n; #在一次長鏈接上容許承載的最大請求數;上下文:http,server,location3: keepalive_disable [msie6 | safari | none ]; #對指定的瀏覽器禁止使用長鏈接;有些瀏覽器不支持長鏈接4: tcp_nodelay on|off; #對keepalive鏈接是否使用TCP_NODELAY選項;默認on;把多個確認報文合成一個響應,確認延遲
5: client_header_timeout time; #讀取http請求首部的超時時長;6: client_body_timeout time; #讀取http請求包體的超時時長;7: send_timeout time; #發送響應的超時時長;
對客戶端請求的限制:
1: limit_except method ... { ... } #指定對範圍以外的其它方法的訪問控制;指定method爲GET方法的同時,nginx會自動添加HEAD方法。上下文:location2: 如: limit_except GET {
3: allow 192.168.1.0/32;4: deny all;5: }6: 請留意上面的例子將對除GET和HEAD方法之外的全部HTTP方法的請求進行訪問限制。7: client_max_body_size SIZE; #http請求包體的最大值;經常使用於限定客戶所可以請求的最大包體;根據請求首部中的Content-Length來檢測,以免無用的傳輸;上下文: http, server, location8: limit_rate speed; #限制客戶端每秒鐘傳輸的字節數;默認爲0,表示沒有限制;上下文:http, server, location, if in location9: limit_rate_after time; #nginx向客戶發送響應報文時,若是時長超出了此處指定的時長,則後續的發送過程開始限速;如:下載站上下文: http, server, location, if in location
文件操做的優化
1: sendfile on|off是否啓用sendfile功能;由內核直接響應用戶請求,默認off上下文:http, server, location, if in location2: aio on|off是否啓用aio功能;徹底異步
3: open_file_cache max=N [inactive=time]|off是否打開文件緩存功能;上下文: http, server, location4: max: 緩存條目的最大值;當滿了之後將根據LRU(最近最少使用)算法進行置換;5: inactive: 某緩存條目在指定時長時沒有被訪問過期,將自動被刪除;默認爲60s;6: 緩存的信息包括:7: 文件句柄、文件大小和上次修改時間;8: 已經打開的目錄結構;9: 沒有找到或沒有訪問權限的信息;10: open_file_cache_errors on|off是否緩存文件找不到或沒有權限訪問等相關信息;默認off;上下文:http, server, location
11: open_file_cache_valid time;多長時間檢查一次緩存中的條目是否超出非活動時長,默認爲60s; 上下文:http, server, location12: open_file_cache_min_use #;在inactive指定的時長內被訪問超此處指定的次數地,纔不會被刪除;默認1分鐘;上下文:http, server, location
對客戶端請求的特殊處理
1: ignore_invalid_headers on|off是否忽略不合法的http首部;默認爲on; off意味着請求首部中出現不合規的首部將拒絕響應;只能用於server和http;
2: log_not_found on|off; 是否將文件找不到的信息也記錄進錯誤日誌中;默認爲on;上下文:http, server, location
3: resolver address; 指定nginx使用的dns服務器地址;上下文: http, server, location4: resover_timeout time;指定DNS解析超時時長,默認爲30s,建議5秒??; 上下文:http, server, location5: server_tokens on|off;是否在錯誤頁面中顯示nginx的版本號;默認on,上下文: http, server, location
http核心模塊的內置變量:
1: $uri: #當前請求的uri,不帶參數;參數 ?=12等之類的2: $request_uri: #請求的uri,帶完整參數;3: $host: #http請求報文中host首部;若是請求中沒有host首部,則以處理此請求的虛擬主機的主機名代替;4: $hostname: #nginx服務運行在的主機的主機名;5: $remote_addr: #客戶端IP6: $remote_port: #客戶端Port7: $remote_user: #使用用戶認證時客戶端用戶輸入的用戶名;8: $request_filename: #用戶請求中的URI通過本地root或alias轉換後映射的本地的文件路徑;用的不少9: $request_method: #請求方法10: $server_addr: #服務器地址11: $server_name: #服務器名稱12: $server_port: #服務器端口13: $server_protocol: #服務器向客戶端發送響應時的協議,如http/1.1, http/1.014: $scheme: #在請求中使用scheme, 如https://www.magedu.com/中的https;15: $http_HEADER: #匹配請求報文中指定的HEADER,$http_host匹配請求報文中的host首部16: $sent_http_HEADER: #匹配響應報文中指定的HEADER,例如$http_content_type匹配響應報文中的content-type首部;17: $document_root: #當前請求映射到的root配置;
配置使用nginx:
nginx虛擬主機
1: server {2: listen 80;3: server_name www.a.com;4: root /web/a5: }
訪問控制access模塊,它只有兩個選項 allow和deny
1: server {2: listen 80;3: server_name www.b.org;4: root /web/b;5:6: allow 192.168.0.0/16;7: deny all;8: }
用戶認證示例
1: location /admin/ {2: auth_basic "admin";
3: auth_basic_user_file /etc/nginx/.htpasswd;4: root /web/b/;5: }6: 使用htpasswd -c -m /path/to/somefile username 建立密碼文件
創建下載站點autoindex,只需autoindex爲on就好了,在/web/b/down目錄下的不可識別的文件都會被以列表的形式列出來
1: location /down/ {2: autoindex on;
3: root /web/b/;4: }5:
防盜鏈
1: 該指令的參數能夠爲下面的內容:2:3: none # 缺乏「Referer」請求頭;4: blocked # 「Referer」 請求頭存在,可是它的值被防火牆或者代理服務器刪除; 這些值都不以「http://」 或者 「https://」字符串做爲開頭;5: server_names # 「Referer」 請求頭包含某個虛擬主機名;6: 任意字符串 # 定義一個服務器名和可選的URI前綴。服務器名容許在開頭或結尾使用「*」符號。 當nginx檢查時,「Referer」請求頭裏的服務器端口將被忽略。7: 正則表達式 # 必須以「~」符號做爲開頭。 須要注意的是表達式會從「http://」或者「https://」以後的文本開始匹配。8:9: ngx_http_referer_module模塊容許攔截「Referer」請求頭中含有非法值的請求,阻止它們訪問站點。 須要注意的是僞造一個有效的「Referer」請求頭是至關容易的, 所以這個模塊的預期目的不在於完全地阻止這些非法請求,而是爲了阻止由正常瀏覽器發出的大規模此類請求。 還有一點須要注意,即便正常瀏覽器發送的合法請求,也可能沒有「Referer」請求頭。10: 實例:11:12: valid_referers none blocked server_names13: *.example.com example.* www.example.org/galleries/14: ~\.google\.;15:16: if ($invalid_referer) { 若是是以上指定範圍外的,則返回 403錯誤
17: return 403;
18: }
URL rewrite,地址重寫
1: rewrite regex replacement [flag]; #上下文 server,location,if
2:3: flag參數能夠是其中之一:4:5: last6: 中止執行當前這一輪的ngx_http_rewrite_module指令集,而後查找匹配改變後URI的新location;7: break8: 中止執行當前這一輪的ngx_http_rewrite_module指令集;9: redirect10: 在replacement字符串未以「http://」或「https://」開頭時,使用返回狀態碼爲302的臨時重定向;11: permanent12: 返回狀態碼爲301的永久重定向。13: 舉例:14:15: server {16: ...17: rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 last;18: rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra last;19: return 403;
20: ...21: }22: 可是當上述指令寫在「/download/」的location中時,應使用標誌break代替last,不然nginx會重複10輪循環,而後返回錯誤500:23:24: location /download/ {25: rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break;26: rewrite ^(/download/.*)/audio/(.*)\..*$ $1/mp3/$2.ra break;27: return 403;
28: }29: location /down1/ { #能夠沒有down1文件夾30: # root /web/b;31: rewrite ^/down1/(.*\.(jpg|gif|png))$ /image/$1 last; #訪問網址是www.a.com/down1,實際目錄是www.a.com/image32: }33:34: rewrite_log on|off #開啓或者關閉將ngx_http_rewrite_module模塊指令的處理日誌以notice級別記錄到錯誤日誌中。默認爲off;
35: return code: #用於結束rewrite規則,而且爲客戶返回狀態碼;可使用的狀態碼有204, 400, 402-406, 500-504等;
SSL
1: #2: #server {3: # listen 443;4: # server_name localhost;5:6: # ssl on; #開啓ssl引擎
7: # ssl_certificate cert.pem; #證書8: # ssl_certificate_key cert.key; #私鑰文件9:10: # ssl_session_timeout 5m; #ssl的超時時間,ssl會話的創建還釋放比保持鏈接更消耗時間,因此若是內存夠大而且你網站的粘性比較大,建議時間調長一點11:12: # ssl_protocols SSLv2 SSLv3 TLSv1; #支持的協議13: # ssl_ciphers HIGH:!aNULL:!MD5; #加密算法14: # ssl_prefer_server_ciphers on; #服務端選擇傾向的算法
stub_status狀態頁
1: location /server-status {2: stub_status on;
3: }4: Active connections: 25: server accepts handled requests6: 2 2 17: Reading: 0 Writing: 1 Waiting: 18:9: active connections -- number of all open connections
10: server accepts handled requests -- nginx accepted 2 connections, handled 2 connections (no one was closed just it was accepted), and handles 1 requests (1.8 requests per connection)11: reading -- nginx reads request header12: writing -- nginx reads request body, processes request, or writes response to a client13: waiting -- keep-alive connections, actually it is active - (reading + writing)
gzip壓縮頁面
1: http {2: gzip on; #開啓壓縮功能,能夠放在http,server
3: gzip_http_version 1.0; #壓縮後使用那種http協議構建響應報文4: gzip_comp_level 2; #壓縮級別5: gzip_types text/plain text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript application/javascript application/json; #僅對這些格式的內容進行壓縮6: gzip_disable msie6; #對IE6不使用壓縮機制7: }