Nginx反向代理、負載均衡、緩存、URL重寫及讀寫分離

2017年3月3日23:21:33 發(fā)表評論 4,777 ℃

IO復(fù)用

單進程:阻塞

多進程:每個進程響應(yīng)一個請求

進程量,進程切換次數(shù)過多

每個進程的地址空間是獨立,很多空間是重復(fù)的數(shù)據(jù),所以內(nèi)存使用效率較低

線程:thread

Light Weight Process

Linux 支持多少種類型的線程庫?如何切換線程庫?

每個線程響應(yīng)一個請求:

線程依然切換:切換較之進程屬于輕量級

同一個進程的線程可共享進程的諸多資源,比如打開的文件

對內(nèi)存的需求較之進程略有下降

快速切換時會帶來線程抖動

多進程多線程

多線程:N個請求

一個線程響應(yīng)多個請求

Nginx

web服務(wù)器

反向代理

web

mail

模塊化

Tengine

varnish,squid

nginx:cache(disk)

httpd:cache(disk,memory)

memcached

nginx:

server{}: 虛擬主機

location /URI/{

root "/web/htdocs"

}

httpd

<DocumentRoot>

</DocumentRoot>


<Location "/bbs">

</Location>

location[=|~|~*|^~|]uri{...}

location URI{}: 

對當前路徑及子路徑下的所有對象都生效

locati URI {}:

精確匹配指定的路徑,不包括子路徑,因此,只對當前資源生效

location ~URI{}:

location ~*URI{}:

模式匹配URI,此處的URI可使用正則表達式,~區(qū)分字符大小寫,~*不區(qū)分字符大小寫

location ^~URI{}:

不使用正則表達式

htpasswd :第二次不能使用-選項

Stub Status模塊

已經(jīng)接受連接的個數(shù),已經(jīng)處理的連接的個數(shù),已經(jīng)處理的請求的個數(shù)

reading :Nginx正在讀取其首部請求的個數(shù)

writing:Nginx正在讀取其主體的請求的個數(shù)、正處理著其請求的個數(shù)或者正在向其客戶發(fā)送響應(yīng)的個數(shù)

waiting:長連接模式的保持的連接個數(shù)

傳統(tǒng)上基于進程或線程模型架構(gòu)的web服務(wù)通過每進程或每線程處理并發(fā)連接請求,這勢必會在網(wǎng)絡(luò)和I/O操作時產(chǎn)生阻塞,其另一個必然結(jié)果則是對內(nèi)存或CPU的利用率低下。生成一個新的進程/線程需要事先備好其運行時環(huán)境,這包括為其分配堆內(nèi)存和棧內(nèi)存,以及為其創(chuàng)建新的執(zhí)行上下文等。這些操作都需要占用CPU,而且過多的進程/線程還會帶來線程抖動或頻繁的上下文切換,系統(tǒng)性能也會由此進一步下降。

在設(shè)計的最初階段,nginx的主要著眼點就是其高性能以及對物理計算資源的高密度利用,因此其采用了不同的架構(gòu)模型。受啟發(fā)于多種操作系統(tǒng)設(shè)計中基于“事件”的高級處理機制,nginx采用了模塊化、事件驅(qū)動、異步、單線程及非阻塞的架構(gòu),并大量采用了多路復(fù)用及事件通知機制。在nginx中,連接請求由為數(shù)不多的幾個僅包含一個線程的進程worker以高效的回環(huán)(run-loop)機制進行處理,而每個worker可以并行處理數(shù)千個的并發(fā)連接及請求。

如果負載以CPU密集型應(yīng)用為主,如SSL或壓縮應(yīng)用,則worker數(shù)應(yīng)與CPU數(shù)相同;如果負載以IO密集型為主,如響應(yīng)大量內(nèi)容給客戶端,則worker數(shù)應(yīng)該為CPU個數(shù)的1.5或2倍。

Nginx會按需同時運行多個進程:一個主進程(master)和幾個工作進程(worker),配置了緩存時還會有緩存加載器進程(cache loader)和緩存管理器進程(cache manager)等。所有進程均是僅含有一個線程,并主要通過“共享內(nèi)存”的機制實現(xiàn)進程間通信。主進程以root用戶身份運行,而worker、cache loader和cache manager均應(yīng)以非特權(quán)用戶身份運行。

主進程主要完成如下工作:

1. 讀取并驗正配置信息;

2. 創(chuàng)建、綁定及關(guān)閉套接字;

3. 啟動、終止及維護worker進程的個數(shù);

4. 無須中止服務(wù)而重新配置工作特性;

5. 控制非中斷式程序升級,啟用新的二進制程序并在需要時回滾至老版本;

6. 重新打開日志文件,實現(xiàn)日志滾動;

7. 編譯嵌入式perl腳本;

worker進程主要完成的任務(wù)包括:

1. 接收、傳入并處理來自客戶端的連接;

2. 提供反向代理及過濾功能;

3. nginx任何能完成的其它任務(wù);

cache loader進程主要完成的任務(wù)包括:

1. 檢查緩存存儲中的緩存對象;

2. 使用緩存元數(shù)據(jù)建立內(nèi)存數(shù)據(jù)庫;

cache manager進程的主要任務(wù):

1. 緩存的失效及過期檢驗;

