IO復(fù)用
單進(jìn)程:阻塞
多進(jìn)程:每個(gè)進(jìn)程響應(yīng)一個(gè)請(qǐng)求
進(jìn)程量,進(jìn)程切換次數(shù)過(guò)多
每個(gè)進(jìn)程的地址空間是獨(dú)立,很多空間是重復(fù)的數(shù)據(jù),所以內(nèi)存使用效率較低
線程:thread
Light Weight Process
Linux 支持多少種類型的線程庫(kù)?如何切換線程庫(kù)?
每個(gè)線程響應(yīng)一個(gè)請(qǐng)求:
線程依然切換:切換較之進(jìn)程屬于輕量級(jí)
同一個(gè)進(jìn)程的線程可共享進(jìn)程的諸多資源,比如打開(kāi)的文件
對(duì)內(nèi)存的需求較之進(jìn)程略有下降
快速切換時(shí)會(huì)帶來(lái)線程抖動(dòng)
多進(jìn)程多線程
多線程:N個(gè)請(qǐng)求
一個(gè)線程響應(yīng)多個(gè)請(qǐng)求
Nginx
web服務(wù)器
反向代理
web
模塊化
Tengine
varnish,squid
nginx:cache(disk)
httpd:cache(disk,memory)
memcached
nginx:
server{}: 虛擬主機(jī)
location /URI/{
root "/web/htdocs"
}
httpd
<DocumentRoot>
</DocumentRoot>
<Location "/bbs">
</Location>
location[=|~|~*|^~|]uri{...}
location URI{}:
對(duì)當(dāng)前路徑及子路徑下的所有對(duì)象都生效
locati URI {}:
精確匹配指定的路徑,不包括子路徑,因此,只對(duì)當(dāng)前資源生效
location ~URI{}:
location ~*URI{}:
模式匹配URI,此處的URI可使用正則表達(dá)式,~區(qū)分字符大小寫(xiě),~*不區(qū)分字符大小寫(xiě)
location ^~URI{}:
不使用正則表達(dá)式
htpasswd :第二次不能使用-選項(xiàng)
Stub Status模塊
已經(jīng)接受連接的個(gè)數(shù),已經(jīng)處理的連接的個(gè)數(shù),已經(jīng)處理的請(qǐng)求的個(gè)數(shù)
reading :Nginx正在讀取其首部請(qǐng)求的個(gè)數(shù)
writing:Nginx正在讀取其主體的請(qǐng)求的個(gè)數(shù)、正處理著其請(qǐng)求的個(gè)數(shù)或者正在向其客戶發(fā)送響應(yīng)的個(gè)數(shù)
waiting:長(zhǎng)連接模式的保持的連接個(gè)數(shù)
傳統(tǒng)上基于進(jìn)程或線程模型架構(gòu)的web服務(wù)通過(guò)每進(jìn)程或每線程處理并發(fā)連接請(qǐng)求,這勢(shì)必會(huì)在網(wǎng)絡(luò)和I/O操作時(shí)產(chǎn)生阻塞,其另一個(gè)必然結(jié)果則是對(duì)內(nèi)存或CPU的利用率低下。生成一個(gè)新的進(jìn)程/線程需要事先備好其運(yùn)行時(shí)環(huán)境,這包括為其分配堆內(nèi)存和棧內(nèi)存,以及為其創(chuàng)建新的執(zhí)行上下文等。這些操作都需要占用CPU,而且過(guò)多的進(jìn)程/線程還會(huì)帶來(lái)線程抖動(dòng)或頻繁的上下文切換,系統(tǒng)性能也會(huì)由此進(jìn)一步下降。
在設(shè)計(jì)的最初階段,nginx的主要著眼點(diǎn)就是其高性能以及對(duì)物理計(jì)算資源的高密度利用,因此其采用了不同的架構(gòu)模型。受啟發(fā)于多種操作系統(tǒng)設(shè)計(jì)中基于“事件”的高級(jí)處理機(jī)制,nginx采用了模塊化、事件驅(qū)動(dòng)、異步、單線程及非阻塞的架構(gòu),并大量采用了多路復(fù)用及事件通知機(jī)制。在nginx中,連接請(qǐng)求由為數(shù)不多的幾個(gè)僅包含一個(gè)線程的進(jìn)程worker以高效的回環(huán)(run-loop)機(jī)制進(jìn)行處理,而每個(gè)worker可以并行處理數(shù)千個(gè)的并發(fā)連接及請(qǐng)求。
如果負(fù)載以CPU密集型應(yīng)用為主,如SSL或壓縮應(yīng)用,則worker數(shù)應(yīng)與CPU數(shù)相同;如果負(fù)載以IO密集型為主,如響應(yīng)大量?jī)?nèi)容給客戶端,則worker數(shù)應(yīng)該為CPU個(gè)數(shù)的1.5或2倍。
Nginx會(huì)按需同時(shí)運(yùn)行多個(gè)進(jìn)程:一個(gè)主進(jìn)程(master)和幾個(gè)工作進(jìn)程(worker),配置了緩存時(shí)還會(huì)有緩存加載器進(jìn)程(cache loader)和緩存管理器進(jìn)程(cache manager)等。所有進(jìn)程均是僅含有一個(gè)線程,并主要通過(guò)“共享內(nèi)存”的機(jī)制實(shí)現(xiàn)進(jìn)程間通信。主進(jìn)程以root用戶身份運(yùn)行,而worker、cache loader和cache manager均應(yīng)以非特權(quán)用戶身份運(yùn)行。
主進(jìn)程主要完成如下工作:
1. 讀取并驗(yàn)正配置信息;
2. 創(chuàng)建、綁定及關(guān)閉套接字;
3. 啟動(dòng)、終止及維護(hù)worker進(jìn)程的個(gè)數(shù);
4. 無(wú)須中止服務(wù)而重新配置工作特性;
5. 控制非中斷式程序升級(jí),啟用新的二進(jìn)制程序并在需要時(shí)回滾至老版本;
6. 重新打開(kāi)日志文件,實(shí)現(xiàn)日志滾動(dòng);
7. 編譯嵌入式perl腳本;
worker進(jìn)程主要完成的任務(wù)包括:
1. 接收、傳入并處理來(lái)自客戶端的連接;
2. 提供反向代理及過(guò)濾功能;
3. nginx任何能完成的其它任務(wù);
cache loader進(jìn)程主要完成的任務(wù)包括:
1. 檢查緩存存儲(chǔ)中的緩存對(duì)象;
2. 使用緩存元數(shù)據(jù)建立內(nèi)存數(shù)據(jù)庫(kù);
cache manager進(jìn)程的主要任務(wù):
1. 緩存的失效及過(guò)期檢驗(yàn);
Nginx的配置有著幾個(gè)不同的上下文:main、http、server、upstream和location(還有實(shí)現(xiàn)郵件服務(wù)反向代理的mail)。配置語(yǔ)法的格式和定義方式遵循所謂的C風(fēng)格,因此支持嵌套,還有著邏輯清晰并易于創(chuàng)建、閱讀和維護(hù)等優(yōu)勢(shì)。
Nginx的代碼是由一個(gè)核心和一系列的模塊組成, 核心主要用于提供Web Server的基本功能,以及Web和Mail反向代理的功能;還用于啟用網(wǎng)絡(luò)協(xié)議,創(chuàng)建必要的運(yùn)行時(shí)環(huán)境以及確保不同的模塊之間平滑地進(jìn)行交互。不過(guò),大多跟協(xié)議相關(guān)的功能和某應(yīng)用特有的功能都是由nginx的模塊實(shí)現(xiàn)的。這些功能模塊大致可以分為事件模塊、階段性處理器、輸出過(guò)濾器、變量處理器、協(xié)議、upstream和負(fù)載均衡幾個(gè)類別,這些共同組成了nginx的http功能。事件模塊主要用于提供OS獨(dú)立的(不同操作系統(tǒng)的事件機(jī)制有所不同)事件通知機(jī)制如kqueue或epoll等。協(xié)議模塊則負(fù)責(zé)實(shí)現(xiàn)nginx通過(guò)http、tls/ssl、smtp、pop3以及imap與對(duì)應(yīng)的客戶端建立會(huì)話。
在nginx內(nèi)部,進(jìn)程間的通信是通過(guò)模塊的pipeline或chain實(shí)現(xiàn)的;換句話說(shuō),每一個(gè)功能或操作都由一個(gè)模塊來(lái)實(shí)現(xiàn)。例如,壓縮、通過(guò)FastCGI或uwsgi協(xié)議與upstream服務(wù)器通信,以及與memcached建立會(huì)話等。
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ū)動(dòng)相關(guān)
httpd {
}
關(guān)于http相關(guān)的配置
server {
}
虛擬主機(jī)
location URI {
directive <parameters>;
}
URI訪問(wèn)屬性;
上下文
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)存(存儲(chǔ)鍵和緩存對(duì)象元數(shù)據(jù))
磁盤(pán)空間:存儲(chǔ)數(shù)據(jù)
proxy_cache_path: 不能定義在server{}上下文中;
緩存目錄:子目錄級(jí)別
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é)議。它擴(kuò)展了HTTP 1.1,在GET、POST、HEAD等幾個(gè)HTTP標(biāo)準(zhǔn)方法以外添加了一些新的方法,使應(yīng)用程序可直接對(duì)Web Server直接讀寫(xiě),并支持寫(xiě)文件鎖定(Locking)及解鎖(Unlock),還可以支持文件的版本控制。
另外常用的三種緩存:
open_log_cache:日志緩存
open_file_cache:
fastcgi_cache:
而nginx的limit限制也基于共享內(nèi)存實(shí)現(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重寫(xiě)模塊
if (condition) {
}
測(cè)試:
雙目測(cè)試:
~, !~
=, !=
~*, !~*
if ($request_method="POST") {
}
if ($request_uri ~* "/forum") {
}
單目測(cè)試:
location /images/ {
rewrite http://172.16.100.19/images/
}
支持正則表達(dá)式:
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: 本次重寫(xiě)完成之后,重啟下一輪檢查;
break: 本次重寫(xiě)完成之后,直接執(zhí)行后續(xù)操作;
memcached: 緩存服務(wù)器,但本身無(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