fastcgi 異步實(shí)現(xiàn)和協(xié)程實(shí)現(xiàn)比較

介紹

異步模型和協(xié)程模型都是原fastcgi的優(yōu)化模型吼旧。

  • cocgi是使用騰訊開源庫libco實(shí)現(xiàn)的協(xié)程模式的fastcgi.
  • mucgi是使用muduo開源庫實(shí)現(xiàn)的異步模式的fastcgi.

兩者針對的場景略有不同虫腋」兔恚可以根據(jù)業(yè)務(wù)情況選擇使用:

  • 對于網(wǎng)絡(luò)抖動的應(yīng)付能力吩谦,mucgi優(yōu)于cocgi優(yōu)于libfcgi
  • 對于后端業(yè)務(wù)復(fù)雜度的應(yīng)付能力,cocgi優(yōu)于mucgi優(yōu)于libfcgi帜篇。

在一個系統(tǒng)中兩者可以結(jié)合起來使用:
mucgi接入如秒殺活動徐绑,抽獎等請求數(shù)波動大且響應(yīng)速度快的后端。
cocgi接入存在復(fù)雜業(yè)務(wù)邏輯忌穿,請求響應(yīng)速度快慢不均的后端抒寂。

last01.jpg


三種模式優(yōu)缺點(diǎn):

部署都是 nginx -> fastcgi -> 同步后端(測試用的是ice)

1. fastcgi(同步)

這個框架的fastcgi是用官網(wǎng) 的libfcgi庫編譯C++程序,
然后用cgi-fcgi或者spawn-fcgi指定ip端口調(diào)起這個程序處理fastcgi請求掠剑。

網(wǎng)上搜到的nginx + fastcgi +c教程基本都是這個模式屈芜。

缺點(diǎn):

  • 監(jiān)聽模式是 listen -> fork 共享監(jiān)聽端口給所有的進(jìn)程。每次只有一個進(jìn)程可以接受新連接。這個模式的問題后面會討論到井佑。

  • 同步進(jìn)程個數(shù)属铁,開多了浪費(fèi)資源,開少了躬翁,nginx會報一堆connect refuse.因?yàn)槿绻衒astcgi的進(jìn)程都在忙焦蘑。而且fastcgi的backlog(這個是存放三次握手成功但沒access鏈接)滿,那么nginx新建立的鏈接會直接返回失敗盒发。

  • 這里要重點(diǎn)指出例嘱,在fastcgi同步模型中,nginx -> fastcgi必須使用短鏈接宁舰。不要在nginx里面配fastcgi_keep_conn on.原因是上面說的拼卵,nginx不是所有請求都用已經(jīng)存在的長鏈,他會自動去創(chuàng)建新鏈接蛮艰。這個時候一個進(jìn)程一個鏈接腋腮,已經(jīng)沒有辦法接受新的鏈接,所以會出現(xiàn)一堆請求失敗壤蚜。

  • 不要去改fastcgi的listen backlog. 在backlog里面的已經(jīng)三次握手鏈接低葫,但沒有accept的鏈接。這些鏈接會等待仍律,不會立刻返回失敗嘿悬。模型里面設(shè)置是5,曾經(jīng)試過把他改成128,也就是說有128個請求等在那里水泉,導(dǎo)致超時的鏈接更多了善涨。超時比拒絕鏈接更傷性能。

總結(jié):

  • libfcgi不能應(yīng)對后端存在大量同步模塊草则,且業(yè)務(wù)復(fù)雜的情況(業(yè)務(wù)處理速度快慢不均)钢拧。
  • libfcgi不能應(yīng)對網(wǎng)絡(luò)抖動的情況(請求數(shù)突然暴漲)。
驚群問題

Linux內(nèi)核版本2.6.18以前炕横,listen -> fork 這種做法會有驚群效應(yīng)源内。在 2.6.18 以后,這個問題得到修復(fù)份殿,僅有一個進(jìn)程被喚醒并 accept 成功膜钓。
多IO+多路IO復(fù)用的模型也存在驚群在問題(如epoll)。nginx就花了大力氣處理這個問題卿嘲。nginx配置accept_mutex on的時候颂斜,用加鎖來保證每次只有一個進(jìn)程的listen_fd會進(jìn)入epoll。
但在極高的tps下拾枣,如用weighttp短鏈壓測nginx echo沃疮。每次都只有一個鏈接能夠被接收的模式盒让,這個接受新連接的速度將是個瓶頸,本機(jī)測試一秒最多2.2-2.5w次司蔬,cpu有一兩個核跑滿邑茄,其它大量idle.
nginx解決這個速度瓶頸問題提供了兩個配置項,一個是關(guān)掉accept_mutex 雖然會有驚群俊啼,但對比開著的性能要提高太多肺缕。至少是能跑滿cpu了。一個是打開multi_accept on,表示一次可以處理多個accept吨些,能很好的提高accept的速度搓谆,但會引起worker負(fù)載不均衡炒辉。
fastcgi要解決accept性能瓶頸目前沒有很好的方案豪墅。使用 SO_REUSEPORT(since Linux 3.9),可以稍微提升下性能黔寇。

