亚洲熟女综合色一区二区三区,亚洲精品中文字幕无码蜜桃,亚洲va欧美va日韩va成人网,亚洲av无码国产一区二区三区,亚洲精品无码久久久久久久

Web APP編程模型和IO策略

現(xiàn)代大型高性能網(wǎng)站諸如淘寶,京東,微博,F(xiàn)B,知乎等等,網(wǎng)站架構(gòu)涉及很多知識(shí)。像業(yè)務(wù)分層,軟件分割模塊化,分布式部署,集群服務(wù)器,負(fù)載均衡等技術(shù)可以幫助架構(gòu)師將一個(gè)大的復(fù)雜的問(wèn)題切分成小的簡(jiǎn)單的問(wèn)題。這篇文章著眼于解決這些切好的小問(wèn)題上,單機(jī)上有哪些編程實(shí)踐或者模型可以很好的做到高并發(fā)。本人web開發(fā)小白一枚,寫文章是想梳理自己的思路,求得大牛斧正,希望各位多多批判。文章的內(nèi)容大多來(lái)自網(wǎng)上的閱讀加上些自己的理解,文末附上參考閱讀的文章。

一個(gè)極簡(jiǎn)高并發(fā)模型

因?yàn)橛袛?shù)年的嵌入式領(lǐng)域的經(jīng)驗(yàn),先說(shuō)一下我認(rèn)為的比較高效的處理模型。

  • 硬件環(huán)境:單機(jī)30core, 1G Hz。
  • 軟件環(huán)境:6Wind fastpath,每個(gè)core上都是run-to-complete的endless loop.沒有操作系統(tǒng)。
  • 功能:一個(gè)超級(jí)簡(jiǎn)單的reverse proxy,具有l(wèi)oad balance的簡(jiǎn)單功能。

衡量并發(fā)性能,我們看一下一個(gè)IP包從網(wǎng)口緩沖區(qū)收上來(lái)處理到發(fā)出去大約需要多長(zhǎng)時(shí)間呢?

收+處理+發(fā)大概是500+1000+500=2000 cycles,時(shí)間也就是2us。單機(jī)1s內(nèi)可以支持30*(1s/2us)=15,000,000 request/s的并發(fā)。屌炸天的并發(fā)能力了吧!原因有兩個(gè):

  • 沒有操作系統(tǒng)overhead。
  • 包處理簡(jiǎn)單,IP層的處理,直接c函數(shù)調(diào)用,總共1000 cycle。

當(dāng)然這是從嵌入式得來(lái)的經(jīng)驗(yàn),web開發(fā)中不可能這樣,沒有Nginx,沒有web框架,沒有l(wèi)ib沒有各種open source,甚至沒有Linux?;氐皆忌鐣?huì)造出飛機(jī)大炮來(lái),這不把web開發(fā)者逼瘋了。軟件也是一個(gè)社會(huì)化協(xié)作的過(guò)程,os,framework,lib,opensource給開發(fā)者帶來(lái)極大方便的同時(shí),也伴隨著性能的開銷。如何在性能和可擴(kuò)展性、維護(hù)性等其他指標(biāo)找到一個(gè)平衡點(diǎn),如何選擇合適的編程模型,合適的第三方模塊達(dá)到最小的overhead,這是成長(zhǎng)為高手的開發(fā)者都會(huì)不斷思考的問(wèn)題。

High Performance architecture,這篇文章總結(jié)了四個(gè)性能殺手:

  • 數(shù)據(jù)復(fù)制
  • 上下文切換
  • 動(dòng)態(tài)內(nèi)存分配
  • 鎖競(jìng)爭(zhēng)

上面的編程模型之所以高效,就是將CPU用到極致,盡量避免這4種情況發(fā)生。心中有這么一個(gè)極簡(jiǎn)的高效模型,后面學(xué)習(xí)其他模式的時(shí)候可以暗做對(duì)比看一下到底會(huì)有哪些額外的開銷。

常用的server端Linux高并發(fā)編程模型

Nginx Vs Apache

大名鼎鼎的Nginx使用了多進(jìn)程模型,主進(jìn)程啟動(dòng)時(shí)初始化,bind,監(jiān)聽一組sockets,然后fork一堆child processes(workers),workers共享socket descriptor。workers競(jìng)爭(zhēng)accept_mutex,獲勝的worker通過(guò)IO multiplex(select/poll/epoll/kqueue/…)來(lái)處理成千上萬(wàn)的并發(fā)請(qǐng)求。為了獲得高性能,Nginx還大量使用了異步,事件驅(qū)動(dòng),non-blocking IO等技術(shù)?!盬hat resulted is a modular, event-driven, asynchronous, single-threaded, non-blocking architecture which became the foundation of nginx code.”

