Nginx總結

1. 瞭解I/O模型

x86類型的CPU把指令分紅了四類:環0-環3,最內層爲核心指令即內核指令,其餘指令在環3上,歷史緣由環1,2沒有使用。html

分類:阻塞型、非阻塞型、複用型、信號驅動型、異步。nginx

同步/異步:web

  關注消息通知機制:正則表達式

    消息通知:
      同步:等待對方返回消息;算法

      異步:被調用者經過狀態、通知或回調機制通知調用者有關被調用者的運行狀態。express

阻塞/非阻塞:vim

  關注調用者在等待結果返回以前所處的狀態:瀏覽器

    阻塞:blocking,調用結果返回以前,調用者被掛起;緩存

    非阻塞:nonblocking,調用結果返回以前,調用者不被掛起。性能優化

一次文件I/O請求,都會由兩階段組成:

  第一步:等待數據,即數據從磁盤到內核內存;

  第二步:複製數據,即數據從內核內存到進程內存。

已上的I/O分類就是給予上述兩步來劃分的:

  阻塞型:已上兩步均被阻塞;

  非阻塞型:第一步是非阻塞的,第二步是阻塞的;

  複用型:一個進程能監視多路I/O,此時須要一個特殊的內核函數(I/O複用器)去監視iI/O;

  信號驅動型:屬於異步I/O,第一步再也不阻塞,調用後再也不等待結果,繼續執行其餘任務;

  異步:屬於異步I/O,不管第一步和第二步均不參與,由內核去完成。

複用型I/O調用:

  Linux:

    select:1024(一個進程最多監視1024個I/O,屢次測試的結果,是由BSD發明)

    poll():沒有限制,是由UNIX

信號驅動型(event-driven):

  epoll(Linux):由 libevent包來實現

  Kqueue(BSD):

  /dev/poll(Solaris)

 

 

2 . HTTPD MPM(多處理模塊)

多處理模塊(MPM),用來綁定到網絡端口上,接受請求, 以及調度子進程處理請求。在更高伸縮性的站點能夠選擇使用線程的 MPM,即 worker 或 event; 須要可靠性或者與舊軟件兼容的站點可使用 prefork

prefork模型:進程模型,二級結構,主進程master負責生成子進程,每一個子進程負責響應一個請求;

worker模型:線程模型,三級結構,主進程master負責生成子進程,每一個子進程負責生成多個線程,每一個線程響應一個請求;

event模型:二級結構,主進程master負責生成子進程,每一個子進程響應多個請求(相似線程模型)。

 

3. Nginx程序架構

 

nginx有三種功能:web服務(靜態的web資源服務器),web反向代理,郵件反向代理

3.1 master/worker

  一個master進程:

    負責加載和分配配置文件、管理worker進程、平滑升級

  一個或者多個worker進程:

    處理並響應用戶請求

  緩存相關的進程:

    cache loader: 載入緩存對象

    cache manager: 管理緩存對象

特性:異步,事件驅動和非阻塞

  併發請求處理:經過kevent/epoll/select,/dev/poll實現,此處須要注意epoll和select,優先使用epoll;

  文件I/O: 高級I/O、sendfile、異步、mmap

3.2 Nginx模塊

Nginx高度模塊化機制,但其模塊早期不支持DSO機制,近期支持模塊動態裝載和卸載。

模塊分類:核心模塊和標準模塊、第三方模塊。

3.2.1 核心模塊(core module)

3.2.2 標準模塊

HTTP modules:
  standard HTTP modules:
  Optional HTTP modules(可選的http模塊) :

Mail modules
Stream modules(流模塊):實現傳輸層代理(屬於四層代理)

3.2.2 第三方模塊

 

4. Nginx配置文件

配置指令:

4.1 性能優化相關的配置

worker_processes number | auto

一般對應cpu核心數;

worker_cpu_affinity auto | cpumask

將進程綁定在cpu上;

worker_priority number | cpumask

指定worker進程的nice值,設定worker進程的優先級[-20,20];

worker_rlimit_nofile_number

worker進程所可以打開的文件數量上限;

 

sendfile系統調用在兩個文件描述符之間直接傳遞數據(徹底在內核中操做),從而避免了數據在內核緩衝區和用戶緩衝區之間的拷貝,操做效率很高,被稱之爲零拷貝。可是隻適用於靜態資源服務器,對於反向代理則無用。

