Nginx幾種IO模型原理以及實(shí)現(xiàn)基于域名的PC端和移動(dòng)端

一、系統(tǒng) I/O 模型

1、同步/異步:關(guān)注的是事件處理的消息通信機(jī)制,即在等待?件事情的處理結(jié)果時(shí),被調(diào)?者是否提供完成通知

同步:synchronous,調(diào)?者等待被調(diào)?者返回消息后才能繼續(xù)執(zhí)?,如果被調(diào)?者不提供消息返回則為同步,同步需要調(diào)?者主動(dòng)詢問事情是否處理完成。即:進(jìn)程發(fā)出請(qǐng)求調(diào)?后,等內(nèi)核返回響應(yīng)以后才繼續(xù)下?個(gè)請(qǐng)求,即如果內(nèi)核?直不返回?cái)?shù)據(jù),那么進(jìn)程就?直等。
異步:asynchronous,被調(diào)?者通過狀態(tài)、通知或回調(diào)機(jī)制主動(dòng)通知調(diào)?者被調(diào)?者的運(yùn)?狀態(tài),即:進(jìn)程發(fā)出請(qǐng)求調(diào)?后,不等內(nèi)核返回響應(yīng),接著處理下?個(gè)請(qǐng)求,Nginx是異步的

2、阻塞/?阻塞:關(guān)注調(diào)?者在等待結(jié)果返回之前所處的狀態(tài)

阻塞:blocking,指IO操作需要徹底完成后才返回到??空間,調(diào)?結(jié)果返回之前,調(diào)?者被掛起,?不了別的事情。
?阻塞:nonblocking,指IO操作被調(diào)?后?即返回給???個(gè)狀態(tài)值,?需等到IO操作徹底完成,最終的調(diào)?結(jié)果返回之前,調(diào)?者不會(huì)被掛起,可以去做別的事情。

二、網(wǎng)絡(luò)I/O 模型

1. 同步阻塞型 I/O 模型:阻塞IO模型是最簡單的IO模型,??線程在內(nèi)核進(jìn)?IO操作時(shí)被阻塞 ??線程通過系統(tǒng)調(diào)?read發(fā)起IO讀操作,由??空間轉(zhuǎn)到內(nèi)核空間。內(nèi)核等到數(shù)據(jù)包到達(dá)后,然后將接收的數(shù)據(jù)拷?到??空間,完成read操作 ??需要等待read將數(shù)據(jù)讀取到buffffer后,才繼續(xù)處理接收的數(shù)據(jù)。整個(gè)IO請(qǐng)求的過程中,??線程是被阻塞的,這導(dǎo)致??在發(fā)起IO請(qǐng)求時(shí),不能做任何事情,對(duì)CPU的資源利?率不夠 優(yōu)點(diǎn):程序簡單,在阻塞等待數(shù)據(jù)期間進(jìn)程/線程掛起,基本不會(huì)占? CPU 資源 缺點(diǎn):每個(gè)連接需要獨(dú)?的進(jìn)程/線程單獨(dú)處理,當(dāng)并發(fā)請(qǐng)求量?時(shí)為了維護(hù)程序,內(nèi)存、線程切換開銷較?,apache 的preforck使?的是這種模式。

同步阻塞:程序向內(nèi)核發(fā)送IO請(qǐng)求后?直等待內(nèi)核響應(yīng),如果內(nèi)核處理請(qǐng)求的IO操作不能?即返回,則進(jìn)程將?直等待并不再接受新的請(qǐng)求,并由進(jìn)程輪訓(xùn)查看IO是否完成,完成后進(jìn)程將IO結(jié)果返回給Client,在IO沒有返回期間進(jìn)程不能接受其他客?的請(qǐng)求,?且是有進(jìn)程??去查看IO是否完成,這種?式簡單,但是?較慢,?的?較少。

同步阻塞.jpg