改進(jìn)點(diǎn):

高內(nèi)核版本使用SO_REUSEPORT提升accept性能偶器。需要改libfcgi源碼.
os_unix.c 
修改代碼如下:
int OS_CreateLocalIpcFd(const char *bindPath, int backlog)
{
...
 328         if(listenSock >= 0) {
 329             int flag = 1;
 330             if(setsockopt(listenSock, SOL_SOCKET, SO_REUSEADDR,
 331                           (char *) &flag, sizeof(flag)) < 0) {
 332                 fprintf(stderr, "Can't set SO_REUSEADDR.\n");
 333             exit(1001);
 334         }
             // 增加下面幾行
 335         {
 336             int flag = 1;
 337             setsockopt(listenSock, SOL_SOCKET, SO_REUSEPORT, (char *) &flag, sizeof(flag));
 338         }
 339     }
 ...
}
測試性能大概提升10%-15% 不算很高。不過方便添加fastcgi進(jìn)程缝裤。

2. mucgi(異步)

異步fastcgi(mucgi)使用了muduo網(wǎng)絡(luò)庫作為通訊框架屏轰。
引入Cgicc庫多個文件用于解析http請求。
僅需要修改backend.cpp和backend.h就可以把請求傳到后端服務(wù)使用.

需要boost庫憋飞。 使用scons安裝霎苗,或者直接運(yùn)行make.sh。(make.sh是導(dǎo)出的scons的編譯日志,實(shí)在不想安裝scons,直接運(yùn)行make.sh也可以編譯程序)

優(yōu)點(diǎn):

  1. nginx可以配置異步長鏈接.提供了性能榛做。
  2. 能很好的應(yīng)對請求數(shù)瞬間爆炸的情況唁盏。比如10秒沒有請求,突然下一秒來了1萬個检眯。一般發(fā)生在公網(wǎng)網(wǎng)絡(luò)抖動的時候厘擂。如果是同步模型,這里就會出現(xiàn)幾千條connect refuse锰瘸。

muduo的日志用起來不是很順手刽严,業(yè)務(wù)環(huán)境我是替換成了log4cxx。為了不增加本模塊的復(fù)雜度避凝,就沒把那份代碼放上來舞萄。

缺點(diǎn):

  • 由于fastcgi是把請求轉(zhuǎn)到后端,后端處理是用同步的管削,這個時候fastcgi進(jìn)程其實(shí)是等在這里了鹏氧。也就是說,一個CGI進(jìn)程或線程能處理的請求數(shù)是要看后端響應(yīng)速度的佩谣。所以當(dāng)后端出現(xiàn)延遲很高的調(diào)用時把还,會造成mucgi堵車。就像是多條道的高速公路,如果路上有的車開得很慢吊履,就容易造成堵車安皱。

改進(jìn):

muduo網(wǎng)絡(luò)庫是支持 在構(gòu)造函數(shù)傳入muduo::net::TcpServer::kReusePort即可
如下:TcpServer server(&loop, addr, "FastCGI", muduo::net::TcpServer::kReusePort)
可以在進(jìn)程很忙的時候,不需重啟就能多加幾個fastcgi進(jìn)程進(jìn)來處理請求艇炎。

doc文檔有同步和異步cgi的性能測試對比酌伊。


3. cocgi(協(xié)程)

協(xié)程fastcgi(cocgi)使用了騰訊開源框架libco。
使用muduo的Buffer類作為tcp的receive buffer缀踪。
加入Cgicc庫多個文件用于解析http請求居砖。
僅需要修改backend.cpp和backend.h就可以把請求傳到后端服務(wù)使用.

使用scons安裝,或者直接運(yùn)行make.sh驴娃。(make.sh是導(dǎo)出的scons的編譯日志,實(shí)在不想安裝scons,直接運(yùn)行make.sh也可以編譯程序)

優(yōu)點(diǎn):

  • 這個可以算是第一個(同步)模型的改進(jìn)版本奏候。每個進(jìn)程可以創(chuàng)建多個協(xié)程,也就是說每個進(jìn)程通過協(xié)程能模擬出多個進(jìn)程的效果唇敞。具體可以看: https://github.com/Tencent/libco
  • 能很好的應(yīng)對后端請求耗時不均衡的情況蔗草。特別是有的請求耗時較長的時候,cocgi表現(xiàn)要比mucgi好疆柔。因?yàn)閰f(xié)程的數(shù)量多咒精,所以阻塞幾個對整個模型的影響幾乎沒有。不像原生的fastcgi和mucgi的模型旷档,開10個進(jìn)程有幾個慢請求就要影響整個系統(tǒng)模叙。