原理解釋
read/write
在傳統的文件傳輸方式(read、write/send方式),具體流程細節以下:

調用read函數,文件數據拷貝到內核緩衝區
read函數返回,數據從內核緩衝區拷貝到用戶緩衝區
調用write/send函數,將數據從用戶緩衝區拷貝到內核socket緩衝區
數據從內核socket緩衝區拷貝到協議引擎中

在這個過程中,文件數據其實是通過了四次拷貝操做:
硬盤—>內核緩衝區—>用戶緩衝區—>內核socket緩衝區—>協議引擎
sendfile
sendfile系統調用則提供了一種減小拷貝次數,提高文件傳輸性能的方法。

sendfile系統調用利用DMA引擎將文件數據拷貝到內核緩衝區,以後數據被拷貝到內核socket緩衝區中
DMA引擎將數據從內核socket緩衝區拷貝到協議引擎中

這裏沒有用戶態和內核態之間的切換,也沒有內核緩衝區和用戶緩衝區之間的拷貝,大大提高了傳輸性能。
這個過程數據經歷的拷貝操做以下:
硬盤—>內核緩衝區—>內核socket緩衝區—>協議引擎
帶有DMA收集拷貝功能的sendfile
對於帶有DMA收集拷貝功能的sendfile系統調用,還能夠再減小一次內核緩衝區之間的拷貝。具體流程以下:

sendfile系統調用利用DMA引擎將文件數據拷貝到內核緩衝區,以後,將帶有文件位置和長度信息的緩衝區描述符添加到內核socket緩衝區中
DMA引擎會將數據直接從內核緩衝區拷貝到協議引擎中

這個過程數據經歷的拷貝操做以下:
硬盤—>內核緩衝區—>協議引擎
sendfile原理解釋

4.2 定義客戶端請求的相關配置

keepalive_timeout

keepalive_timeout   timeout  [header_timeout];

設定保持鏈接超時時長,0表示禁止長鏈接,默認爲75s,能夠調整短點。

keepalive_requests

keepalive_requests  number;

在一次長鏈接上所容許請求的資源的最大數量,默認爲100

keepalive_disable

keepalive_disable   none | browser ...

對哪一種瀏覽器禁用長鏈接

send_timeout

send_timeout   time;

向客戶端發送響應報文的超時時長,此處是指兩次寫操做之間的間隔時長,而非整個響應過程的傳輸時長 

client_body_buffer_size 

client_body_buffer_size  size;

用於接收每一個客戶端請求報文的body部分的緩衝區大小;默認爲16k;超出此大小時,其將被暫存到磁盤上的由client_body_temp_path指令所定義的位置。注意,這裏是接收,不是下發數據,上傳文件到該網站,纔看獲得效果

client_body_temp_path 

client_body_temp_path  path [level1 [level2 [level3]]];

設定用於存儲客戶端請求報文的body部分的臨時存儲路徑及子目錄結構和數量

這裏指定的路徑下存放文件,目錄名爲16進制的數字,是通過hash運算後,利用hash的值的最後幾位數,依次分層,如三層目錄進行存放文件

例子

  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

4.3 對客戶端進行限制的相關配置

.1九、limit_rate

limit_rate   rate;

限制響應給客戶端的傳輸速率,單位是bytes/second,默認值0表示無限制

.20、limit_except  

limit_except  method ... { ... },僅用於location

限制客戶端使用除了指定的請求方法以外的其它方法

method:GET, HEAD, POST, PUT, DELETE,MKCOL, COPY, MOVE,OPTIONS, PROPFIND,PROPPATCH, LOCK, UNLOCK, PATCH

location {
limit_except   GET {
allow 192.168.1.0/24;
deny all;
} 
}

除了GET和HEAD 以外其它方法僅容許192.168.1.0/24網段主機使用

4.4 文件操做優化的配置

aio 

對於大文件採用aio,節省cpu,而對於小文件,採用sendfile,減小拷貝;而且對於大文件aio採用directio,避免擠佔文件系統緩存,讓文件系統緩存更多的小文件。

aio   on | off | threads[=pool];是否啓用aio功能,默認是on

directio 

directio  size | off;通常是異步

