第一部分:
html
Nginx介紹及原理簡單分析nginx
快速入門web ------------------------正則表達式
關於Nginx,咱們能夠到其官網 http://nginx.org/ 以及WIKI http://wiki.nginx.org 進行下載和了解。算法
咱們能夠看一下下面的英文介紹:apache
Nginx (pronounced engine-x) is a free, open-source, high-performance HTTP server and reverse proxy, as well as an IMAP/POP3 proxy server. Igor Sysoev started development of Nginx in 2002, with the first public release in 2004. Nginx now hosts nearly12.18% (22.2M) of active sites across all domains. Nginx is known for its high performance, stability, rich feature set, simple configuration, and low resource consumption.後端
從上面的,咱們大概能夠知道以下信息:瀏覽器
第一,Nginx是一個開源,免費的高性能HTTP服務器和HTTP/MAIL反向代理服務器。緩存
第二,自2004以來,Nginx的使用佔比逐漸上升,目前大概佔有WEB SERVER市場的12%。bash 【咱們能夠經過http://www.netcraft.com/來看一下目前主流的WEB SERVER的使用趨勢。】
第三,Nginx具備高性能,穩定性,豐富的特性,簡單的配置,低資源佔用等特色。
什麼是正向代理/代理服務器 and 反向代理/反向代理服務器?
正向代理示意圖:
反向代理示意圖:
通俗點說,正向代理中的代理服務器比如「管家」,由這個「管家」幫你作事情,而反向代理中的反向代理服務器比如「祕書」,要想見領導必須經過「祕書」。 在正向代理中,客戶機須要明確的知道「管家」的一些信息,如IP,PORT等;可是在反向代理中,客戶請求的是「領導」,他並不知道在這過程當中「祕書」發揮了做用。
Nginx的工做模式及原理簡單分析
同Apache http server的Perfork工做模型相似,Nginx也有master,worker進程的概念。
第一,很顯然,啓動Nginx,就必須在端口啓動監聽服務,也就是套接字(ip+port),一般Nginx做爲WEB SERVER和反向代理服務器都會在80端口監聽。在LINUX上,要開啓<1024端口的監聽服務,必須用特權身份運行,也就是說master進程應該以root身份啓動。
第二,那麼master進程主要的職責是什麼?
讀取並驗證配置信息 建立,綁定,關閉套接字 啓動,終止,維護worker進程的個數
master負責管理worker進程,這一點好理解,須要注意的是master在處理配置信息這一塊。
假設nginx已經啓動,咱們更改配置文件後reload,若是這個配置文件語法有誤,nginx會怎麼作? 若是這個配置文件OK,nginx又會怎麼作?
若是配置文件有誤,reload後,master會提示配置錯誤,並不會影響請求的處理。 若是配置文件OK,reload後,何時生效呢?
Nginx支持熱部署!!!
若是主配置文件發生改變,那麼並不會馬上影響到WORKER進程,而是MASTER等到WORKER進程的鏈接請求處理完畢後KILL掉這個WORKER進程,而後從新生成一個WORKER進程,這樣這個WORKER進程就將以新的配置啓動了。也就是說,老的鏈接用老的配置,新的鏈接用新的配置。從新加載配置文件不會中斷正在處理的請求。
第三,worker進程是幹嗎的?咱們應該有多少個Worker進程?每個Worker進程中有多少個線程?
在Nginx中,鏈接請求由爲數很少的幾個僅包含一個線程的進程worker以高效的迴環機制進行處理,而每一個worker能夠並行處理數千個的併發鏈接和請求。
Worker進程的個數,這個是能夠配置的,可是通常而言,個數應該和CPU個數一致性,主要是爲了CPU的進程切換。
what can worker process do ? 接受,傳入並處理來自客戶端的鏈接; 提供反向代理等功能;
第四,worker進程如何處理請求的?
當一個請求來了,那麼多個worker進程,誰去處理,仍是幾個一塊兒處理?如何處理?
首先,要清楚的是,一個請求能夠由一個worker進程處理並只能由這個worker進程徹底處理。 Nginx在內部實際上是維護了一個accept_mutex,其實就是一個鎖,確保在某一時刻,一個請求只能被 一個worker進程捕獲。當一個worker進程在accept這個鏈接以後,就開始讀取請求,解析請求,處理請求,產生數據後,再返回給客戶端,最後才斷開鏈接,這樣一個完整的請求就是這樣的了。
Nginx採用了異步非阻塞事件驅動的方式來處理請求的,只要咱們設置好WORKER進程個數與CPU的親緣性綁定,那麼就能減小CPU在進程間切換所花費的時間以及切換帶來的進程的保存/恢復現場,同時,因爲Nginx中一個worker裏面只有一個線程,也避免了線程的上下文切換。
第五,異步/非阻塞/事件驅動???
咱們知道,不少請求來了,他們大多須要讀寫數據,發生IO請求,此時程序就會發生中斷,若是此時咱們一直等待IO調用結束,才繼續工做,那麼這種就是阻塞的,那麼很顯然不少請求來了,都處於等待狀態,CPU就將處於空閒狀態,爲了提供高併發的能力,Nginx採用的是非阻塞的方式。若是發生IO中斷,那麼你去作你的事情,可是過一段時間來看看IO調用是否結束,這就是非阻塞:你能夠作更多的事情,可是你得時不時的檢查中斷狀態,帶來的開銷也不小。
爲了更高效,Nginx利用了LINUX的EPOLL模型(其餘系統相似): EPOLL模型,提供一種事件驅動機制,它能夠監控多個事件是否準備好了,若是準備好了,那麼就放入EPOLL隊列中。這種機制是異步的。經過這樣,WORKER進程只須要循環處理EPOLL隊列中的請求,咱們只須要在請求間不斷切換,而這種切換是不須要付出什麼代價的,經過這種循環處理已經準備好的請求,從而Nginx能夠高效的處理高併發的問題。
好了,到這裏,咱們應該對Nginx的原理有些認識了,下面經過Nginx提供的一些具體功能來加深認識。
|
第二部分:
Nginx做爲Web Server詳解
安裝與初步使用 ------------------------
咱們能夠直接到NGINX的官網下載最新的穩定版,好比1.6.2。 Nginx很是輕量級,編譯安裝的過程很是快。
能夠發現,在編譯中,咱們指定了nginx的owner,group爲咱們新建的系統用戶和組。
須要指定一些臨時目錄路徑,並確保在啓動NGINX時,這些臨時目錄是存在,不然可能啓動出錯。
因爲Nginx是基於模塊化的方式設計的,因此咱們須要清楚哪些模塊是默認編譯安裝的?
./configure --help的方式,能夠得到這些信息,若是是with-somemodule,說明這個module默認是不編譯的,要想使用,必須顯式的使用with;若是是without-somemodule,說明這個module默認是編譯的,不想編譯的話,必須顯式的使用without。
在安裝過程當中,極可能遇到缺乏一些軟件包,直接利用YUM的方式安裝便可。
啓動Nginx
根據編譯時指定的可執行命令路徑,
便可啓動Nginx
查看監聽端口:
咱們也能夠經過瀏覽器或者直接curl的方式訪問Nginx爲咱們提供的首頁。
咱們的主戰場:nginx.conf
配置文件分析 ------------------------
worker_processes表示啓動WORKER進程的個數,而worker_connections表示每一個WORKER進程最多能夠處理的鏈接。那麼,咱們最多支持的鏈接數 爲 worker_processes * worker_connections。上面的,都是全局的配置。
下面,咱們重點分析的是http段的server配置。
指令以分號結束。 每個server用來定義一個虛擬主機,Nginx必須採用這樣的方式來進行配置。 可見Nginx支持基於ServerName和Port的虛擬主機。 咱們須要重點理解和注意的是location中的uri配置:
location [ = | ~ | ~* | ^~ ] uri { ... }
說明location在支持uri方面,有以下形式:
location uri {} 對這個uri下面的全部路徑(包括子路徑)都有效 匹配範圍很大
location = uri {} 只對當前路徑生效,注意若是此uri是一個目錄,那麼並不會對這個目錄下的有效,僅僅當這個uri是文件的時候纔有效。 精確匹配到具體的文件路徑,對目錄無效
location ~ uri {} 模式匹配,就是正則 區分大小寫 uri此時就是一個正則表達式
location ~* uri {} 同上,也是模式匹配,不區分大小寫
location ^~ uri {} 不使用正則表達式
那麼一個請求URL來了,匹配優先級是?
優先級從高到低 = ^~ ~和~* 不使用其餘任何符號的
舉個例子: http://servername:port/bbs/....
那麼會首先尋找location = /bbs 的進行匹配,而後看不使用模式匹配的location ^~ uri可否匹配,如不匹配,繼續看使用模式匹配的可否匹配location ~ uri / location ~* uri,若是模式匹配也不成功,那麼看location uri是否包含這個路徑,若是最後不包含這個路徑,那麼就是404頁面了。
看下面的一個實例配置:
在/web目錄下有bbs,sports目錄
也就是說,root/uri的方式共同定位到文件資源的路徑。
訪問控制法則 基於IP地址的(deny/allow形式,注意默認狀況下是allow all的) 基於用戶/密碼的(auth_basic 採用htpasswd生成用戶密碼文件便可)
在location中能夠 autoindex on 來列出文件
在SERVER段中,能夠經過定義以下location來在網頁上顯示NGINX的狀態信息
說明: Active connections表示活動的鏈接數。 accepts/handled表示已經接受/處理的鏈接數 requests表示已經處理的請求。 【注意,在一個鏈接中,能夠處理多個請求】 reading表示nginx reads request header writing表示nginx reads request body ,process request or writes response to a client waiting表示keep-alive connections,actually it is active (reading + writing)
/usr/sbin/nginx #啓動Nginx /usr/sbin/nginx -t #檢查nginx.conf配置文件是否有誤 /usr/sbin/nginx -s reload #從新載入配置文件 /usr/sbin/nginx -s stop #中止nginx
到這裏,Nginx的基本使用以及做爲web server配置方面,就差很少了。
|
第三部分:
關於反向代理
作一個實驗來講明反向代理:
request -> nginx -> apache http://www.zfz1.com:80/bbs請求到達nginx,被反向代理到Apache上,經過虛擬主機的方式進行響應http://www.zfz1.com:8080/bbs
直接上配置:
nginx.conf:
apache虛擬主機配置:
/etc/hosts配置:
/web/bbs/index.html:
驗證:
從配置上,其實反向代理就是在location中用proxy_pass取代了root而已。
關於access_log的說明:
因爲,咱們使用了反向代理,Apache接收到的請求都是來自nginx的,那麼access_log中記錄的IP等信息其實都是nginx的信息,這樣顯然不是咱們想要的,咱們但願日誌中記錄的是真實的客戶端信息,這樣之後有利於咱們進行日誌分析。
其實,請求會在nginx這一端進行封裝,咱們能夠自定義一些http header,好比:
$XXX爲Nginx內置的HTTP變量,好比:$remote_addr
這些內置的變量,咱們能夠通官方文檔來查閱:http://nginx.org/en/docs/http/ngx_http_core_module.html#variables
利用proxy_set_header進行HTTP HEADER設置,那麼咱們就能夠在APACHE的LOGFORMAT中進行引用YOUR_HEADER_NAME了。這樣日誌中記錄的就是咱們想要的信息。
|
第四部分:
關於負載均衡
咱們能夠把後端的多個apache歸併成一個組,還能夠定義負載均衡法則。對於nginx而言,這些後端的APP SERVER,稱爲上游服務器,即upstream。
在upstream中,咱們能夠定義多個server,每個server的定義不要加上協議,要麼是IP+PORT,要麼是SERVERNAME+PORT,利用weight的方式定義加權輪調。Nginx能夠對上游服務器進行健康狀態檢查,若是上游服務器DOWN了,那麼Nginx不在將請求鏈接給他,若是上游服務器又活了,那麼讓他處理鏈接請求。max_fails和fail_timeout能夠定義健康狀態檢查。若是全部的上游服務器都掛了怎麼辦呢?server 127.0.0.1 backup就會起做用了。
有些時候,咱們必須未來自同一個客戶端的請求定向到同一臺後端服務器【保持SESSION會話】,ip_hash指令就是用來幹這個的,根據客戶端請求的源地址作HASH運算,只要HASH運算結果相同,那麼就會一直分發到相同的上游服務器。
事實上,nginx支持三種負載均衡算法: 第一,加權輪調 round_robin 第二,IPHASH 第三,最少鏈接【挑一個鏈接數最少的上游服務器進行處理】least_conn
|
第五部分:
關於緩存
Nginx之全部有效的減輕了上游服務器的壓力,是由於nginx的緩存機制。 nginx的緩存大概能夠分爲: 共享內存:存儲鍵和緩存對象元數據。也就是說查找緩存,是在內存中完成的。 磁盤空間:存儲數據。緩存數據最終也是在磁盤上的。
在http段中進行配置: proxy_cache_path /nginx/cache levles=1:2:1 keys_zone=first:20m max_size=1g
表示緩存目錄位於/nginx/cache下,1:2:1表示會創建三級目錄,第一級目錄名稱爲1個字符,第二季目錄名稱爲2個字符,第三級目錄名稱爲1個字符。keys_zone=a:b用來講明緩存在共享內存中的配置,a即表明名稱,若是誰要使用緩存,就必須引用這個名稱,b即表明內存大小。max_size用來定義磁盤緩存空間的最大大小。
在location段中明確開啓緩存功能: proxy_cache first;
|
第六部分:
關於URL重寫
Nginx中支持rewrite模塊,並支持正則表達式,來進行URL的rewrite。
這裏就不在介紹了,具體的使用方法,能夠參考nginx的官方文檔便可。
|
第七部分:
結束語
因爲在項目中用到了一點nginx方面的東西,學習了下,寫出來和你們分享,若是理解上有錯誤,歡迎你們留言指正~ |