nginx(web server,web reverse proxy)php
http事務:request <----> response
request:
<method> <URL> <version>
<HEADERS>
...
<body>html
response:
<version> <status> <reason phrase>
<HEADERS>
...
<body>node
web資源:URL (scheme://server:port/path/to/source)linux
方法:GET, HEAD, POST, (WEBDAV) PUT, DELETE, TRACE, OPTIONSnginx
status:
1xx: 信息類
2xx: 成功類,200
3xx: 重定向,301, 302, 304
4xx: 客戶端類錯誤,403, 401, 404
5xx: 服務端類錯誤,502web
I/O類型:
同步和異步:synchronous, asyncrhonous
關注的是消息通知機制正則表達式
同步:調用發出不會當即返回,但一旦返回就能夠返回最終結果;
異步:調用發出以後,被調用方當即返回消息,但返回的非最終結果;被調用者經過狀態、通知機制來通知調用者,或經過回調函數來處理結果;後端
阻塞和非阻塞:block, nonblock
關注的是調用者等待調用結果(消息、返回值)時的狀態緩存
阻塞:調用結果返回以前,調用者(調用線程)會被掛起;調用者只有在獲得結果以後纔會返回;
非阻塞:調用結果返回以前,調用不會阻塞當前線程;性能優化
5種I/O模型:
同步阻塞 blocking IO
同步非阻塞 nonblocking IO
IO複用 IO multiplexing select(),poll()
信號驅動IO signal driven IO 通知:一、水平觸發:屢次通知;二、邊緣觸發:只通知一次;
異步IO asyncrhonous IO
nginx:讀音engine x
二次研發:tengine、registry
libevent:高性能的網絡庫
一、epool()
Nginx的特性:
模塊化設計、較好擴展性;
高可靠性:master/worker
支持熱部署:不停機更新配置文件、更換日誌、更新服務器程序版本;
低內存消耗 :10000個keep-alive鏈接模式下的非活動鏈接僅消耗2.5M內存;
事件驅動機制(mmap), 異步IO(aio), 內存映射機制(mmap);
基本功能:
靜態資源的web服務器,能緩存打開的文件描述符;
http、smtp、pop三、imap4等協議的反向代理服務器;
緩存加速、負載均衡;
支持FastCGI(php-fpm), uWSGI(Python Web Framwork)等協議
模塊化(非DSO機制),過濾器zip、SSI及圖像的大小調整;
支持SSL;
擴展功能:
基於名稱和IP的虛擬主機;
支持keepalive
支持平滑升級
定製訪問日誌,支持使用日誌緩存區提供日誌存儲性能;
支持url rewrite;
支持路徑別名;
支持基於IP及用戶的訪問控制;
支持速率限制,支持併發數限制;
Nginx的程序架構:
master/worker
一個master進程,可生成一個或多個worker進程;
事件驅動模型:epoll(Linux默認邊緣觸發), kqueue(FreeBSD), /dev/poll(Solaris)
消息通知(複用器):select, poll, rt signals
支持sendfile, sendfile64
支持AIO,mmap
master: 加載配置文件、管理worker進程、平滑升級,...
worker:http服務,http代理,fastcgi代理,...
模塊類型:
一、核心模塊:core module
二、標準模塊:
a、標準http模塊:Standard HTTP modules
b、可選http模塊:Optional HTTP modules
c、郵件相關模塊:Mail modules
三、第三方模塊:3rd party modules
安裝方法:
一、源碼:編譯安裝
二、製做好的程序包:rpm包
配置文件組織結構
main block:全局配置;對http及mail模塊均有效;
events {}:定義event模型(事件驅動)的相關配置;對http及mail模塊均有效
http {}:http協議的相關配置;
mail {}:mail協議的相關配置;
配置指令:要以分號結尾,語法格式:directive value1 [value2...]
支持使用變量:一、內置變量:模塊會提供內建變量;二、自定義變量:set var_name value;
main配置段:
類別:
正常運行必備的配置;
優化性能相關的配置;
用於調試、定位問題的配置;
正常運行必備的配置:
一、user USERNAME [GROUPNAME];
指定用於運行worker進程的用戶和組;
user nginx nginx;
二、pid /PATH/TO/PID_FILE;
指定nginx進程的pid文件路徑;
pid /var/run/nginx.pid;
三、worker_rlimit_nofile #;
指定單個worker進程所可以打開的最大文件描述符數量;
性能優化相關的配置:
一、worker_processes #;
worker進程的個數;一般應該爲物理CPU核心數量減1;
能夠爲"auto",實現自動設定;
二、worker_cpu_affinity CPUMASK(cpu掩碼) CPUMASK ...;
worker_cpu_affinity auto [CPUMASK]
實現nginx綁定cpu;
優勢:提高緩存的命中率;
CPUMASK:多少顆cpu就用多少個二進制來表示;以下例如4顆cpu;
0001
0010
0100
1000
worker_cpu_affinity 00000001 00000010 00000100;
三、worker_priority nice;
定義worker進程的優先級;
[-20, 19],默認nice值爲0
100-139,默認優先級爲120
四、timer_resolution interval;
計時器解析度,下降此值,可減小gettimeofday()系統調用的次數;
調試、定位問題的配置:
一、daemon off|on;
是否以守護進程方式啓動nignx;默認爲on;調試時應該設置爲off;
二、master_process on|off;
是否以master/worker模型運行nginx;默認是on;調試時應該設置爲off;
三、error_log /PATH/TO/ERROR_LOG level;
錯誤日誌文件的記錄方式,及其級別;出於調試的須要,能夠設爲debug;但debug僅在編譯時使用了「--with-debug」選項時纔有效;
方式:
file /PATH/TO/SOME_LOG_FILE;
stderr:發送到錯誤輸出;
syslog:server=address[,parameter=value]:發送給syslog服務器;
memory:size
日誌級別:
debug:依賴於configure時的--with-debug選項;
info、notice、warn、error、crit、alert、emerg
事件驅動相關的配置:
一、accept_mutex on | off;
master調度用戶請求至各worker進程時使用的負載均衡鎖;on表示能讓多個worker輪流地、序列化的響應新請求;
二、lock_file file;
accept_mutex用到的鎖文件路徑;
三、use method;
指明併發鏈接請求處理時使用的方法;即指明使用的事件模型;建議讓nginx自行選擇;
use epool;linux只有epool可選
四、worker_connections number;
每一個worker進程所可以響應的最大併發請求數量;
總結:常須要進行調整的參數:
worker_processes,worker_connetctions,worker_cpu_affinity,worker_priority
新改動配置生效的方式:nginx -s reload | stop | quit | reopen
nginx做爲web服務器時使用的配置:
定義套接字相關功能
一、server {}:定義一個虛擬主機;
server {
listen PORT;
server_name HOSTNAME;
root /PATH/TO/DOCUMENTROOT;
}
...
注意:
(1) 基於port的虛擬主機;
listen指令監聽在不一樣的端口;
(2) 基於hostname的虛擬主機;
server_name指令指向不一樣的主機名;
(3)基於ip的虛擬主機:
listen IP:PORT;
二、listen
listen address[:port] [default_server] [ssl] [http2 | spdy] [backlog=number] [rcvbuf=size] [sndbuf=size]
listen port [default_server] [ssl] [http2 | spdy]
listen unix:path [default_server] [ssl] [http2 | spdy]
default_server:設置默認虛擬主機;用於基於IP地址,或使用了任意不能對應於任何一個server的name時所返回站點;
ssl:用於限制只能經過ssl鏈接提供服務;
backlog:後援隊列的長度;
rcvbuf:接收緩衝區大小;
sndbuf:發送緩衝區大小;
spdy:SPDY protocol(speedy),在編譯了spdy模塊的狀況下,用於支持SPDY協議;
http2:http version 2;
三、server_name NAME [...];
指明當前server的主機名;後可跟一個或多個用空白字符分隔的主機;
支持使用*任意長度的任意字符;
支持~起始的正則表達式模式字符串;
優先級:
(1) 首先作精確匹配;例如:www.magedu.com
(2) 左側通配符;例如:.magedu.com
(3) 右側通配符,例如:www.magedu.
(4) 正則表達式,例如:~^.*.magedu.com$
(5) default_server
四、root path;
設置web資源的路徑映射;用於指明請求的URL所對應的文檔的目錄路徑;
可用上下文:http,server,location,if
五、location [ = | ^~ | ~ | ~* ] uri { ... };
location @name { ... }
功能:容許根據用戶請求的URI來匹配定義的各location;匹配到時,此請求將被相應的location塊中的配置所處理,例如作訪問控制等功能;
=:URI的精確匹配;
^~:URI的前半部分匹配,不支持正則表達式;
~:作正則表達式匹配,區分字符大小寫;
~*:作正則表達式匹配,不區分字符大小寫;
匹配優先級:精確匹配=、^~、~或~*、不帶符號的URL;
六、alias path;
只能用於location配置段,定義路徑別名;
location /images/ {
root /data/imgs/;
}
http://www.magedu.com/images/a.jpg <--- /data/imgs/images/a.jpg
location /images/ {
alias /data/imgs/;
}
http://www.magedu.com/images/a.jpg <--- /data/imgs/a.jpg
注意:root表示指明路徑爲對應的location "/" URL;alias表示路徑映射,即location指令後定義的URL是相對於alias所指明的路徑而言;
七、index file;
默認主頁面;
例如: index index.php index.html;
八、error_page code [...] [=code] URI | @name;
根據http的響應狀態碼來指明特用的錯誤頁面;
error_page 404 /404_customed.html
[=code]:以指定的響應碼進行響應,而不是默認的原來的響應碼;默認表示以新資源的響應碼爲其響應碼;
error_page 404 =200 /404.html
九、基於IP的訪問控制
allow IP | NETWORK | unix: | all;
deny IP | NETWORK | unix: | all;
可用上下文:http, server, location, limit_except
十、基於用戶的訪問控制(basic,digest)
auth_basic "";
auth_basic_user_file "/PATH/TO/PASSWD_FILE";
帳號密碼建議使用htpasswd來建立
htpasswd命令;
十一、https服務
前提:生成私鑰,生成證書籤署請求,並得到證書;
server {
listen 443 ssl;
server_name www.magedu.com;
ssl_certificate cert.pem; 指明證書文件位置
ssl_certificate_key cert.key; 指明私鑰文件位置
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
location / {
root /vhosts/web1;
index index.html index.htm;
}
}
十二、stub_status {on|off};
經過指定的uri輸出stub status;僅能用於location上下文;
location /status {
stub_status on;
allow 172.20.120.0/23
deny all;
}
結果示例:
Active connections: 5
server accepts handled requests
234 234 462
Reading: 1 Writing: 5 Waiting: 12
Active connections:當前全部處於打開狀態的鏈接數;
accepts:已經接受過的鏈接數;
handled:已經處理過的鏈接數;
requests:已經處理過的請求數;在「保持鏈接」模式下,請求數量可能會多於鏈接數量;
Readking:正處於接收請求狀態的鏈接數;
Writing:請求已經接收完成,正處於處理請求或發送響應的過程當中的鏈接數;
Waiting:保持鏈接模式,且處於活動狀態的鏈接數;
1三、rewrite regex replacement [flag];
把用戶請求的URI基於regex作檢查,匹配到時將替換爲replacement指定的字符串;
在同一個location中存在的多個rewrite規則會自上而下逐個被檢查(循環);可使用flag控制此循環功能;
regex:正則表達式,用於匹配用戶請求的url;
replacement:重寫爲的結果;
[flag]:
last:一旦此rewrite規則重寫完成後,就再也不被後面其餘的rewrite規則進行處理;而是由user agent從新對重寫後的URL再一次發起請求,並從頭開始執行相似的過程;
break:一旦此rewrite規則重寫完成後,由user agent對新的URL從新發起請求,且再也不會被當前location內的任何rewrite規則所檢查;
redirect:以302響應碼(臨時重定向)返回新的URL;
permanent:以301響應碼(永久重定向)返回新的URL;
例如:
rewrite ^/images/(.*.jpg)$ /imgs/$1 break;
http://www.magedu.com/images/a/1.jpg ---> http://www.magedu.com/imgs/a/1.jpg
1四、if
語法 if (condition) {...}
應用環境:server,location
condition:
(1)變量名:
變量值爲空串,或者以「0」開始,則爲fault,其餘均爲true;
(2)以變量爲操做數構成的比較表達式
可以使用=,!=相似的比較操做符進行測試;
(3)正則表達式的模式匹配操做;
~:區分大小寫的模式匹配檢查;
~:不區分大小寫的模式匹配檢查;
!~和!~:對上面兩種測試取反;
(4)測試路徑爲文件的可能性:-f,!-f
(5)測試路徑爲目錄的可能性:-d,!-d
(6)測試文件的存在性:-e,!-e
(7)檢查文件是否有執行權限:-x,!-x
例如:
if ($http_user_agent ~ MSIE) {
rewrite ^(.)$ /msie/$1 break;
}
1五、防盜鏈
location ~* .(jpg|gif|jpeg|png)$ {
valid_referer none blocked www.lewis.com;
if ($invalid_referer) {
rewrite ^/ http://www.lewis.com/403.html;
}
}
1六、定製訪問日誌
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log logs/access.log main;
注意:此處可用變量爲nginx各模塊內建變量;
網絡鏈接相關配置:
一、keepalive_timeout #; 長鏈接的超時時長,默認爲75s;
二、keepalive_requests #; 在一個長鏈接上所可以容許請求的最大資源數;
三、keepalive_disable [msie|safari|none]; 爲指定類型的user agent禁用長鏈接;
四、tcp_nodelay on|offf; 是否對長鏈接使用TCP_NODELAY選項;
五、client_header_timeout #; 讀取http請求報文首部的超時時長;
六、client_body_timeout #; 讀取http請求報文body部分的超時時長;
七、send_timeout #; 發送響應報文的超時時長;
LNMP:php啓用fpm模型;
例如:
location / {
root /vhosts/web1;
index index.php index.html index.htm;
}
location ~ .php$ {
root /vhosts/web1;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME /vhosts/web1/$fastcgi_script_name;
include fastcgi_params;
}
nginx反向代理:proxy、fastcgi、upstream
ngx_http_proxy_module:實現反向代理及緩存功能;
(1) proxy_pass URL;
應用上下文:location, if in location, limit_except
proxy_pass後面的路徑不帶uri時,其會將location的uri傳遞給後端的主機;下面的示例會將/uri/傳遞給backend服務器;
location /uri/ {
proxy_pass http://hostname;
}
proxy_pass後面的路徑是一個uri時,其會將location的uri替換爲後端主機本身的uri;
location /uri/ {
proxy_pass http://hostname/new_uri/;
}
若是location定義其uri時使用的正則表達式模式匹配,則proxy_pass後的路徑不可以使用uri;
location ~* .(jpg|gif|jpeg)$ {
proxy_pass http://HOSTNAME;
}
此處的http://HOSTNAME後面不能有任何uri,哪怕只有/也不能夠;
(2) proxy_set_header field value;
用於proxy server向backend server發請求報文時,將某請求首部從新賦值,或在原有值後面添加一個新的值; 也能夠添加自定義首部;
示例:
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
原有請求報文中若是存在X-Forwared-For首部,則將remote_addr以逗號分隔補原有值後,不然則直接添加此首部;
實踐做業:
假如nginx有兩個server(虛擬主機),且均反代至後端某一個主機,此主機亦有兩個虛擬主機,虛擬主機名與nginx的相同;
要求:用戶請求nginx的哪個虛擬主機,就將其代理後後端主機的對應的虛擬主機;
緩存相關的選項(緩存要先定義,後調用):
(3) proxy_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size]
定義緩存;可用上下文爲http;
(4) proxy_cache zone | off;
調用緩存;可用上下文 爲http, server和location;
(5) proxy_cache_key string;
定義緩存鍵;
proxy_cache_key $scheme$proxy_host$request_uri;
(6) proxy_cache_valid [code ...] time;
對不一樣響應碼的響應設定其可緩存時長;
示例:
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | off ...;
處於什麼狀態下,以舊的緩存響應;
proxy_cache_bypass string:設置在何種狀況下nginx將不從cache取數據;
$cookie_nocache $arg_nocache $httpd_authorization
跟鏈接相關的選項
(7) proxy_connect_timeout time;
定義與後端服務器創建鏈接的超時時長;默認爲60s,不建議超出75s;
(8) proxy_send_timeout time;
把請求發送給後端服務器的超時時長;默認爲60s;
(9) proxy_read_timeout time;
等待後端服務器發送響應報文的超時時長;
ngx_http_upstream_module:定義服務器組
用於將多個服務器定義成服務器組,而由proxy_pass, fastcgi_pass等指令進行引用;
(1) upstream name { ... }
定義一個後端服務器組,name爲組名稱;僅能用於http上下文 ;
(2) server address [parameters];
在upstream中定義一個服務器及其相關參數;僅能用於upstream上下文;
經常使用參數:
weight=number:定義服務器權重,默認爲1;
max_fails=number:最大失敗鏈接嘗試次數,失敗鏈接超時時長由fail_timeout參數指定;
fail_timeout=number:等待目標服務器發送響應的時長;
backup:備用服務器,全部主服務器均故障時才啓用此主機;
down:手動標記其再也不處理任何用戶請求;
使用方法:
(a) 定義upstream服務器組
upstream websrvs {
server 172.16.100.68 weight=2 max_fails=2 fail_timeout=6s;
server 172.16.100.6 weight=1 max_fails=2 fail_timeout=6s;
}
(b) 在反代場景中(proxy_pass, fastcgi_pass, ...)進行調用;
location / {
proxy_pass http://websrvs/;
}
(3) ip_hash;
源地址hash,把來自同一個ip地址的請求始終發往同一個backend server,除非此backend server不可用;
(4) least_conn;
最少鏈接;當各server權重不一樣時,即爲加權最少鏈接;
(5) health_check [parameters];
健康狀態檢測機制;只能用於location上下文;建議關閉訪問日誌;
經常使用參數:
interval=time檢測的頻率,默認爲5秒;
fails=number:斷定服務器不可用的失敗檢測次數;默認爲1次;
passes=number:斷定服務器可用的失敗檢測次數;默認爲1次;
uri=uri:作健康狀態檢測測試的目標uri;默認爲/;
match=NAME:健康狀態檢測的結果評估調用此處指定的match配置塊;
(6) match name { ... }
對backend server作健康狀態檢測時,定義其結果判斷機制;只能用於http上下文;
經常使用的參數:
status code[ code ...]: 指望的響應狀態碼;
header HEADER[operator value]:指望存在響應首部,也可對指望的響應首部的值基於比較操做符和值進行比較;
body:指望響應報文的主體部分應該有的內容;
(7) hash key [consistent];
指明基於hash方式進行調度時,其hash key;
hash $remote_addr至關於ip_hash;
經常使用的hash key:
$cookie_name:將一個用戶的請求始終發往同一個backend server,能實現會話綁定的功能;此處的name爲cookie某些參數的名稱,此處經常使用的有cookie_username;
$request_uri: 將對同一個uri的請求始終發往同一個backend server,後端爲cache server時特別有用;
session會話保持:
session sticky:基於ip, ngix還可基於請求報文首部中的多種信息,例如cookie, uri;
session cluster:每一個server均把建立和維護session同步集羣中的其它主機;僅適用於較小規模的環境;
session server:使用一個共享的存儲服務存儲session信息;
ngx_http_headers_module模塊配置
(1) add_header name value [always];
向響應報文添加自定義首部,併爲其賦值;
示例:
add_header realserver $server_addr; 添加真實服務器地址的自定義首部
add_header cache_status $upstream_cache_status; 添加nginx緩存狀態的自定義首部
(2) expires [modified] time;
expires epoch | max | off;
容許或禁止向響應報文的Cache-Control或Expires首部添加新值或修改其值;
fastcgi模塊指令:
(1) fastcgi_pass address;
address爲fastcgi server監聽的地址和端口;
示例:fastcgi_pass 127.0.0.1:9000;
(2) fastcgi_index name;
定義fastcgi應用的默認主頁;
示例:fastcgi_index index.php;
(3) fastcgi_param parameter value [if_not_empty];
設定傳遞給後端fastcgi server參數及其值;
示例:fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
/index.php --> /scripts/index.php
http://www.magedu.com/users.php?username=tom
(4) fastcgi_cache_path path [levels=levels] [use_temp_path=on|off] keys_zone=name:size [inactive=time] [max_size=size];
定義緩存:緩存空間等;
可應用的上下文 :http
緩存機制:
元數據:內存,即爲keys_zone;
數據:磁盤,即爲path;
path:文件系統路徑,用於儲存緩存的文件數據;
levels=#[:#[:#]]:緩存目錄層級定義;
levels=2:1
keys_zone=name:size
內存中用於緩存k/v映射關係的空間名稱及大小;
name: cache的標識符;
size:元數據cache大小;
max_size:緩存空間上限;
注意:只能用於http上下文;
(5) fastcgi_cache zone | off;
調用定義過的緩存;
zone即爲經過fastcgi_cache_path定義緩存時其keys_zone參數中的name;
(6) fastcgi_cache_key string;
定義如何使用緩存鍵;
使用示例:fastcgi_cache_key $request_uri;
(7) fastcgi_cache_methods GET | HEAD | POST ...;
爲什麼請求方法對應的請求進行緩存,默認爲GET和HEAD;
(8) fastcgi_cache_min_uses number;
緩存項的最少使用次數;
(9) fastcgi_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_503 | http_403 | http_404 | off ...;
是否可以使用stale緩存項響應用戶請求;
(10) fastcgi_cache_valid [code ...] time;
對不一樣響應碼的響應設定其可緩存時長;
示例:
fastcgi_cache_valid 200 302 10m;
fastcgi_cache_valid 301 1h;
fastcgi_cache_valid 404 1m;
注意:調用緩存時,至少應該指定三個參數
fastcgi_cache
fastcgi_cache_key
fastcgi_cache_valid
LNMP:php啓用fpm模型;
php-fpm的工做方式:
listen = 127.0.0.1:9000
listen.allowed_clients = 127.0.0.1
pm = dynamic|static
pm.start_servers:啓動fpm進程時啓動的工做進程數量;
pm.min_spare_servers:最少空閒進程數;
pm.max_spare_servers:最大空閒進程數;
pm.max_children:最大工做進程數;
user = USERNAME
group = GROUPNAME
示例:location / {
root /vhosts/web1;
index index.php index.html index.htm;
}
location ~ .php$ {root /vhosts/web1;fastcgi_pass 127.0.0.1:9000;fastcgi_index index.php;fastcgi_param SCRIPT_FILENAME /vhosts/web1/$fastcgi_script_name;include fastcgi_params;}