2. 同步非阻塞型 I/O 模型:??線程發(fā)起IO請(qǐng)求時(shí)?即返回。但并未讀取到任何數(shù)據(jù),??線程需要不斷地發(fā)起IO請(qǐng)求,直到數(shù)據(jù)到達(dá)后,才真正讀取到數(shù)據(jù),繼續(xù)執(zhí)?。即 “輪詢”機(jī)制存在兩個(gè)問題:如果有?量?件描述符都要等,那么就得?個(gè)?個(gè)的read。這會(huì)帶來?量的Context Switch(read是系統(tǒng)調(diào)?,每調(diào)??次就得在??態(tài)和核?態(tài)切換?次)。輪詢的時(shí)間不好把握。這?是要多久之后數(shù)據(jù)才能到。等待時(shí)間設(shè)的太?,程序響應(yīng)延遲就過?;設(shè)的太短,就會(huì)造成過于頻繁的重試,?耗CPU?已,是?較浪費(fèi)CPU的?式,?般很少直接使?這種模型,?是在其他IO模型中使??阻塞IO這?特性。

同步?阻塞:程序向內(nèi)核發(fā)送請(qǐng)IO求后?直等待內(nèi)核響應(yīng),如果內(nèi)核處理請(qǐng)求的IO操作不能?即返回IO結(jié)果,進(jìn)程將不再等待,?且繼續(xù)處理其他請(qǐng)求,但是仍然需要進(jìn)程隔?段時(shí)間就要查看內(nèi)核IO是否完成。


同步非阻塞.jpg

3. IO多路復(fù)用型(IO multiplexing):就是我們說的select,poll,epoll,有些地?也稱這種IO?式為event driven IO。select/poll/epoll的好處就在于單個(gè)process就可以同時(shí)處理多個(gè)?絡(luò)連接的IO。它的基本原理就是select,poll,epoll這個(gè)function會(huì)不斷的輪詢所負(fù)責(zé)的所有socket,當(dāng)某個(gè)socket有數(shù)據(jù)到達(dá)了,就通知??進(jìn)程。 當(dāng)??進(jìn)程調(diào)?了select,那么整個(gè)進(jìn)程會(huì)被block,?同時(shí),kernel會(huì)“監(jiān)視”所有select負(fù)責(zé)的socket,當(dāng)任何?個(gè)socket中的數(shù)據(jù)準(zhǔn)備好了,select就會(huì)返回。這個(gè)時(shí)候??進(jìn)程再調(diào)?read操作,將數(shù)據(jù)從kernel拷?到??進(jìn)程。

Apache prefork是此模式的主進(jìn)程+多進(jìn)程/單線程+select,work是主進(jìn)程+多進(jìn)程/多線程+poll模式


IO多路復(fù)用.jpg

4. 信號(hào)驅(qū)動(dòng)IO:signal-driven I/O ??進(jìn)程可以通過sigaction系統(tǒng)調(diào)?注冊(cè)?個(gè)信號(hào)處理程序,然后主程序可以繼續(xù)向下執(zhí)?,當(dāng)有IO操作準(zhǔn)備就緒時(shí),由內(nèi)核通知觸發(fā)?個(gè)SIGIO信號(hào)處理程序執(zhí)?,然后將??進(jìn)程所需要的數(shù)據(jù)從內(nèi)核空間拷?到??空間, 此模型的優(yōu)勢(shì)在于等待數(shù)據(jù)報(bào)到達(dá)期間進(jìn)程不被阻塞。??主程序可以繼續(xù)執(zhí)?,只要等待來?信號(hào)處理函數(shù)的通知。 優(yōu)點(diǎn):線程并沒有在等待數(shù)據(jù)時(shí)被阻塞,內(nèi)核直接返回調(diào)?接收信號(hào),不影響進(jìn)程繼續(xù)處理其他請(qǐng)求因此可以提?資源的利?率 缺點(diǎn):信號(hào) I/O 在?量 IO 操作時(shí)可能會(huì)因?yàn)樾盘?hào)隊(duì)列溢出導(dǎo)致沒法通知