Nginx的配置有著幾個不同的上下文:main、http、server、upstream和location(還有實現(xiàn)郵件服務(wù)反向代理的mail)。配置語法的格式和定義方式遵循所謂的C風(fēng)格,因此支持嵌套,還有著邏輯清晰并易于創(chuàng)建、閱讀和維護等優(yōu)勢。

Nginx的代碼是由一個核心和一系列的模塊組成, 核心主要用于提供Web Server的基本功能,以及Web和Mail反向代理的功能;還用于啟用網(wǎng)絡(luò)協(xié)議,創(chuàng)建必要的運行時環(huán)境以及確保不同的模塊之間平滑地進行交互。不過,大多跟協(xié)議相關(guān)的功能和某應(yīng)用特有的功能都是由nginx的模塊實現(xiàn)的。這些功能模塊大致可以分為事件模塊、階段性處理器、輸出過濾器、變量處理器、協(xié)議、upstream和負載均衡幾個類別,這些共同組成了nginx的http功能。事件模塊主要用于提供OS獨立的(不同操作系統(tǒng)的事件機制有所不同)事件通知機制如kqueue或epoll等。協(xié)議模塊則負責(zé)實現(xiàn)nginx通過http、tls/ssl、smtp、pop3以及imap與對應(yīng)的客戶端建立會話。

在nginx內(nèi)部,進程間的通信是通過模塊的pipeline或chain實現(xiàn)的;換句話說,每一個功能或操作都由一個模塊來實現(xiàn)。例如,壓縮、通過FastCGI或uwsgi協(xié)議與upstream服務(wù)器通信,以及與memcached建立會話等。

LEMP:

Enginx (FastCGI) + php-fpm

location ~* \.php$ {

fastcgi_pass 127.0.0.1:9000;

}


fastcgi


Nginx配置文件

main, 

worker_process

error_log

user

group

events {

}

事件驅(qū)動相關(guān)


httpd {

}

關(guān)于http相關(guān)的配置


server {

}

虛擬主機


location URI {

directive <parameters>;

}


URI訪問屬性;


上下文


server {

listen 80;

server_name www.test.com;

location / {

后端服務(wù)器;

}

}

GET、POST、HEAD、PUT、TRACE、OPTIONS、CONNECTION、DELETE

nginx:

round-robin

ip_hash

least_conn

Nginx

cache:共享內(nèi)存(存儲鍵和緩存對象元數(shù)據(jù))

磁盤空間:存儲數(shù)據(jù)

proxy_cache_path: 不能定義在server{}上下文中;

緩存目錄:子目錄級別

proxy_cache_path /nginx/cache/first levels=1:2:1 keys_z max_size=1G;

cache_manager: LRU

WebDAV (Web-based Distributed Authoring and Versioning) 一種基于 HTTP 1.1協(xié)議的通信協(xié)議。它擴展了HTTP 1.1,在GET、POST、HEAD等幾個HTTP標準方法以外添加了一些新的方法,使應(yīng)用程序可直接對Web Server直接讀寫,并支持寫文件鎖定(Locking)及解鎖(Unlock),還可以支持文件的版本控制。


另外常用的三種緩存:
open_log_cache:日志緩存
open_file_cache:
fastcgi_cache:

而nginx的limit限制也基于共享內(nèi)存實現(xiàn)。

nginx: gzip

upstream phpsrvs {

server 

server

}

upstream imgsrvs {

server

server 

}

upstream staticfilesrvs {

server

server

}

location / {

root /web/htdocs;

index index.php index.html;

}

location ~* \.php$ {

fastcgi_pass http://phpsrvs;

}

location ~* "\.(jpg|jpeg|gif|png)$" {

proxy_pass http://imgsrvs;

}

rewirte: URL重寫模塊

if (condition) {

}

測試:

雙目測試:

~, !~

=, !=

~*, !~*

if ($request_method="POST") {

}

if ($request_uri ~* "/forum") {

}

單目測試:

location /images/ {

rewrite http://172.16.100.19/images/

}

支持正則表達式:

location / {

root html;

index index.html;

rewrite "^/bbs/(.*)/images/(.*)\.jpg$" http://www.test.com/bbs/$2/images/$1.jpg last;

}

http://www.test.com/bbs/a/images/b.jpg --> http://www.test.com/bbs/b/images/a.jpg --> http://www.test.com/bbs/a/images/b.jpg

http://www.test.com/bbs/index.html --> http://www.test.com/forum/index.html

last: 本次重寫完成之后,重啟下一輪檢查;

break: 本次重寫完成之后,直接執(zhí)行后續(xù)操作;

memcached: 緩存服務(wù)器,但本身無法決定緩存任何數(shù)據(jù)

一半依賴于客戶端,一半依賴于服務(wù)器

set key 5 60 hello

lazy: 惰性, LRU,最近最少使用

內(nèi)存緩存服務(wù)器:

48bytes

1MB

buddy system: 伙伴系統(tǒng)

避免內(nèi)存外碎片

slab allocator: slab分配器

避免內(nèi)存內(nèi)碎片

memcached: 不通信分布式緩存服務(wù)器


event-driven:

libevent

【騰訊云】云服務(wù)器、云數(shù)據(jù)庫、COS、CDN、短信等云產(chǎn)品特惠熱賣中

發(fā)表評論

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: