高性能web服務器nginx---理論篇

一、Nginx介紹

1.1 功能描述

Nginx的功能包括基本的HTTP功能和擴展功能。和Apache服務器一樣,Nginx服務器爲了提供更多的功能並且能夠有效地擴展這些功能,使用了模塊化的方式來擴展其功能。每一個模塊都提供了一個功能,通過編譯這些功能模塊來實現功能的擴展。

 

1.2 基本HTTP功能

提供靜態文件和index文件,生成自動索引,打開文件描述符緩存;

使用緩存加速反向代理,簡單的負載均衡和容錯;

使用緩存機制加速遠程FastCGI服務器的訪問,簡單的負載均衡和容錯;

模塊化的結構,過濾器包括gzip、字節rangechunk響應、 XSLTSSI和圖像大小調整(確切地說是將大圖轉換爲小圖)過濾,被傳遞到後臺度武器(FastCGI或者是代理服務器)多個SSI指令在單個頁面的並行處理;

支持SSL TLS SNI

 

1.3 擴展HTTP功能

基於名稱和基於IP的虛擬服務器;

支持Keep-alive 和管道連接;

靈活的配置;

重新配置和在線升級而不用終端對客服訪問的處理;

訪問日誌的格式,緩存日誌寫入和快速日誌輪詢;

3xx-5xx 錯誤代理重定向;

重寫模塊;

基於客戶端IP地址和HTTP基本認證的訪問控制;

基於HTTP協議的PUTDELETEMKCOLCOPYMOVE方法;

FLV流文件;

速度限制;

限制同時連接數或者是來自同一個IP地址的請求;

嵌入式Perl語言解析;

 

1.4 架構和擴展性:

一個master進程和幾個workers進程,workers進程有非特權用戶運行;

消息通知方法:epoll(Linux 2.6+)kqueue(FreeBSD 4.1+)rt singnals(Linux 2.2.19+),/dev/poll(Solaris 7 11/99+),event ports(Solaris 10).select,and poll

支持kqueue的各個功能,包括EV_CLEAREV_DISABLE(禁用臨時事件),NOTE_LOWATEV_EOFnumber of available data,錯誤代碼;

支持sendfile(FreeBSD 3.1+, Linux 2.2+, Mac OS X 10.5), sendfile64 (Linux 2.4.21+),sendfilev(Solaris 8 7/01+)

AIO(FreeBSD 4.3+, Linux 2.6.22+) 支持;

支持Accept-filters(FreeBSD 4.1+) TCP_DEFER_ACCEPT(Linux 2.4+)

10000個非活動HTTP keep-alive連接僅用掉2.5MB內存;

數據複製操作控制在最低限速。

 

總結:非擁塞、事件驅動、單線程、一個masterNworker、高效的資源使用、高度的模塊化;

 

二、Nginx模塊介紹

Nginx核心模塊:包括Nginx的內核模塊(CoreModule)和事件驅動模塊(EventsModule)

HTTP服務模塊:這類模塊包括三類模塊,即HTTP的內核模塊(HTTPCoreModule)和標準模塊以及可選的HTTP模塊。

 

   2.1  Nginx的核心模塊

. 配置示例

# user nginx;

worker_processes 1;

 

#error_log logs/error.log;

#error_log logs/error.log notice;

#error_log logs/error.log info;

#pid logs/nginx.pid;

 

. 核心模塊指令

指令名稱:error_log

語法:error_log file [ debug | info | notice | warn | error |crit ]

默認值:$(prefix)/logs/error.log

功能:用於Nginx服務器(包括FastCGI) 指定記錄錯誤日誌文件和記錄錯誤的級別。日誌的級別有debuginfo notice warn error crit (詳細程度由高到低:debug提供了全部日誌記錄,而crit僅報告了關鍵錯誤)。

注意:不要認爲設置error_log off能夠關閉日誌記錄功能,相反這樣會將日誌寫入到一個文件名爲off的文件中。如果想關閉錯誤日誌功能,則可是使用一下配置:

error_log /dev/null crit;

 

指令名稱:lock_file

語法:lock_file file

功能:Nginx使用了連接互斥鎖進程順序的accept()系統調用,如果使用Nginx使用gccIntel C++或者是SunPro C++i386amd64sparc64ppc64編譯創建,那麼Nginx服務器將自動採用異步互斥進程訪問控制,而在其他情況下鎖文件會被使用,默認是不使用,除非在編譯時開啓了該功能。

例如:

lock_file /var/log/lock_file;

 

指令名稱:pid

語法:pid /var/log/nginx.pid;

功能:用於設定Nginxpid文件位置。

 

指令名稱:include

語法:inculde file|*

功能:用於載入配置文件。如果沒有指定絕對路徑,那麼文件的路徑將會和配置文件的目錄關聯,換而言之,Nginx會認爲與配置文件在同一目錄下;

例如:

include conf/ssl.conf

include vhosts/*.conf

 

指令名稱:timer_resolution

語法:timer_resolution t

功能:指令用於縮短gettimeofday()系統調用的時間,默認情況下gettimeofday()kevent()epoll/dev/pollselect()poll()調用完成之後調用。如果在具體的使用中需要一個筆記標準的時間來記錄$upstream_response_time或者$msec變量。那麼將會使用到該指令。

例如:timer_resolution 100ms;

 

指令名稱:user

語法:user user [group]

功能:如果master進程是以root用戶來運行的,那麼Nginx將會使用setuid()/setgid()來實現UER/GROUP的接替工作。如果沒有指定GROUP,那麼Nginx將會使用同USER一樣的組名稱。默認情況下,使用nobody用戶名稱和nobody組名稱;或者在配置./configure 腳本時指定--user=USER --group=GROUP來實現。

 

指令名稱:worker_cpu_affinity

語法:worker_cpu_affinity cpumask ...;

功能:該指令只能用於Linux,設置worker進程與CPU的親和力。該指令允許通過調用sched_setaffinity() worker進程綁定到一個CPU上。

例如:

worker_processes 4;

worker_cpu_affinity 0001 0010 0100 1000;

# 設置將每一個進程綁定到一個CPU上。

worker_processes 2;

worker_cpu_affinity 0101 1010;

# 設置將第一個worker綁定到CPU0/CPU2;將第二個worker綁定到CPU1/CPU3

對於超線程(HTT) CPU合適。

 

指令名稱:worker_priority

語法:worker_priority [-] number

功能:指令用於指定worker進程的優先級,從-20(最高級)19(最低級),默認爲0

注意:Kernel進程運行在-5優先級,因此不建議設置-5或更小;

 

指令名稱:worker_processes

語法:worker_processes Number

功能:如果Nginx提供SSL或者gzip,即對CPU的使用率較高,並且系統中有兩個以上的CPU或者內核,那麼可以設置worker_processes的值爲CPU的數量或者是內核的數量。如果提供了大量的靜態文件,並且中的數量超過了有效的內存大小,那麼可以增加該指令的值,以便於充分利用磁盤的寬帶。另外,如果想要將worker進程保定到某個CPU或者內核上,則可以使用worker_cpu_affinity指令。

建議:worker線程的個數;通常應該爲物理CPU核心個數減1

 

指令名稱:worker_rlimit_nofile

語法:worker_rlimit_nofile limit

功能:用於定義一個worker進程可以同時處理的文件數量,也就是說一個worker進程所能夠打開的最大文件句柄數;

 

名稱名稱:worker_rlimit_sigpending

語法:worker_rlimit_sigpending Number

功能:定義每一個用戶(調用進程的用戶ID)能夠被排入隊列的信號(signals)數量。如果隊列(queue)滿了,但由於這個限制,信號(signals)會被忽略,也就是說每個用戶能夠發往worker的信號的數量;

 

2.2 Nginx事件模塊

.配置示例

events {

 worker_connections 1024;

}

 

.時間模塊指令

指令名稱:accept_mutex_delay

語法:accept_mutex_delay Nms;

默認值:500ms

功能:如果一個工作進程 (worker process) 沒有互斥鎖,那麼它將至少在這個設定值的時間之後纔會被回收。

 

指令名稱:worker_connections

語法:work_connections number

默認值:1024

功能:該指令用於設置每個worker進程所處理的連接數。

通過worker_connections worker_processes指令能夠計算最大客戶端連接數:

max_clients = worker_processes * worker_connections

在反響代理的環境中,最大客戶端連接數變爲:

max_clients = worker_processes * worker_connections/4

原因在於,默認情況下一個瀏覽器會對服務器打開兩個連接,Nginx使用來自於同一個池中的FDS(文件描述符)來連接上游的服務器。

 

指令名稱:use

語法:use type

功能:如果在執行./configure 的時候指定了不只一個事件模型,那麼在使用Nginx時候可以通過該指令告訴Nginx想使用的事件驅動模型。默認情況下,Nginx在編譯時會檢測系統,並且Nginx會根據所在操作系統選擇一個最適合的事件驅動類型。可選擇的值:/dev/pollepolleventportkqueuertsig、或select

 

指令名稱:multi_accept

語法:multi_accept [ on| off ]

功能:定義Nginx是否立即接收從所有監聽隊列進入的連接。也就是說 multi_accept會在Nginx接到一個新的連接後立即發出通知後調用accept()來接收儘量多的連接。

 

指令名稱:accept_mutex

語法:accept_mutex [ on | off ]

默認值爲:on

功能:Nginx使用連接互斥鎖(mutex) 進行順序的accept()系統調用。

 

指令名稱:accept_mutex_delay

語法:accept_mutex_delay Nms;

功能:定義一個worker進程在嘗試再次獲取資源之前應等待的時間。如果指令accept_mutex設置爲off,那麼該值(指的是accept_mutex_delay的值),如果不能使用。單位爲毫秒(milliseconds)

 

2.3 NginxHTTP核心模塊

①、配置結構

http {

 

 ...

 

server {

listen 80;

server_name www.sharelinux.com;

 

....

 

location / {

root html;

index index.html index.htm;

...

}

}

 

}

 

.HTTP核心模塊指令

指令名稱:aio

語法:aio [ on | off | sendfile ]

使用環境:http, server , location

功能:對應Linux來說還需要配合使用directio指令。另外如果使用了該指令,那麼將會自動禁用sendfile的支持。

例如:

location /video {

aio on;

directio 512;

output_buffers 1 128k;

}

 

指令名稱:alias

語法:aliasfile-path|directory-path

功能:該指令用於指定一個路徑、但是不同於root指令;

例如:

location /i/ {

alias /webroot/images/;

# 這裏可以理解爲:把/webroot/images/看做爲/i/image目錄下的文件和i目錄下的文件一一對應;

}

 

location /m/ {

root /webroot/images/;

#  這裏可以理解爲:把/webroot/images/映射爲i目錄所在的根/image目錄下還需要建立m目錄;

}

注意:root表示指明路徑爲對應location的“ /” URL;alias表示路徑映射,即location中的URL是相對於alias所指明的路徑而言;如果還是不理解可以查看訪問日誌;

 

指令名稱:client_body_in_single_buffer

語法:client_body_in_single_buffer

功能:用於指定是否將整個客戶端的請求保存在單個請求緩存中。爲了減少複製操作,當使用變量$requset_body的時候推薦使用該指令。

注意:當請求體不能被單個緩存(參照client_body_buffer_size)容納下的時候,那麼請求體將會保存在磁盤上。

 

指令名稱:client_body_buffer_size

語法:client_body_buffer_size the_size

默認值:8k/16k

功能:指定客戶端請求體緩存的大小。如果請求體大於該緩存大小,那麼整個請求體或者請求體的某些部分將會被寫入臨時文件。

默認值等於兩個頁面大小,頁面的大小依賴於所在的操作系統平臺,可能是8k或者是16k。當請求中Conten-Length的值小於指定緩存的大小時,那麼Nginx將會使用較小的一個緩存,因此Nginx也並非總是爲每一個請求分配指定大小的緩存。

 

指令名稱:client_body_temp_path

語法:client_body_temp_path dir-path [ level1 [level2 [level 3 ] ] ]

默認值:client_body_temp

功能:用於指定一個存儲臨時文件的目錄,在這個目錄中將會存儲客戶端請求body體。按照指定子目錄等級,可能也會有三級目錄。例如:

client_body_temp_path /tmp/nginx/clent_temp 1 2;

那麼目錄的存儲結構將會是:

/tmp/nginx/clent_temp/6/36/00001234568

 

指令名稱:client_body_timeout

語法:client_body_timeout N;

默認值:60

功能:該指令用於設置讀取客戶端請求標題的超時時長。這個超時僅指一個請求的請求頭還沒有進入請求頭的讀取步驟時的超時時長,如果在這個設定的時長內客戶端沒有發送任何數據,那麼Nginx將返回“Request time out (408)

 

指令名稱:client_max_body_size

語法:client_max_body_size 1m

功能:用於設定客戶端請求體的最大值,在客戶端請求中通過Content-Length表明。如果客戶端請求體大於指定的值,那麼客戶端將會收到一個“
Request Entity Too Large
(413) 的錯誤。

 

指令名稱:default_type

語法:default_type MIME-type

默認值:default_type text/plain

功能:用於指定一個默認的MIME類型,對於沒有標準的MIME匹配的文件類型將會使用該類型。

 

指令名稱:directio

語法:directio [ size | off ]

功能:用於啓動O_DIRECT (FreeBSD,Linux),F_NOCACHE (Mac OS X)標誌或者directio()函數(Solaris),對於大於該指定大小的文件,那麼僵啓用這種方式讀取該文件。如果啓動該指令,則將禁用sendfile。例如:

directio 4m;

 

指令名稱:error_page

語法:error_page coed [code...] [=| =answer-code ] URI | @name_location

功能:用於指定一個URI,在訪問出錯的時候將會顯示該頁面。

error_page  404 /404.html;

error_page 502 503 504 /50x.html;

error_page 403 http://www.sharelinux.com/forbiddent.html;

error_page 404 -  @fetch;

 還可以通過該指令將一個狀態碼改變爲另一個狀態碼。例如:

error_page 404 =200 /empty.gif;

error_page 404 =403 /forbidden.gif;

另外,還可以通過等號 =’來使用自己設計的錯誤處理程序來決定指定錯誤代碼的返回狀態,例如:

error_page 404 =  /404.php

注意:這個“=”後沒有狀態碼

如果重定向中不需要改變URI,那麼可以通過以下方法將錯誤處理傳遞到一個命名的location中:

location / {

error_page 404 @fallback;

}

 

location @fallback {

proxy_pass http://backend;

}

 

指令名稱:keepalive_disable

語法:keepalive_disable [ msie6 | safari | none ]

默認值:msie6 safari

功能:用於禁用某些用戶帶來的keepalive功能。

 

指令名稱:keepalive_timeout

語法:keepalive_timeout [ time ] [ time ]

默認值:keepalive_timeout 75

功能:該指令有兩個參數,第一個參數用於設定客戶端keep-alive連接超時,在這個時間過後,服務器將會關閉連接。第二個選項是一個可選項,它的值決定了響應頭Keep-Alivetimeout="time"的值,這個頭能夠告訴一些瀏覽器關閉連接,這樣故武器就不用再次關閉連接了。如果沒有設置這個參數,那麼Nginx將不會發送Keep-Alive頭,兩個參數的值可以不相同。

 

指令名稱:keepalive_requests

語法:keepalive_requests N

默認值:keepalive_requests 100

功能:用於設置Nginx服務器能夠保持活躍的連接數。

 

指令名稱:large_client_header_buffers

語法:large_client_header_buffers Number Size

默認值:large_client_header_buffers 4 4k/8k

功能:指令用於指定客戶端一些比較大的請求頭使用的緩衝區數量和大小。

 

指令名稱:limit_except

語法:limit_except methods {...}

功能:該指令用於限制訪問location HTTP方法。例如:

limit_except GET {

allow 192.168.1.0/24;

deny all;

}

 

 指令名稱:limit_rate

語法:limit_rate speed

功能:用於限制流量

 

指令名稱:limit_rate_after

語法:limit_rate_after time

默認值:limit_rate_after 1m

功能:用於限制流量

 

指令名稱:listen

語法:listen address:port [ default_server | [ backlog=num | rcvbuf=size | sndbuf=size | accept_fiter=filter | deferred |bind|ipv6only=[on|off] | ssl ]]

功能:用於指定Server{...}區段設置接收請求的IP地址和端口。可以僅指定一個IP地址、一個端口或者是一個服務器的名字作爲地址,例如:

listen 127.0.0.1;

listen 127.0.0.1:8080;

listen *:8088;

listen localhost:8000

這些參數必須跟隨在default_server參數之後。

backlog=num參數:指定調用listen(2)backlog的值,默認爲-1

rcvbuf-size參數用於設置監聽套接字的SO_RCVBUF參數值;

sndbuf-size參數用於設置監聽套接字的SO_SNDBUF參數值;

accept_filter=filter參數:設置過濾器的名字,該參數僅用於FreeBSD,有兩個過濾器datareadyhttcodeady

deferred參數:設置該參數表示延時accep(2)t Linux中使用TCP_DEFER_ACCEPT選項;

bind參數:該參數指定將bind(2)分開調用;

ssl參數:該參數用於監聽SSL

例如:

listen 80;

listen 443 default_server ssl;

 

指令名稱:location

語法:location[=|~|~*|^~|[@] /uri/ ] {...}

功能:允許根據用戶請求的URI來匹配定義的各location,匹配到時,此請求將被相應的location塊中的配置所處理;

=: 精確匹配檢查;

~: 正則表達式模式匹配,區分字符大小寫;

~*:正則表達式模式 匹配,不區分字符大小寫;

^~URI的前半部分匹配,不檢查正則表達式;

 

匹配優先級:精確匹配(=)^~~~*、由不帶符號的URL進行左側匹配

 

指令名稱:open_file_cache

語法:open_file_cache max = N [inactive = time ] | off

默認值:open_file_cache off

指令選項:

Max:該選項用於指定緩存條目的最大值,當緩存滿後,根據最近最少(LRU)算法將緩存條目移除;

Inactive:用於指定一個非活動時間,如果在這個時間內緩存的條目沒有被訪問,那麼該條目將會被刪除,默認值爲60秒;

Off:禁止緩存;

可以緩存的信息如下:

  打開文件的描述符、文件的大小和修改時間信息;

  目錄存在性的信息;

  在搜索文件過程中出現的錯誤信息---找不到文件、沒有讀取的權限等。

open_file_cache max=1000 inactive=20s;

open_file_cache_valid 30s;

open_file_cache_min_uses 2;

open_file_cache_errors on;

 

指令名稱:open_file_cache_errors

語法:open_file_cache_errors on|off

默認值:open_file_cache_errors off

功能:開啓或禁用緩存文件錯誤。

 

指令名稱:open_file_cache_min_uses

語法:open_file_cache_min_uses number

默認值:open_file_cache_min_uses 1

功能:用於指定的時間內一個文件被訪問的最少次數,如果訪問的次數大於這個值,那麼該文件的描述符將會被緩存到緩存中。

 

指令名稱:open_file_cache_valid

語法:open_file_cache_valid time

默認值:open_file_cache_valid 60

功能:指定了檢測緩存信息的間隔(open_file_cache指令相關)

 

指令名稱:root

語法:root path

默認值:root html

功能:指定了一個請求的根文檔目錄。

 

指令名稱:satisfy

語法:satisfy [ all | any ]

All:需要所有條件都有效;

Any:至少一個有效;

例如:

localtion / {

satisfy any;

allow 172.16.0.1/24;

deny all;

auth_basic "Closed site";

auth_basic_user_file conf/.htpasswd;

}

客戶端訪問該資源有兩個條件。

使用satisfy all,客戶端必須滿足以上兩個條件才能夠訪問該資源;使用satisfy any,客戶端只需要滿足任意一個條件就可以訪問該資源;

 

指令名稱:send_timeout

語法:send_timeout Time

默認值:send_timeout 60

功能:設置響應超時,當超過這個設定的時間後,Nginx將會關閉一個不活動的連接。當一個連接變爲非活動狀態的那一刻起,客戶端便停止傳輸數據。需要注意的是,這個超時的確定不是整個傳輸響應的時間,而是兩個讀操作之間的時間,如果在這個時間內,客戶端沒有進行任何操作,那麼Nginx將會關閉連接。

 

指令名稱:sendfile

語法:sendfile [ on|off ]

默認值:sendfile off

功能:用於設置是否使用sendfile(),由於這種方法是在內核中進行操作的,因此sendfile()read(2)write(2)的寫作操作更有效,這是由於read-wirte有一個從用戶空間傳遞數據的過程。

 

指令名稱:server

語法:sever {...}

功能:用於設置虛擬主機。

 

指令名稱:server_name

語法:server_name name […]

功能:指令執行以下兩個動作。

將進入的HTTP請求的主機頭(Host header) Nginx配置文件中各個Server{...}區段比較,並且選擇第一個被匹配的Server區段---這就是如何確定虛擬主機。服務器名字(Server name) 按照以下順序處理:

全域名,靜態域名;

開始部分使用通配符的域名,例如:*.sharelinux.com;

結尾部分使用通配符的域名,例如:www.sharelinux.*;

帶有正則表達式的域名;

如果沒有找到匹配的server,那麼會按照下面的順序在配置文件中選擇一個server{...};

匹配listen指令被標記爲:[ default|default_server ]server區段;

②匹配listen指令(或着隱含有listen 80)的第一個server區段(或者隱含有listen 80)

 

指令名稱:tcp_nodelay

語法:tcp_nodelay [on|off]

默認值:tcp_nodelay on

功能:用於允許或禁止使用套接字選項TCP_NODELAY。這個選項只對keep-alive連接有效。

 

指令名稱:tcp_nopush

語法:tcp_nopush [on|off]

默認值:tcp_nopush off

功能:用於允許或禁止使用套接字選項TCP_NOPUSH(FreeBSD系統中)或者TCP_CORK(Linux系統中),該選項僅在使用sendfile時有效。如果tcp_nopush設置爲on,那麼Nginx將會嘗試在被一個TCP數據包中發送整個HTTP響應頭。

 

指令名稱:try_files

語法:try_files path1 [path2] uri

功能:用於順序檢測文件的存在性,並返回第一個找到的文件。$uri/表示是一個目錄,即$uri之後緊跟一個斜線"/"。如果沒找到文件,那麼最後的參數內部重定向將會被使用,最後一個可以使用的參數必須存在,否則將會產生內部錯誤。不像rewrite$args不會自動保存,因此如果最後的蠶絲不是一個命名的location,則需要明確指出。

例如:

try_files $uri $uri/ /index.php?q=$uri$args;

 

指令名稱:types

語法:types {…}

功能:用於設置響應請求文件的文件類型。默認的映射如下:

types {

text/html html;

image/git git;

image/jpeg jpg;

}

完整的映射表包含在conf/mime.types中。

 

 

Nginx工作原理:

 

 

三、Nginx模型設計與Linux五種IO模型

3.1 同步和異步synchronous, asynchronous

  關注的是消息通知機制;

 

  同步:調用發出不會立即返回,但一旦返回就可以返回最終結果;

  異步:調用發出之後,被調用方立即返回消息,但返回的非最終結果;被調用者通過狀態、通知機制來通知調者,或通過回調函數來處理結果;

 

3.2 阻塞和非阻塞block, nonblock

  關注的是調用等等調用結果(消息、返回值)時的狀態

 

  阻塞:調用結果返回之前,調用者(調用線程)會被掛起;調用者只有在得到結果之後纔會返回;

  非阻塞:調用結果返回之前,調用不會阻塞當前線程;

 

3.3 五種I/O模型

阻塞型IO [blocking IO]

非阻塞型IO [nonblocking IO]

複用型IO [IO multiplexing] (slectpoll複用器)   備註:httpd peforkhttpd worker

信號驅動型IO [signal driven IO] (epoll)  備註:httpd event

異步IO [asyncrhonous IO]  備註:nginx

 

3.4 IO工作流程模型:

. 阻塞IO模型wKiom1Sg9V-D8SatAACU7AUefNY010.jpg

 

. 非阻塞IO模型

wKiom1Sg9Vzhe6q8AAElPUJ987I344.jpg

. 複用IO模型

wKioL1Sg9g_TkXEqAAD8CG7Umko374.jpg

.信號驅動IO模型

wKiom1Sg9V3yyfb0AADyVb8OvuE969.jpg

. 異步IO模型

wKioL1Sg9hHzyaNCAAC52mj3xa8791.jpg

 

 

四、Nginx設計架構圖

wKioL1Sg9g6Ta_4zAAMJnMvqxbA383.jpg


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章