是否同步(直接)寫磁盤,而非寫緩存,在Linux主機啓用O_DIRECT標記,則文件大於等於給定大小時使用,例如directio  4m

open_file_cache

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指令所指定的次數的緩存項即爲非活動項,將被刪除

inactive=time 爲10分鐘;open_file_cache_min_uses爲3,表示在10分鐘內訪問低於3次表示非活動的,該文件就不會被緩存,會被清空

open_file_cache_errors 

open_file_cache_errors on | off;

是否緩存查找時發生錯誤的文件一類的信息,默認值爲off

open_file_cache_min_uses

open_file_cache_min_uses  number;

open_file_cache指令的inactive參數指定的時長內,至少被命中此處指定的次數方可被歸類爲活動項,默認值爲1

open_file_cache_valid

open_file_cache_valid  time;

緩存項有效性的檢查頻率,默認值爲60s

4.5 Nginx 之 實現https

要利用nginx軟件實現https的頁面,用到ngx_http_ssl_module模塊

一、ssl

ssl  on | off;

爲指定虛擬機啓用HTTPS  protocol,建議用listen指令代替

二、ssl_certificate

ssl_certificate  file;

當前虛擬主機使用PEM格式的證書文件

建立自簽名的證書文件

cd /etc/pki/tls/certs/
make nginx6.crt

將生成的私鑰文件解密

openssl rsa -in nginx6.key-out nginx66.key

將這兩個文件複製到配置文件裏指定的路徑便可

在客戶的上查看生成的證書信息,命令以下

openssl s_client -connect  www.e.com:443

三、ssl_certificate_key

ssl_certificate_key  file;

當前虛擬主機上與其證書匹配的私鑰文件

四、ssl_protocols

ssl_protocols [SSLv2] [SSLv3] [TLSv1] [TLSv1.1] [TLSv1.2];

 支持ssl協議版本,默認爲後三個,主流版本是[TLSv1.2]

五、ssl_session_cache 

ssl_session_cache off | none | [builtin[:size]] [shared:name:size];

builtin[:size]:使用OpenSSL內建緩存,爲每worker進程私有,開啓多大的空間來做爲緩存空間

[shared:name:size]:在各worker之間使用一個共享的緩存,這樣會提升緩存的命中率,提升性能。

六、ssl_session_timeout

ssl_session_timeout  time;

客戶端鏈接能夠複用sslsession cache中緩存的ssl參數的有效時長,默認5m

示例:

vim  /etc/nginx/conf.d/https.conf
server{
    listen 443 ssl;
    server_name www.e.com;
    root /app/website5;
    ssl_certificate /etc/nginx/ssl/nginx5.crt;
    ssl_certificate_key/etc/nginx/ssl/nginx5.key;
    ssl_session_cache shared:sslcache:20m;
    ssl_session_timeout 10m;
}
server{
    listen 443 ssl;
    server_name www.f.com;
    root /app/website6;
    ssl_certificate /etc/nginx/ssl/nginx6.crt;
    ssl_certificate_key/etc/nginx/ssl/nginx6.key;
    ssl_session_cache shared:sslcache:20m;
    ssl_session_timeout 10m;
}
示例配置

4.6 ngx_http_rewrite_module模塊:

將用戶請求的URI基於PCRE regex所描述的模式進行檢查,然後完成重定向替換

當舊的業務和新的業務不同,網站改名了,如網站名原來是www.dianping.com/zz後面更名爲www.dianping.com/zhengzhou 

一、rewrite 

rewrite regex  replacement  [flag]

將用戶請求的URI基於regex所描述的模式進行檢查,匹配到時將其替換爲replacement指定的新的URI

注意:若是在同一級配置塊中存在多個rewrite規則,那麼會自上而下逐個檢查;被某條件規則替換完成後,會從新一輪的替換檢查

 隱含有循環機制,但不超過10次;若是超過,提示500響應碼,[flag]所表示的標誌位用於控制此循環機制

若是replacement是以http://或https://開頭,則替換結果會直接以重向返回給客戶端

.[flag]:有如下幾個關鍵字

last:重寫完成後中止對當前URI在當前location中後續的其它重寫操做,然後對新的URI啓動新一輪重寫檢查;提早重啓新一輪循環

break:重寫完成後中止對當前URI在當前location中後續的其它重寫操做,然後直接跳轉至重寫規則配置塊以後的其它配置;結束循環,建議在location中使用