HMVKD1[2@AW@6M85_AM6~$9

Nginx 架構(gòu)

對(duì)比著看一下Apache的兩種常用運(yùn)行模式,詳見 Apache Modules

  • 1. Apache MPM prefork模式

主進(jìn)程通過(guò)進(jìn)程池維護(hù)一定數(shù)量(可配置)的worker進(jìn)程,每個(gè)worker進(jìn)程負(fù)責(zé)一個(gè)connection。worker進(jìn)程之間通過(guò)競(jìng)爭(zhēng)mpm-accept mutex實(shí)現(xiàn)并發(fā)和鏈接處理隔離。 由于進(jìn)程內(nèi)存開銷和切換開銷,該模式相對(duì)來(lái)說(shuō)是比較低效的并發(fā)。

5X8}[HT{UIPNW9Q$0N`8J[B
  • 2. Apache MPM worker模式

由于進(jìn)程開銷較大,MPM worker模式做了改進(jìn),處理每個(gè)connection的實(shí)體改為thread。主進(jìn)程啟動(dòng)可配數(shù)量的子進(jìn)程,每個(gè)進(jìn)程啟動(dòng)可配數(shù)量的server threads和listen thread。listen threads通過(guò)競(jìng)爭(zhēng)mpm-accept mutex獲取到新進(jìn)的connection request通過(guò)queue傳遞給自己進(jìn)程所在的server threads處理。由于調(diào)度的實(shí)體變成了開銷較小的thread,worker模式相對(duì)prefork具有更好的并發(fā)性能。

小結(jié)兩種webserver,可以發(fā)現(xiàn)Nginx使用了更高效的編程模型,worker進(jìn)程一般跟CPU的core數(shù)量相當(dāng),每個(gè)worker駐留在一個(gè)core上,合理編程可以做到最小程度的進(jìn)程切換,而且內(nèi)存的使用也比較經(jīng)濟(jì),基本上沒有浪費(fèi)在進(jìn)程狀態(tài)的存儲(chǔ)上。而Apache的模式是每個(gè)connection對(duì)應(yīng)一個(gè)進(jìn)程/線程,進(jìn)程/線程間的切換開銷,大量進(jìn)程/線程的內(nèi)存開銷,cache miss的概率增大,都限制了系統(tǒng)所能支持的并發(fā)數(shù)。

IO策略

由于IO的處理速度要遠(yuǎn)遠(yuǎn)低于CPU的速度,運(yùn)行在CPU上的程序不得不考慮IO在準(zhǔn)備暑假的過(guò)程中該干點(diǎn)什么,讓出CPU給別人還是自己去干點(diǎn)別的有意義的事情,這就涉及到了采用什么樣的IO策略。一般IO策略的選用跟進(jìn)程線程編程模型要同時(shí)考慮,兩者是有聯(lián)系的。

同步阻塞IO

11

同步阻塞IO是比較常見的IO模型,網(wǎng)絡(luò)編程中如果創(chuàng)建的socket的描述符屬性設(shè)置為阻塞的,當(dāng)socket對(duì)應(yīng)的用戶空間緩沖區(qū)內(nèi)尚無(wú)可讀數(shù)據(jù)時(shí),該進(jìn)程/線程在系統(tǒng)調(diào)用read/recv socket時(shí),會(huì)將自己掛起阻塞等待socket ready。

同步非阻塞IO和非阻塞IO同步復(fù)用

1.1

對(duì)比著同步阻塞IO,如果socket數(shù)據(jù)沒有ready,系統(tǒng)調(diào)用read/recv會(huì)直接返回,進(jìn)程可以繼續(xù)執(zhí)行不會(huì)掛起讓出CPU。當(dāng)然這樣做對(duì)單個(gè)socket來(lái)說(shuō)沒有多大的意義,如果要支持大量socket的并發(fā)就很有用了,也就是IO復(fù)用。select/poll/epoll就是這樣的應(yīng)用,IO的read是非阻塞式調(diào)用,select是阻塞式的,同步發(fā)生在select上。程序通過(guò)select調(diào)用同時(shí)監(jiān)控一組sockets,任何一個(gè)socket發(fā)生注冊(cè)過(guò)的事件時(shí),select由阻塞變?yōu)閞eady,函數(shù)調(diào)用返回后程序可以讀取IO了。前面提到的Nginx(使用epoll)和apache(使用select)都有使用這一IO策略。select/epoll這種IO策略還有另外一個(gè)名字叫Reactor,具體他們之間的細(xì)節(jié)區(qū)別再另開一文。

異步非阻塞IO

1

對(duì)比同步非阻塞IO,異步非阻塞IO也有個(gè)名字—Proactor。這種策略是真正的異步,使用注冊(cè)callback/hook函數(shù)來(lái)實(shí)現(xiàn)異步。程序注冊(cè)自己感興趣的socket 事件時(shí),同時(shí)將處理各種事件的handler也就是對(duì)應(yīng)的函數(shù)也注冊(cè)給內(nèi)核,不會(huì)有任何阻塞式調(diào)用。事件發(fā)生后內(nèi)核之間調(diào)用對(duì)應(yīng)的handler完成處理。這里暫且理解為內(nèi)核做了event的調(diào)度和handler調(diào)用,具體到底是異步IO庫(kù)如何做的,如何跟內(nèi)核通信的,后續(xù)繼續(xù)研究。

原文鏈接:https://segmentfault.com/a/1190000004547892

原創(chuàng)作者招募ing

歡迎各位朋友加入馬幫傳道者寫作團(tuán),秀出你的好身材,秀出你的好文章,讓大家發(fā)現(xiàn)你的美,美在文章中,美在不斷的自我挑戰(zhàn)中!

馬哥Linux運(yùn)維微信公眾號(hào)致力于發(fā)送好文章,也會(huì)不斷發(fā)現(xiàn)身邊的好文章,發(fā)現(xiàn)優(yōu)秀的你,惠及更多的運(yùn)維朋友們!

歡迎一起交流成長(zhǎng),一起愉快的玩耍!

原創(chuàng)投稿聯(lián)系magedu-小助手QQ:152260971

 

相關(guān)新聞

歷經(jīng)多年發(fā)展,已成為國(guó)內(nèi)好評(píng)如潮的Linux云計(jì)算運(yùn)維、SRE、Devops、網(wǎng)絡(luò)安全、云原生、Go、Python開發(fā)專業(yè)人才培訓(xùn)機(jī)構(gòu)!