缺點(diǎn):

  • 協(xié)程模型也是同步模型,所以nginx->cocgi不能配置長鏈接鞋屈,測試時候發(fā)現(xiàn)范咨,就算有2000協(xié)程,如果前端請求很多谐区,nginx發(fā)起的連接會等待回收湖蜕。然而如果長鏈接沒釋放,新連接有兩種選擇宋列,一種是等待昭抒,可能引發(fā)超時(代碼里面是這種)。一種是直接close炼杖,可以返回請求失敗灭返。兩種都會影響用戶體驗(yàn)。
  • 每個進(jìn)程的協(xié)程數(shù)不宜開太高坤邪。開多也會浪費(fèi)資源熙含。測試時候,每個進(jìn)程一般開30-50個協(xié)程艇纺。

改進(jìn)點(diǎn):

nginx->cocgi可以使用長鏈接怎静,如果要配好超時和自動回收的機(jī)制邮弹。還要和請求量和協(xié)程做個均衡。

異步實(shí)現(xiàn)源碼和協(xié)程實(shí)現(xiàn)源碼:
https://github.com/toniz/fastcgi-async-or-coroutine

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蚓聘,一起剝皮案震驚了整個濱河市腌乡,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌夜牡,老刑警劉巖与纽,帶你破解...
    沈念sama閱讀 211,948評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異塘装,居然都是意外死亡急迂,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評論 3 385
  • 文/潘曉璐 我一進(jìn)店門蹦肴,熙熙樓的掌柜王于貴愁眉苦臉地迎上來僚碎,“玉大人,你說我怎么就攤上這事冗尤√牵” “怎么了胀溺?”我有些...
    開封第一講書人閱讀 157,490評論 0 348
  • 文/不壞的土叔 我叫張陵裂七,是天一觀的道長。 經(jīng)常有香客問我仓坞,道長背零,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,521評論 1 284
  • 正文 為了忘掉前任无埃,我火速辦了婚禮徙瓶,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘嫉称。我一直安慰自己侦镇,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,627評論 6 386
  • 文/花漫 我一把揭開白布织阅。 她就那樣靜靜地躺著壳繁,像睡著了一般。 火紅的嫁衣襯著肌膚如雪荔棉。 梳的紋絲不亂的頭發(fā)上闹炉,一...
    開封第一講書人閱讀 49,842評論 1 290
  • 那天,我揣著相機(jī)與錄音润樱,去河邊找鬼渣触。 笑死,一個胖子當(dāng)著我的面吹牛壹若,可吹牛的內(nèi)容都是我干的嗅钻。 我是一名探鬼主播皂冰,決...
    沈念sama閱讀 38,997評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼养篓!你這毒婦竟也來了灼擂?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,741評論 0 268
  • 序言:老撾萬榮一對情侶失蹤觉至,失蹤者是張志新(化名)和其女友劉穎剔应,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體语御,經(jīng)...
    沈念sama閱讀 44,203評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡峻贮,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,534評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了应闯。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片纤控。...
    茶點(diǎn)故事閱讀 38,673評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖碉纺,靈堂內(nèi)的尸體忽然破棺而出船万,到底是詐尸還是另有隱情,我是刑警寧澤骨田,帶...
    沈念sama閱讀 34,339評論 4 330
  • 正文 年R本政府宣布耿导,位于F島的核電站,受9級特大地震影響态贤,放射性物質(zhì)發(fā)生泄漏舱呻。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,955評論 3 313
  • 文/蒙蒙 一悠汽、第九天 我趴在偏房一處隱蔽的房頂上張望箱吕。 院中可真熱鬧,春花似錦柿冲、人聲如沸茬高。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,770評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽怎栽。三九已至,卻和暖如春慨亲,著一層夾襖步出監(jiān)牢的瞬間婚瓜,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,000評論 1 266
  • 我被黑心中介騙來泰國打工刑棵, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留巴刻,地道東北人。 一個月前我還...
    沈念sama閱讀 46,394評論 2 360
  • 正文 我出身青樓蛉签,卻偏偏與公主長得像胡陪,于是被迫代替她去往敵國和親沥寥。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,562評論 2 349

推薦閱讀更多精彩內(nèi)容

  • 1. Nginx的模塊與工作原理 Nginx由內(nèi)核和模塊組成柠座,其中邑雅,內(nèi)核的設(shè)計非常微小和簡潔,完成的工作也非常簡單...
    rosekissyou閱讀 10,202評論 5 124
  • 第一章 Nginx簡介 Nginx是什么 沒有聽過Nginx妈经?那么一定聽過它的“同行”Apache吧淮野!Ngi...
    JokerW閱讀 32,650評論 24 1,002
  • 什么是Nginx? Nginx是一個高性能的HTTP和反向代理服務(wù)器吹泡,也是一個IMAP/POP3/SMTP服務(wù)器N...
    jiangmo閱讀 2,536評論 1 9
  • I/O模型Nginx介紹Nginx的安裝和目錄結(jié)構(gòu)Nginx的配置Nginx的編譯安裝 一骤星、I/O模型 (一)I/...
    哈嘍別樣閱讀 890評論 0 4
  • 周末沒有特別多的顏色粉刷這世界 雨順著玻璃流下窗外是遠(yuǎn)行的旅人 文豪可以抒寫一段又一段愛情故事 我只能描繪出一張又...
    拿什么拯救地球閱讀 163評論 0 0