last 和break是在服務器內部操做的,客戶端不知道,客戶端訪問的url不會發生變化。可是服務器端會返回替換過的新的內容。

redirect和permanent是服務器端給客戶端發一個301或者302的請求,客戶端須要從新發起請求,所以最終客戶端看到的瀏覽器是url和原始的url是不同的,url會被轉換,如將fj改爲成fujian,那麼當用戶訪問的是http://172.18.50.73/fj/ 最終返回結果的時候,瀏覽器上的url會變動改成http://172.18.50.73/fujian/

redirect:臨時重定向,重寫完成後以臨時重定向方式直接返回重寫後生成的新URI給客戶端,由客戶端從新發起請求;不能以http://或https://開頭,使用相對路徑,狀態碼:302

permanent:重寫完成後以永久重定向方式直接返回重寫後生成的新URI給客戶端,由客戶端從新發起請求,狀態碼:301

例子

如下是正則表達式,$1表示前面的(.*).寫在server段或者location段裏,如下四個選項只需四選一。

rewrite ^/fj/(.*)$ /fujian/$1 last | break |redirect |permanent;
 

測試

curl  -L http://172.18.50.73/fj/

 或者直接在瀏覽器裏輸入http://172.18.50.73/fj/查看結果

二、return

return 返回一個具體的地址

return code [text];

return  code URL;

中止處理並將指定的代碼返回給客戶端。非標準代碼444關閉鏈接而不發送響應頭。

從版本0.8.42開始,能夠指定重定向URL(代碼301,302,303,307和308)或響應正文文本(對於其餘代碼)。響應正文文本和重定向網址能夠包含變量。做爲特殊狀況,重定向URL能夠指定爲此服務器本地的URI,在這種狀況下,根據請求方案($ scheme)和server_name_in_redirect和port_in_redirect指令造成完整的重定向URL。

此外,能夠將用於代碼302的臨時重定向的URL指定爲惟一的參數。這樣的參數應以「http://」,「https://」或「$ scheme」字符串開頭。 URL能夠包含變量。

測試,能正常返回text,

return URL;

中止處理,並返回給客戶端指定的響應碼。可是實際測試都是屢次循環重定向,致使url不能打開,用curl命令測試,出現了報錯:curl: (47) Maximum(50) redirects followed致使實驗不成功

三、rewrite_log

rewrite_log  on | off;

是否開啓重寫日誌, 發送至error_log(notice level)

四、set 

set  $variable value;

用戶自定義變量,注意:變量定義和調用都要以$開頭 

五、if

if  (condition) { ... }

引入新的上下文,條件知足時,執行配置塊中的配置指令;server,location

condition:比較操做符:

== 相同

!= 不一樣

~:模式匹配,區分字符大小寫

~*:模式匹配,不區分字符大小寫

!~:模式不匹配,區分字符大小寫

!~*:模式不匹配,不區分字符大小寫

文件及目錄存在性判斷:

-e, !-e  存在(包括文件,目錄,軟連接)

-f, !-f  文件

-d, !-d 目錄

-x, !-x 執行

4.7 ngx_http_referer_module模塊

 referer是指從哪兒跳轉,該字段能夠用來防止盜鏈。

好比網頁內有代碼<a href=http://172.18.50.73/m.txt>test referer </a>那麼再網頁上test referer就會有連接到資源http://172.18.50.73/m.txt上,點擊該連接,log就會有對應的referer在code以後,如這裏是http://172.18.50.73/a.html,若是沒有referer,則code後的字段顯示「-」

.一、valid_referers  none|blocked|server_names|string...;

定義referer首部的合法可用值,不能匹配的將是非法值

none:請求報文首部沒有referer首部

blocked:請求報文有referer首部,但無有效值

server_names:參數,其能夠有值做爲主機名或主機名模式

arbitrary_string:任意字符串,但可以使用*做通配符

regular expression:被指定的正則表達式模式匹配到的字符串,要使用~開頭,例如:~.*\.magedu\.com

.示例:

valid_referers  none blocked  server_names  *.sunny.com   ~\.sunny\.~\.baidu\.;

 #定義有效的referers

if ($invalid_referer) {
return 403;
}

 #定義若是出現無效的referer將返回code 403

相關文章
相關標籤/搜索