異步阻塞:程序進(jìn)程向內(nèi)核發(fā)送IO調(diào)?后,不?等待內(nèi)核響應(yīng),可以繼續(xù)接受其他請(qǐng)求,內(nèi)核收到進(jìn)程請(qǐng)求后進(jìn)?的IO如果不能?即返回,就由內(nèi)核等待結(jié)果,直到IO完成后內(nèi)核再通知進(jìn)程,apache event模型就是主進(jìn)程+多進(jìn)程/多線程+信號(hào)驅(qū)動(dòng)


信號(hào)驅(qū)動(dòng)式IO.jpg

** 異步(?阻塞) IO(asynchronous IO):**相對(duì)于同步IO,異步IO不是順序執(zhí)?。??進(jìn)程進(jìn)?aio_read系統(tǒng)調(diào)?之后,?論內(nèi)核數(shù)據(jù)是否準(zhǔn)備好,都會(huì)直接返回給??進(jìn)程,然后??態(tài)進(jìn)程可以去做別的事情。等到socket數(shù)據(jù)準(zhǔn)備好了,內(nèi)核直接復(fù)制數(shù)據(jù)給進(jìn)程,然后從內(nèi)核向進(jìn)程發(fā)送通知。IO兩個(gè)階段,進(jìn)程都是?阻塞的。 Linux提供了AIO庫函數(shù)實(shí)現(xiàn)異步,但是?的很少。?前有很多開源的異步IO庫,例如libevent、libev、libuv。異步過程如下圖所?:

異步?阻塞:程序進(jìn)程向內(nèi)核發(fā)送IO調(diào)?后,不?等待內(nèi)核響應(yīng),可以繼續(xù)接受其他請(qǐng)求,內(nèi)核調(diào)?的IO如果不能?即返回,內(nèi)核會(huì)繼續(xù)處理其他事物,直到IO完成后將結(jié)果通知給內(nèi)核,內(nèi)核在將IO完成的結(jié)果返回給進(jìn)程,期間進(jìn)程可以接受新的請(qǐng)求,內(nèi)核也可以處理新的事物,因此相互不影響,可以實(shí)現(xiàn)較?的同時(shí)并實(shí)現(xiàn)較?的IO復(fù)?,因此異步?阻塞使?最多的?種通信?式,nginx是異步?阻塞。


image.png

三、實(shí)現(xiàn)基于域名的PC端和移動(dòng)端

  1. 創(chuàng)建PC端配置文件 vim /usr/local/nginx/conf/conf.d/pc.conf
server{
    listen  80;
    listen  443 ssl;
    ssl_certificate /usr/local/nginx/certs/www.tuntun.net.crt;
    ssl_certificate_key /usr/local/nginx/certs/www.tuntun.net.key;
    ssl_session_cache shared:sslcache:20m;
    ssl_session_timeout 10m;

    server_name www.tuntun.net;
    charset utf-8;

    access_log /usr/local/nginx/logs/access_json.log access_json;

    error_page 500 502 503 504 404 /error.html;

    location = /error.html {
        root /data/nginx/html;
    }

    location / {
        root /data/nginx/html;
        index index.html index.php;
    }
}
  1. 創(chuàng)建移動(dòng)端配置文件 vim /usr/local/nginx/conf/conf.d/mobile.conf
server{
    listen  80;
    server_name www.mobile.tuntun.net;
    charset utf-8;

    access_log /usr/local/nginx/logs/access_json.log access_json;

    error_page 500 502 503 504 404 /error.html;

    location = /error.html {
        root /data/nginx/mobile;
    }

    location / {
        root /data/nginx/mobile;  
        index index.html index.php;
    }
    location =/jd.jpg {
        root /data/nginx/images;
        index index.html;
    }
}

3、分別為PC端和移動(dòng)端的頁面目錄并放置不同代碼root /data/nginx/html; root /data/nginx/mobile; 并設(shè)置不同域名。
server_name www.tuntun.net;

image.png

server_name www.mobile.tuntun.net;
image.png

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容