I/O模型

電商網站 通常采用滿屏加載
有很多研究都表明,性能對使用者的行為有很大的影響:
79%的使用者表示不太可能再次打開一個緩慢的網站
47%的使用者期望網頁能在2秒鐘以内加載
40%的使用者表示如果加載時間超過三秒鐘,就會放棄這個網站
頁面加載時間延遲一秒可能導緻轉換損失7%,頁面浏覽量減少 11%
8秒定律:使用者通路一個網站時,如果等待網頁打開的時間超 過8秒,會有超過30%的使用者放棄等待
httpd MPM:
prefork:程序模型,兩級結構,主程序master負責生成子程序,每個子程序負責響應一個請求
worker:線程模型,三級結構,主程序master負責生成子程序,每個子程序負責生成多個線程,每個線程響應一個請求
event:線程模型,三級結構,主程序master負責生成子程序,每個子程序響應多個請求
I/O:
網絡IO:本質是socket讀取
磁盤IO:
每次IO,都要經由兩個階段:
第一步:将資料從磁盤檔案先加載至核心記憶體空間(緩沖區),等待資料準備完成,時間較長
第二步:将資料從核心緩沖區複制到使用者空間的程序的内 存中,時間較短
同步/異步:關注的是消息通信機制
同步:synchronous,調用者自已主動等待被調用者傳回消息,才能繼續執行
異步:asynchronous,被調用者通過狀态、通知或回調機制主動通知調用者被調用者的運作狀态
阻塞/非阻塞:關注調用者在等待結果傳回之前所處的狀态
阻塞:blocking,指IO操作需要徹底完成後才傳回到使用者空間,調用結果傳回之前,調用者被挂起
非阻塞:nonblocking,指IO操作被調用後立即傳回給使用者一個狀态值,無需等到IO操作徹底完成,最終的調用結果 傳回之前,調用者不會被挂起
I/O模型:
阻塞型、非阻塞型、複用型、信号驅動型、異步
同步阻塞IO模型是最簡單的IO模型,使用者線程在核心進行IO 操作時被阻塞
使用者線程通過系統調用read發起IO讀操作,由使用者空間轉到核心空間。核心等到資料包到達後,然後将接收的資料拷貝到使用者空間,完成read操作
使用者需要等待read将資料讀取到buffer後,才繼續處理接收 的資料。整個IO請求的過程中,使用者線程是被阻塞的,這導 緻使用者在發起IO請求時,不能做任何事情,對CPU的資源使用率不夠
使用者線程發起IO請求時立即傳回。但并未讀取到任何資料, 使用者線程需要不斷地發起IO請求,直到資料到達後,才真正 讀取到資料,繼續執行。即 “輪詢”機制
整個IO請求的過程中,雖然使用者線程每次發起IO請求後可以 立即傳回,但是為了等到資料,仍需要不斷地輪詢、重複請求 ,消耗了大量的CPU的資源
是比較浪費CPU的方式,一般很少直接使用這種模型,而是在 其他IO模型中使用非阻塞IO這一特性
多個連接配接共用一個等待機制,本模型會阻塞程序,但是程序是阻塞在 select或者poll這兩個系統調用上,而不是阻塞在真正的IO操作上
使用者首先将需要進行IO操作添加到select中,繼續執行做其他的工作(異 步),同時等待select系統調用傳回。當資料到達時,IO被激活,select 函數傳回。使用者線程正式發起read請求,讀取資料并繼續執行。
從流程上來看,使用select函數進行IO請求和同步阻塞模型沒有太大的區 别,甚至還多了添加監視IO,以及調用select函數的額外操作,效率更差 。并且阻塞了兩次,但是第一次阻塞在select上時,select可以監控多個 IO上是否已有IO操作準備就緒,即可達到在同一個線程内同時處理多個 IO請求的目的。而不像阻塞IO那種,一次隻能監控一個IO
雖然上述方式允許單線程内處理多個IO請求,但是每個IO請求的過程還 是阻塞的(在select函數上阻塞),平均時間甚至比同步阻塞IO模型還要 長。如果使用者線程隻是注冊自己需要的IO請求,然後去做自己的事情,等 到資料到來時再進行處理,則可以提高CPU的使用率
IO多路複用是最常使用的IO模型,但是其異步程度還不夠“徹底”,因 為它使用了會阻塞線程的select系統調用。是以IO多路複用隻能稱為異步 阻塞IO模型,而非真正的異步IO
IO多路複用是指核心一旦發現程序指定的一個或者多個IO條件準備 讀取,它就通知該程序
IO多路複用适用如下場合:
當用戶端處理多個描述符時(一般是互動式輸入和網絡套接口),必須使用I/O複用
當一個用戶端同時處理多個套接字時,此情況可能的但很少出現
當一個TCP伺服器既要處理監聽套接口,又要處理已連接配接套接口, 一般也要用到I/O複用
當一個伺服器即要處理TCP,又要處理UDP,一般要使用I/O複用
當一個伺服器要處理多個服務或多個協定,一般要使用I/O複用
信号驅動IO:signal-driven I/O
使用者程序可以通過sigaction系統調用注冊一個信号處理程式 ,然後主程式可以繼續向下執行,當有IO操作準備就緒時, 由核心通知觸發一個SIGIO信号處理程式執行,然後将使用者 程序所需要的資料從核心空間拷貝到使用者空間
此模型的優勢在于等待資料報到達期間程序不被阻塞。使用者主 程式可以繼續執行,隻要等待來自信号處理函數的通知
該模型并不常用
異步IO與信号驅動IO最主要的差別是信号驅動IO是由核心通 知何時可以進行IO操作,而異步IO則是由核心告訴我們IO操 作何時完成了。具體來說就是,信号驅動IO當核心通知觸發 信号處理程式時,信号處理程式還需要阻塞在從核心空間緩沖 區拷貝資料到使用者空間緩沖區這個階段,而異步IO直接是在 第二個階段完成後核心直接通知可以進行後續操作了
相比于IO多路複用模型,異步IO并不十分常用,不少高性能 并發服務程式使用IO多路複用模型+多線程任務處理的架構基 本可以滿足需求。況且目前作業系統對異步IO的支援并非特 别完善,更多的是采用IO多路複用模型模拟異步IO的方式( IO事件觸發時不直接通知使用者線程,而是将資料讀寫完畢後 放到使用者指定的緩沖區中)
主要實作方式有以下幾種:
Select:Linux實作對應,I/O複用模型,BSD4.2最早實作
Poll:Linux實作,對應I/O複用模型,System V unix最早實作
Epoll:Linux實作,對應I/O複用模型,具有信号驅動I/O模型 的某些特性
Kqueue:FreeBSD實作,對應I/O複用模型,具有信号驅動I/O 模型的某些特性
/dev/poll:SUN的Solaris實作,對應I/O複用模型,具有信号 驅動I/O模型的某些特性
Iocp Windows實作,對應第5種(異步I/O)模型
Select:POSIX所規定,目前幾乎在所有的平台上支援,其良 好跨平台支援也是它的一個優點,本質上是通過設定或者檢查 存放fd标志位的資料結構來進行下一步處理
缺點
單個程序可監視的fd數量被限制,即能監聽端口的數量有限 cat /proc/sys/fs/file-max
對socket是線性掃描,即采用輪詢的方法,效率較低
select 采取了記憶體拷貝方法來實作核心将 FD 消息通知給 使用者空間,這樣一個用來存放大量fd的資料結構,這樣會使 得使用者空間和核心空間在傳遞該結構時複制開銷大
poll
本質上和select沒有差別,它将使用者傳入的數組拷貝到核心空間,然後查詢每個fd對應的裝置狀态
其沒有最大連接配接數的限制,原因是它是基于連結清單來存儲的
大量的fd的數組被整體複制于使用者态和核心位址空間之間, 而不管這樣的複制是不是有意義
poll特點是“水準觸發”,如果報告了fd後,沒有被處理, 那麼下次poll時會再次報告該fd
邊緣觸發:隻通知一次
epoll:在Linux 2.6核心中提出的select和poll的增強版本
支援水準觸發LT和邊緣觸發ET,最大的特點在于邊緣觸發,它隻告訴程序哪些fd剛剛變為就需态,并且隻會通知一次
使用“事件”的就緒通知方式,通過epoll_ctl注冊fd,一旦該fd 就緒,核心就會采用類似callback的回調機制來激活該fd, epoll_wait便可以收到通知
優點:
沒有最大并發連接配接的限制:能打開的FD的上限遠大于1024(1G的記憶體能監聽約10萬個端口)
效率提升:非輪詢的方式,不會随着FD數目的增加而效率下降; 隻有活躍可用的FD才會調用callback函數,即epoll最大的優點就 在于它隻管理“活躍”的連接配接,而跟連接配接總數無關
記憶體拷貝,利用mmap(Memory Mapping)加速與核心空間的消 息傳遞;即epoll使用mmap減少複制開銷
Nginx介紹
Nginx:engine X ,2002年,開源,商業版
NGINX是免費,開源,高性能的HTTP和反向代理伺服器,郵件代理伺服器,通用TCP/UDP代理伺服器
解決C10K問題(10K Connections)
官網:http://nginx.org
二次開發版:
Tengine, OpenResty(章亦春)
特性:
子產品化設計,較好的擴充性
高可靠性
支援熱部署:不停機更新配置檔案,更新版本,更換日志檔案 平滑遷移
低記憶體消耗:10000個keep-alive連接配接模式下的非活動連接配接,僅 需要2.5M記憶體
event-driven,aio,mmap,sendfile
基本功能:
靜态資源的web伺服器
http協定反向代理伺服器
pop3/imap4協定反向代理伺服器
FastCGI(LNMP),uWSGI(python)等協定
子產品化(非DSO),如zip,SSL子產品
web服務相關的功能:
虛拟主機(server)
支援 keep-alive 和管道連接配接
通路日志(支援基于日志緩沖提高其性能)
url rewirte
路徑别名
基于IP及使用者的通路控制
支援速率限制及并發數限制
重新配置和線上更新而無須中斷客戶的工作程序
Memcached 的 GET 接口
nginx的程式架構:
master/worker結構
一個master程序: 負載加載和分析配置檔案、管理worker程序、平滑更新
一個或多個worker程序 處理并響應使用者請求
緩存相關的程序:
cache loader:載入緩存對象
cache manager:管理緩存對象
nginx高度子產品化,但其子產品早期不支援DSO機制;1.9.11版本支援動态裝載和解除安裝
子產品分類:
核心子產品:core module
标準子產品:
HTTP 子產品: ngx_http_*
HTTP Core modules 預設功能
HTTP Optional modules 需編譯時指定
Mail 子產品 ngx_mail_*
Stream 子產品 ngx_stream_*
第三方子產品
靜态的web資源伺服器
html,圖檔,js,css,txt等靜态資源
結合FastCGI/uWSGI/SCGI等協定反向代理動态資源請求
http/https協定的反向代理
imap4/pop3協定的反向代理
tcp/udp協定的請求轉發(反向代理)
Nginx安裝
官方: http://nginx.org/packages/centos/7/x86_64/RPMS
Fedora-EPEL: https://mirrors.aliyun.com/epel/7/x86_64/
編譯安裝:
yum install pcre-devel openssl-devel zlib-devel
useradd -r nginx
./configure --prefix=/usr/local/nginx --conf- path=/etc/nginx/nginx.conf --error-log- path=/var/log/nginx/error.log --http-log- path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid – lock-path=/var/run/nginx.lock --user=nginx --group=nginx – with-http_ssl_module --with-http_v2_module --with- http_dav_module --with-http_stub_status_module --with- threads --with-file-aio
make && make install
編譯安裝nginx選項:
–prefix=/etc/nginx 安裝路徑
–sbin-path=/usr/sbin/nginx 指明nginx程式檔案安裝路徑
–conf-path=/etc/nginx/nginx.conf 主配置檔案安裝位置
–error-log-path=/var/log/nginx/error.log 錯誤日志檔案安 裝位置
–http-log-path=/var/log/nginx/access.log 通路日志檔案安 裝位置
–pid-path=/var/run/nginx.pid 指明pid檔案安裝位置
–lock-path=/var/run/nginx.lock 鎖檔案安裝位置
–http-client-body-temp- path=/var/cache/nginx/client_temp 用戶端body部分的臨時 檔案存放路徑,如果伺服器允許用戶端使用put方法送出大資料 時,臨時存放的磁盤路徑
–http-proxy-temp-path=/var/cache/nginx/proxy_temp 作為代理伺服器,伺服器響應封包的臨時檔案存放路徑
–http-fastcgi-temp- path=/var/cache/nginx/fastcgi_temp 作為fastcgi代理服務 器,伺服器響應封包的臨時檔案存放路徑
–http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp 作為uwsgi代理伺服器,伺服器響應封包的臨時檔案存放路徑
–http-scgi-temp-path=/var/cache/nginx/scgi_temp 作為 scgi反代伺服器,伺服器響應封包的臨時檔案存放路徑
–user=nginx 指明以那個身份運作worker程序,主要master 程序一般由root運作
–group=nginx
–with-http_ssl_module 表示把指定子產品編譯進來
ls /usr/local/nginx/ html是測試頁,sbin是主程式
ls /usr/local/nginx/sbin/ nginx 隻有一個程式檔案
ls /usr/local/nginx/html/ 50x.html index.html 測試網頁
Nginx:預設為啟動nginx -h 檢視幫助選項
-V 檢視版本和配置選項
-t 測試nginx文法錯誤
-c filename 指定配置檔案(default: /etc/nginx/nginx.conf)
-s signal 發送信号給master程序,signal可為:stop, quit, reopen, reload 示例:-s stop 停止nginx -s reload 加載配置檔案
-g directives 在指令行中指明全局指令
配置檔案的組成部分:
主配置檔案:nginx.conf
子配置檔案 include conf.d/*.conf
fastcgi, uwsgi,scgi等協定相關的配置檔案
mime.types:支援的mime類型
主配置檔案的配置指令:
directive value [value2 …];
注意:
(1) 指令必須以分号結尾
(2) 支援使用配置變量
内建變量:由Nginx子產品引入,可直接引用 自定義變量:由使用者使用set指令定義
set variable_name value;
引用變量:$variable_name
主配置檔案結構:四部
main block:主配置段,即全局配置段,對http,mail都有效
stream
Main 全局配置段常見的配置指令分類
正常運作必備的配置
優化性能相關的配置
用于調試及定位問題相關的配置
事件驅動相關的配置
幫助文檔 http://nginx.org/en/docs/
正常運作必備的配置:
幫助文檔:http://nginx.org/en/docs/ngx_core_module.html
1、user
Syntax: user user [group];
Default: user nobody nobody;
Context: main
指定worker程序的運作身份,如組不指定,預設和使用者名同名
2、pid /PATH/TO/PID_FILE 指定存儲nginx主程序PID的檔案路徑
3、include file | mask 指明包含進來的其它配置檔案片斷
4、load_module file
子產品加載配置檔案:/usr/share/nginx/modules/*.conf
指明要裝載的動态子產品路徑: /usr/lib64/nginx/modules
性能優化相關的配置:
1、worker_processes number | auto
worker程序的數量;通常應該為目前主機的cpu的實體核心數
2、worker_cpu_affinity cpumask …
worker_cpu_affinity auto [cpumask] 提高緩存命中率
CPU MASK:
00000001:0号CPU
00000010:1号CPU
10000000:8号CPU
worker_cpu_affinity 0001 0010 0100 1000;
worker_cpu_affinity 0101 1010;
3、worker_priority number
指定worker程序的nice值,設定worker程序優先級:[-20,20]
4、worker_rlimit_nofile number
worker程序所能夠打開的檔案數量上限,如65535
事件驅動相關的配置:
events {
…
}
1、worker_connections number 每個worker程序所能夠打開的最大并發連接配接數數量,如10240 總最大并發數:worker_processes * worker_connections
2、use method
指明并發連接配接請求的處理方法 ,預設自動選擇最優方法 use epoll;
3、accept_mutex on | off 互斥 處理新的連接配接請求的方法;on指由各個worker輪流處理新請求 ,Off指每個新請求的到達都會通知(喚醒)所有的worker程序,但隻有一個程序可獲得連接配接,造成“驚群”,影響性能
調試和定位問題:
1、daemon on|off
是否以守護程序方式運作nignx,預設是守護程序方式
2、master_process on|off
是否以master/worker模型運作nginx;預設為on ,off 将不啟動worker
3、error_log file [level]
錯誤日志檔案及其級别;出于調試需要,可設定為debug;但 debug僅在編譯時使用了“–with-debug”選項時才有效
方式:
file /path/logfile;
stderr:發送到标準錯誤
syslog:server-address[,parameter=values]:發送到syslog
memory:size 記憶體
level:debug|info|notice|warn|error|crit|alter|emerg
Nginx各種子產品
ngx_http_core_module
與套接字相關的配置:
1、server { … }
配置一個虛拟主機
server {
listen address[:PORT]|PORT;
server_name SERVER_NAME;
root /PATH/TO/DOCUMENT_ROOT;
2、listen PORT|address[:port]|unix:/PATH/TO/SOCKET_FILE listen address[:port] [default_server] [ssl] [http2 | spdy] [backlog=number] [rcvbuf=size] [sndbuf=size]
default_server 設定為預設虛拟主機
ssl 限制僅能夠通過ssl連接配接提供服務
backlog=number 超過并發連接配接數後,新請求進入後援隊列的長度
rcvbuf=size 接收緩沖區大小
sndbuf=size 發送緩沖區大小
(1) 基于port; listen PORT; 指令監聽在不同的端口
(2) 基于ip的虛拟主機;listen IP:PORT; IP 位址不同
(3) 基于hostname,server_name fqdn; 指令指向不同的主機名
3、server_name name …;
虛拟主機的主機名稱後可跟多個由空白字元分隔的字元串
支援*通配任意長度的任意字元
server_name .yangyang.host www.yangyang.
支援~起始的字元做正規表達式模式比對,性能原因慎用
server_name ~^www\d+.magedu.com$ \d 表示 [0-9]
比對優先級機制從高到低:
(1) 首先是字元串精确比對 如:www.magedu.com
(2) 左側通配符 如:.magedu.com
(3) 右側通配符 如:www.magedu.
(4) 正規表達式 如: ~^.*.magedu.com$
(5) default_server
4、tcp_nodelay on | off; 在keepalived模式下的連接配接是否啟用TCP_NODELAY選項
當為off時,延遲發送,合并多個請求後再發送
預設On時,不延遲發送
可用于:http, server, location
5、sendfile on | off; 是否啟用sendfile功能,在核心中封裝封包直接發送 預設Off
6、server_tokens on | off | build | string 是否在響應封包的Server首部顯示nginx版本
7、定義路徑相關的配置
root
設定web資源的路徑映射;用于指明請求的URL所對應的文檔 的目錄路徑,可用于http, server, location, if in location
root /data/www/vhost1;
示例 http://www.magedu.com/images/logo.jpg --> /data/www/vhosts/images/logo.jpg
8、location [ = | ~ | ~* | ^~ ] uri { … } location @name { … }
在一個server中location配置段可存在多個,用于實作從uri到 檔案系統的路徑映射;ngnix會根據使用者請求的URI來檢查定義的所有 location,并找出一個最佳比對,而後應用其配置
示例:
server {…
server_name www.magedu.com;、
location /images/ {
root /data/imgs/;
http://www.magedu.com/images/logo.jpg --> /data/imgs/images/logo.jpg
是以意思是,如果 /images/中的/等于 /data/imgs/ 通路 /images/其實就是去通路/data/imgs/images
=:對URI做精确比對;
location = / {
http://www.yangyang.host/ 比對
http://www.yangyang.host/index.html 不比對
^~:對URI的最左邊部分做比對檢查,不區分字元大小寫
~:對URI做正規表達式模式比對,區分字元大小寫
~*:對URI做正規表達式模式比對,不區分字元大小寫
不帶符号:比對起始于此uri的所有的uri
比對優先級從高到低:
=, ^~, /*, 不帶符号
root /vhosts/www/htdocs/
http://www.yangyang.host/index.html --> /vhosts/www/htdocs/index.html
location /admin/ {
root /webapps/app1/data/
http://www.yangyang.host/admin/index.html --> /webapps/app1/data/admin/index.html
location示例
9、alias path;
路徑别名,文檔映射的另一種機制;僅能用于location上下文
注意:location中使用root指令和alias指令的意義不同
(a) root,給定的路徑對應于location中的/uri/左側的/
(b) alias,給定的路徑對應于location中的/uri/右側的/
10、index file …;
指定預設網頁檔案,注意:ngx_http_index_module子產品
11、error_page code … [=[response]]
uri; 子產品:ngx_http_core_module
定義錯誤頁,以指定的響應狀态碼進行響應
可用位置:http, server, location, if in location
error_page 404 /404.html
error_page 404 =200 /404.html
12、try_files file … uri; try_files file … =code;
按順序檢查檔案是否存在,傳回第一個找到的檔案或檔案夾(結尾加斜線 表示為檔案夾),如果所有的檔案或檔案夾都找不到,會進行一個内部重 定向到最後一個參數。隻有最後一個參數可以引起一個内部重定向,之前 的參數隻設定内部URI的指向。最後一個參數是回退URI且必須存在,否則會出現内部500錯誤
try_files $uri /images/default.gif; #這裡/images/default.gif的路徑不是磁盤絕對路徑,是uri路徑
location / {
try_files $uri $uri/index.html $uri.html =404;
定義用戶端請求的相關配置
13、keepalive_timeout timeout [header_timeout];
設定保持連接配接逾時時長,0表示禁止長連接配接,預設為75s
14、keepalive_requests number;
在一次長連接配接上所允許請求的資源的最大數量 預設為100
15、keepalive_disable none | browser …
對哪種浏覽器禁用長連接配接
16、send_timeout time;
向用戶端發送響應封包的逾時時長,此處是指兩次寫操作之間的間隔時長,而非整個響應過程的傳輸時長
17、client_body_buffer_size size;
用于接收每個用戶端請求封包的body部分的緩沖區大小 ;預設為16k;超出此大小時,其将被暫存到磁盤上的由下面 client_body_temp_path指令所定義的位置
18、client_body_temp_path path [level1 [level2 [level3]]];
設定用于存儲用戶端請求封包的body部分的臨時存儲路 徑及子目錄結構和數量
目錄名為16進制的數字;
client_body_temp_path /var/tmp/client_body 1 2 2
1 1級目錄占1位16進制,即2^4=16個目錄 0-f
2 2級目錄占2位16進制,即2^8=256個目錄 00-ff
2 3級目錄占2位16進制,即2^8=256個目錄 00-ff
對用戶端進行限制的相關配置
19、limit_rate rate;
限制響應給用戶端的傳輸速率,機關是bytes/second
預設值0表示無限制
20、limit_except method … { … },僅用于location限制用戶端使用除了指定的請求方法之外的其它方法
method:GET, HEAD, POST, PUT, DELETE MKCOL, COPY, MOVE, OPTIONS, PROPFIND, PROPPATCH, LOCK, UNLOCK, PATCH
除了GET和HEAD 之外其它方法僅允許192.168.1.0/24網 段主機使用
檔案操作優化的配置
21、aio on | off | threads[=pool];
是否啟用aio功能
22、directio size | off;
當檔案大于等于給定大小時,例如directio 4m,同步(直接)寫磁盤 ,而非寫緩存
23、open_file_cache off;
open_file_cache max=N [inactive=time]; nginx可以緩存以下三種資訊:
(1) 檔案中繼資料:檔案的描述符、檔案大小和最近一次的修改時間
(2) 打開的目錄結構
(3) 沒有找到的或者沒有權限通路的檔案的相關資訊
max=N:可緩存的緩存項上限;達到上限後會使用LRU算法實作管理
inactive=time:緩存項的非活動時長,在此處指定的時長内未被命中 的或命中的次數少于open_file_cache_min_uses指令所指定的次數的緩存項 即為非活動項,将被删除
24、open_file_cache_errors on | off; 是否緩存查找時發生錯誤的檔案一類的資訊 預設值為off
25、open_file_cache_min_uses number; open_file_cache指令的inactive參數指定的時長内,至
少被命中此處指定的次數方可被歸類為活動項 預設值為1
26、open_file_cache_valid time; 緩存項有效性的檢查頻率
預設值為60s
ngx_http_access_module子產品 實作基于ip的通路控制功能
1、allow address | CIDR | unix: | all;
2、deny address | CIDR | unix: | all;
http, server, location, limit_except
自上而下檢查,一旦比對,将生效,條件嚴格的置前
ngx_http_auth_basic_module子產品
實作基于使用者的通路控制,使用basic機制進行使用者認證
1、auth_basic string | off;
2、auth_basic_user_file file;
ngx_http_stub_status_module子產品
用于輸出nginx的基本狀态資訊 輸出資訊示例:
Active connections: 291
server accepts handled requests
16630948 16630948 31070465
上面三個數字分别對應accepts,handled,requests三個值
Reading: 6 Writing: 179 Waiting: 106
Active connections:目前狀态,活動狀态的連接配接數
accepts:統計總值,已經接受的用戶端請求的總數
handled:統計總值,已經處理完成的用戶端請求的總數
requests:統計總值,用戶端發來的總的請求數
Reading:目前狀态,正在讀取用戶端請求封包首部的連接配接的連接配接數
Writing:目前狀态,正在向用戶端發送響應封包過程中的連接配接數
Waiting:目前狀态,正在等待用戶端送出請求的空閑連接配接數
1、stub_status; 示例:
ngx_http_log_module子產品 指定日志格式記錄請求
1、log_format name string …;
string可以使用nginx核心子產品及其它子產品内嵌的變量
2、access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];
access_log off;
通路日志檔案路徑,格式及相關的緩沖的配置
buffer=size
flush=time
示例
log_format compression ‘
r
e
m
o
t
a
d
−
remote_addr-
remoteaddr−remote_user [KaTeX parse error: Double superscript at position 15: time_local] ' '̲"request" $status KaTeX parse error: Double superscript at position 14: bytes_sent ' '̲"http_referer" “
h
p
u
s
g
n
"
http_user_agent" "
httpuseragent""gzip_ratio”’;
access_log /spool/logs/nginx-access.log compression buffer=32k;
log_format需要放在http裡
3、open_log_file_cache max=N [inactive=time] [min_uses=N] [valid=time];
open_log_file_cache off;
緩存各日志檔案相關的中繼資料資訊
max:緩存的最大檔案描述符數量
min_uses:在inactive指定的時長内通路大于等于此值方 可被當作活動項
inactive:非活動時長 valid:驗證緩存中各緩存項是否為活動項的時間間隔
ngx_http_gzip_module 用gzip方法壓縮響應資料,節約帶寬
1、gzip on | off;
啟用或禁用gzip壓縮
2、gzip_comp_level level;
壓縮比由低到高:1 到 9
預設:1
3、gzip_disable regex …;
比對到用戶端浏覽器不執行壓縮
4、gzip_min_length length;
啟用壓縮功能的響應封包大小門檻值
5、gzip_http_version 1.0 | 1.1;
設定啟用壓縮功能時,協定的最小版本
預設:1.1
6、gzip_buffers number size;
支援實作壓縮功能時緩沖區數量及每個緩存區的大小
預設:32 4k 或 16 8k
7、gzip_types mime-type …;
指明僅對哪些類型的資源執行壓縮操作;即壓縮過濾器
預設包含有text/html,不用顯示指定,否則出錯
8、gzip_vary on | off;
如果啟用壓縮,是否在響應封包首部插入“Vary: Accept- Encoding”
9、gzip_proxied off | expired | no-cache | no-store | private | no_last_modified | no_etag | auth | any …;
nginx充當代理伺服器時,對于後端伺服器的響應封包,在何種條件下啟用壓縮功能
off:不啟用壓縮
expired,no-cache, no-store,private:對後端伺服器的響應封包首部Cache-Control值任何一個,啟用壓縮功能
gzip on;
gzip_comp_level 6;
gzip_min_length 64;
gzip_proxied any;
gzip_types text/xml text/css application/javascript;
ngx_http_ssl_module子產品:
1、ssl on | off;
為指定虛拟機啟用HTTPS protocol, 建議用listen指令代替
2、ssl_certificate file;
目前虛拟主機使用PEM格式的證書檔案
3、ssl_certificate_key file;
目前虛拟主機上與其證書比對的私鑰檔案
4、ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2];
支援ssl協定版本,預設為後三個
5、ssl_session_cache off | none | [builtin[:size]] shared:name:size;
none: 通知用戶端支援ssl session cache,但實際不支援
builtin[:size]:使用OpenSSL内建緩存,為每worker程序私有
6、ssl_session_timeout time;
用戶端連接配接可以複用ssl session cache中緩存的ssl參數的有效時長,預設5m
1 生成證書和私鑰檔案
cd /etc/pki/tls/certs
make a.crt 預設加密key檔案
openssl rsa -in a.key -out aa.key 去掉密碼
vim /etc/pki/tls/certs/Makefile
%.key:
umask 77 ;
/usr/bin/openssl genrsa $(KEYLEN) > $@ 删除-aes128
2 實作
vim /etc/nginx/conf.d/vhosts.conf
listen 443 ssl;
server_name www.a.com;
root /data/web1/;
ssl on;
ssl_certificate /etc/nginx/conf.d/ssl/a.crt;
ssl_certificate_key /etc/nginx/conf.d/ssl/aa.key;
ssl_session_cache shared:sslcache:20m;
ssl_session_timeout 10m;
server_name www.b.com;
root /data/web2;
ssl_certificate /etc/nginx/conf.d/ssl/b.crt;
ssl_certificate_key /etc/nginx/conf.d/ssl/bb.key;
ngx_http_rewrite_module子產品:
The ngx_http_rewrite_module module is used to change request URI using PCRE regular expressions, return redirects, and conditionally select configurations.
将使用者請求的URI基于PCRE regex所描述的模式進行檢 查,而後完成重定向替換
http://www.yangyang.host/hn --> http://www.yangyang.host/henan
http://www.yangyang.host —> https://www.yangyang.host/
1、rewrite regex replacement [flag]
将使用者請求的URI基于regex所描述的模式進行檢查,比對到時将其替換為replacement指定的新的URI
注意:如果在同一級配置塊中存在多個rewrite規則,那麼會自下而下逐個檢查;被某條件規則替換完成後,會重新一輪 的替換檢查
隐含有循環機制,但不超過10次;如果超過,提示500響應碼,[flag]所表示的标志位用于控制此循環機制
如果replacement是以http://或https://開頭,則替換 結果會直接以重向傳回給用戶端, 即永久重定向301
[flag]:
last:重寫完成後停止對目前URI在目前location中後續 的其它重寫操作,而後對新的URI啟動新一輪重寫檢查;提前重 啟新一輪循環,不建議在location中使用
break:重寫完成後停止對目前URI在目前location中後 續的其它重寫操作,而後直接跳轉至重寫規則配置塊之後的其它 配置;結束循環,建議在location中使用
redirect:臨時重定向,重寫完成後以臨時重定向方式直 接傳回重寫後生成的新URI給用戶端,由用戶端重新發起請求; 使用相對路徑,或者http://或https://開頭,狀态碼:302
permanent:重寫完成後以永久重定向方式直接傳回重寫 後生成的新URI給用戶端,由用戶端重新發起請求,狀态碼: 301
2、return
eturn code [text];
return code URL;
return URL; 停止處理,并傳回給用戶端指定的響應碼
3、rewrite_log on | off;
是否開啟重寫日志, 發送至error_log(notice level)
4、set
v
i
b
l
;
∗
用
戶
自
定
義
變
量
注
意
:
和
調
都
要
以
variable value; * 使用者自定義變量 * 注意:變量定義和調用都要以
variablevalue;∗使用者自定義變量∗注意:變量定義和調用都要以開頭
5、if (condition) { … }
引入新的上下文,條件滿足時,執行配置塊中的配置指令;server, location
condition:
比較操作符:
= 相同
!= 不同
~:模式比對,區分字元大小寫
~*:模式比對,不區分字元大小寫
!~:模式不比對,區分字元大小寫
!~*:模式不比對,不區分字元大小寫
檔案及目錄存在性判斷:
-e, !-e 存在(包括檔案,目錄,軟連結)
-f, !-f 檔案
-d, !-d 目錄
-x, !-x 執行
listen 80;
access_log /data/logs/nginx-access.log comp ;
root /data/web11/;
ssl_certificate_key /etc/nginx/conf.d/ssl/a.key;
if ($scheme = http ) {
rewrite / https://www.a.com/ permanent;
location /status {
stub_status;
ngx_http_referer_module子產品:
用來阻止Referer首部無有效值的請求通路,可防止盜鍊
1、valid_referers none|blocked|server_names|string …;
定義referer首部的合法可用值,不能比對的将是非法值
none:請求封包首部沒有referer首部
blocked:請求封包有referer首部,但無有效值
server_names:參數,其可以有值作為主機名或主機名模式
arbitrary_string:任意字元串,但可使用*作通配符
regular expression:被指定的正規表達式模式比對到的字元 串,要使用~開頭,例如: ~.*.yangyang.host
valid_referers none block server_names .yangyang.host .yangyang.host yangyang. yangyang. ~.yangyang.;
if ($invalid_referer) {
return 403 http://www.yangyang.host;
vim link.html
ngx_http_proxy_module子產品: 轉發請求至另一台主機
1、proxy_pass URL;
Context:location, if in location, limit_except
注意:proxy_pass後面路徑不帶uri時,會将location的uri傳遞(附加)給後端主機
上面示例:http://HOSTNAME/uri --> http://host/uri
如果上面示例中有 /,即:http://host[:port]/ 意味着:http://HOSTNAME/uri --> http://host/ 即置換
意思就是,如果proxy_pass http://URI 這裡跟的不是主站加/的話 ,就會轉發到http://URI/uri/
proxy_pass後面的路徑是一個uri時,其會将location的uri替換為proxy_pass的uri
如果location定義其uri時使用了正規表達式的模式,則 proxy_pass之後必須不能使用uri; 使用者請求時傳遞的uri将直 接附加至後端伺服器之後
2、proxy_set_header field value;
設定發往後端主機的請求封包的請求首部的值
Context: http, server, location
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
請求封包的标準格式如下:
X-Forwarded-For: client1, proxy1, proxy2
3、proxy_cache_path;
定義可用于proxy功能的緩存;Context:http
proxy_cache_path path [levels=levels] [use_temp_path=on|off]
keys_zone=name:size [inactive=time] [max_size=size] [manager_files=number] [manager_sleep=time] [manager_threshold=time] [loader_files=number] [loader_sleep=time] [loader_threshold=time] [purger=on|off] [purger_files=number] [purger_sleep=time] [purger_threshold=time];
4、proxy_cache zone | off;
預設off 指明調用的緩存,或關閉緩存機制;Context:http, server, location
5、proxy_cache_key string;
緩存中用于“鍵”的内容
預設值:proxy_cache_key
c
scheme
schemeproxy_host$request_uri;
6、proxy_cache_valid [code …] time;
定義對特定響應碼的響應内容的緩存時長
定義在http{…}中
proxy_cache_valid 200 302 10m;
proxy_cache_valid 404 1m;
示例:在http配置定義緩存資訊
proxy_cache_path /var/cache/nginx/proxy_cache
levels=1:1:1 keys_zone=proxycache:20m
inactive=120s max_size=1g;
說明:proxycache:20m 指記憶體中緩存的大小,主要用于存放key和metadata(如:使用次數)
max_size=1g 指磁盤存入檔案内容的緩存空間最大值調用緩存功能,需要定義在相應的配置段,如server{…};
proxy_cache proxycache;
proxy_cache_key $request_uri;
proxy_cache_valid 200 302 301 1h;
proxy_cache_valid any 1m;
7、proxy_cache_use_stale;
proxy_cache_use_stale error | timeout | invalid_header | updating | http_500 | http_502 | http_503 | http_504 | http_403 | http_404 | off …
在被代理的後端伺服器出現哪種情況下,可以真接使用過期的緩存響應用戶端
8、proxy_cache_methods GET | HEAD | POST …;
對哪些用戶端請求方法對應的響應進行緩存,GET和 HEAD方法總是被緩存
9、proxy_hide_header field;
預設nginx在響應封包不傳遞後端伺服器的首部字段Date, Server, X-Pad, X-Accel-等,用于隐藏後端伺服器特定的響 應首部
10、proxy_connect_timeout time;
定義與後端伺服器建立連接配接的逾時時長,如逾時會出現502錯誤,預設為60s,一般不建議超出75s
11、proxy_send_timeout time;
将請求發送給後端伺服器的逾時時長;預設為60s
12、proxy_read_timeout time;
等待後端伺服器發送響應封包的逾時時長,預設為60s
ngx_http_headers_module子產品
向由代理伺服器響應給用戶端的響應封包添加自定義首部,或修改指定首部的值
1、add_header name value [always];
添加自定義首部
add_header X-Via $server_addr;
add_header X-Cache $upstream_cache_status;
add_header X-Accel $server_name;
2、add_trailer name value [always]; 添加自定義響應資訊的尾部
ngx_http_fastcgi_module子產品
轉發請求到FastCGI伺服器,不支援php子產品方式
1、fastcgi_pass address;
address為後端的fastcgi server的位址
可用位置:location, if in location
2、fastcgi_index name;
fastcgi預設的首頁資源
示例:fastcgi_index index.php;
3、fastcgi_param parameter value [if_not_empty];
設定傳遞給 FastCGI伺服器的參數值,可以是文本,變 量或組合
示例1:
1)在後端伺服器先配置fpm server和mariadb-server
2)在前端nginx服務上做以下配置:
示例2:通過/pm_status和/ping來擷取fpm server狀态資訊
兩台主機
2 fastcgi伺服器實作
systemctl restart php-fpm
4、fastcgi_cache_path path [levels=levels] [use_temp_path=on|off]
定義fastcgi的緩存;
path 緩存位置為磁盤上的檔案系統
max_size=size 磁盤path路徑中用于緩存資料的緩存空間上限
levels=levels:緩存目錄的層級數量,以及每一級的目錄數量
levels=ONE:TWO:THREE
示例:leves=1:2:2
keys_zone=name:size
k/v映射的記憶體空間的名稱及大小
inactive=time
非活動時長
5、fastcgi_cache zone | off; 調用指定的緩存空間來緩存資料
可用位置:http, server, location
6、fastcgi_cache_key string; 定義用作緩存項的key的字元串
fastcgi_cache_key $request_rui;
7、fastcgi_cache_methods GET | HEAD | POST …; 為哪些請求方法使用緩存
8、fastcgi_cache_min_uses number; 緩存空間中的緩存項在inactive定義的非活動時間内至少要被通路到此處所指定的次數方可被認作活動項
9、fastcgi_keep_conn on | off; 收到後端伺服器響應後,fastcgi伺服器是否關閉連接配接,建議啟用長連接配接
10、fastcgi_cache_valid [code …] time; 不同的響應碼各自的緩存時長
ngx_http_upstream_module子產品
用于将多個伺服器定義成伺服器組,而由proxy_pass, fastcgi_pass等指令進行引用
1、upstream name { … }
定義後端伺服器組,會引入一個新的上下文
預設排程算法是wrr
Context: http
upstream httpdsrvs {
server …
server…
2、server address [parameters];
在upstream上下文中server成員,以及相關的參數;Context:upstream address的表示格式:
unix:/PATH/TO/SOME_SOCK_FILE
IP[:PORT]
HOSTNAME[:PORT]
parameters:
weight=number 權重,預設為1
max_conns 連接配接後端報務器最大并發活動連接配接數,1.11.5後支援
max_fails=number 失敗嘗試最大次數;超出此處指定的次數時 ,server将被标記為不可用,預設為1
fail_timeout=time 後端伺服器标記為不可用狀态的連接配接逾時時長,預設10s
backup 将伺服器标記為“備用”,即所有伺服器均不可用時才啟用
down 标記為“不可用”,配合ip_hash使用,實作灰階釋出
3、ip_hash 源位址hash排程方法
4、least_conn 最少連接配接排程算法,當server擁有不同的權重時其為wlc,當所有後端主機連接配接數相同時,則使用wrr,适用于長連接配接
5、hash key [consistent] 基于指定的key的hash表來實 現對請求的排程,此處的key可以直接文本、變量或二者組合
作用:将請求分類,同一類請求将發往同一個upstream server,使用consistent參數,将使用ketama一緻性hash算法, 适用于後端是Cache伺服器(如varnish)時使用
hash $request_uri consistent;
hash $remote_addr;
6、keepalive 連接配接數N;
為每個worker程序保留的空閑的長連接配接數量,可節約nginx 端口,并減少連接配接管理的消耗
7、health_check [parameters];
健康狀态檢測機制;隻能用于location上下文
常用參數:
interval=time檢測的頻率,預設為5秒
fails=number:判定伺服器不可用的失敗檢測次數;預設為1次
passes=number:判定伺服器可用的失敗檢測次數;預設為1次
uri=uri:做健康狀态檢測測試的目标uri;預設為/
match=NAME:健康狀态檢測的結果評估調用此處指定的match配置塊
注意:僅對nginx plus有效
8 match name { … }
對backend server做健康狀态檢測時,定義其結果判斷機制; 隻能用于http上下文
常用的參數:
status code[ code …]: 期望的響應狀态碼
header HEADER[operator value]:期望存在響應首部,也可對期望的響應首部的值基于比較操作符和值進行比較 body:期望響應封包的主體部分應該有的内容
nginx的其它的二次發行版:
Tengine:由淘寶網發起的Web伺服器項目。它在Nginx的基礎上,針對大通路量網站的需求,添加了很多進階功能和特 性。Tengine的性能和穩定性已經在大型的網站如淘寶網,天貓商城等得到了很好的檢驗。它的最終目标是打造一個高效、穩定 、安全、易用的Web平台。從2011年12月開始,Tengine成為 一個開源項目,官網 http://tengine.taobao.org/
OpenResty:基于 Nginx 與 Lua 語言的高性能 Web 平台
ngx_stream_core_module子產品
模拟反代基于tcp或udp的服務連接配接,即工作于傳輸層的反 代或排程器
1、stream { … }
定義stream相關的服務;Context:main
2、listen
listen address:port [ssl] [udp] [proxy_protocol] [backlog=number] [bind] [ipv6only=on|off] [reuseport] [so_keepalive=on|off|[keepidle]:[keepintvl]:[keepcnt]];
ngx_stream_proxy_module子產品
可實作代理基于TCP,UDP (1.9.13), UNIX-domain sockets的資料流
1 proxy_pass address;
指定後端伺服器位址
2 proxy_timeout timeout;
無資料傳輸時,保持連接配接狀态的逾時時長 預設為10m
3 proxy_connect_timeout time;
設定nginx與被代理的伺服器嘗試建立連接配接的逾時時長 預設為60s