Nginx的c30k問(wèn)題解決方法
最近我們的下載服務(wù)遭遇了c30k,導(dǎo)致nginx的下載服務(wù)近乎停滯。原因嘛,很簡(jiǎn)單,服務(wù)器部署在國(guó)外,眾所周知的原因,SL機(jī)房的線路不穩(wěn),加上不同地區(qū)出口速率抖動(dòng)很厲害,為了加速下載,我們放開(kāi)了限制,允許用戶使用多線程的下載工具。這樣一來(lái),自然產(chǎn)生了c10k問(wèn)題。下載文件都不小,每個(gè)用戶至少使用4線程,同時(shí)下載若干個(gè)素材。。。很自然并發(fā)鏈接數(shù)30k以上。
更受限于手頭money,無(wú)法擴(kuò)容(實(shí)際上要有錢也不會(huì)跑國(guó)外)。因此,必須提高單機(jī)并發(fā)能力和吞吐量。
我們的下載服務(wù)是使用Perl寫(xiě)的一個(gè)Plack應(yīng)用,典型的PSGI,實(shí)現(xiàn)下載驗(yàn)證,實(shí)時(shí)防火墻,用戶下載跟蹤等等,無(wú)法直接使用靜態(tài)文件分發(fā)(實(shí)際上Perl的性能還是很高效的,部署于Starman,對(duì)比PHP的實(shí)現(xiàn),是后者(PHP-FPM)的10倍左右)。
Starman是一個(gè)很不錯(cuò)的PSGI Server,它使用傳統(tǒng)的Prefork模式。即便高效,但Prefork確實(shí)無(wú)法有效應(yīng)對(duì)c10k,我無(wú)法把Starman的worker增大到幾百上千個(gè)。在以前的文章曾經(jīng)提到Evented IO是能夠應(yīng)付c10k的一個(gè)方案。因此,我使用Twiggy換下了Starman。Twiggy是基于AE(AnyEvent)的一個(gè)PSGI Server,單進(jìn)程。在低并發(fā)下,單進(jìn)程的Twiggy的qps是弱于Starman,不過(guò)到了高并發(fā),Twiggy的優(yōu)勢(shì)就顯現(xiàn)出來(lái)了。在實(shí)際部署中,我啟動(dòng)了多個(gè)Twiggy進(jìn)程,分別監(jiān)聽(tīng)獨(dú)立的端口,nginx則使用upstream進(jìn)行負(fù)載均衡。 10個(gè)Twiggy的吞吐量已經(jīng)遠(yuǎn)遠(yuǎn)超過(guò)了50個(gè)Starman worker。 Twiggy的開(kāi)銷也不大,因此可以很放心的增加Twiggy的進(jìn)程。
感謝PSGI的接口規(guī)范,從Starman切換到Twiggy,應(yīng)用程序無(wú)需做任何改動(dòng)。(前提是程序內(nèi)不能有阻塞io的操作)。
另一個(gè)問(wèn)題是服務(wù)器的IO-Wait比較高,畢竟下載這個(gè)是IO-Bound的任務(wù)。
Nginx支持Linux Native AIO,因此我考慮是否使用AIO能夠大大降低IO-Wait? 性能應(yīng)該有比較明顯的提升?
網(wǎng)上有一些資料,吹噓的Nginx AIO性能提升,神奇云云。我有點(diǎn)將信將疑,因?yàn)槎紱](méi)有任何的測(cè)試數(shù)據(jù)比較,均是人云亦云。另外,多數(shù)配置都是或多或少有問(wèn)題的。
我使用的CentOS, Nginx AIO要使用,必須是CentOS 5.5以上。因?yàn)橹挥?.5的kernel才有AIO的backport,nginx并沒(méi)有使用libaio。
此外,Nginx的AIO本來(lái)是為FreeBSD開(kāi)發(fā),Linux固然可以使用,不過(guò)受到了Linux AIO的很多限制。
1. 必須使用Direct IO. 這樣一來(lái),導(dǎo)致無(wú)法使用vm的disk cache.
2. 文件只有大小和directio_alignment定義block size整數(shù)倍的數(shù)據(jù)才可以使用AIO,當(dāng)文件整數(shù)據(jù)塊之前和之后,那些不能取整的部分則是blocking方式讀取的,這也是為什么需要output-buffer。directio_alignment大小取決于你使用的文件系統(tǒng),默認(rèn)是512,而對(duì)于XFS,注意,如果你沒(méi)有修改XFS bsize, 需要調(diào)整為XFS默認(rèn)的4k.
我使用的配置如下:
location /archive {
internal;
aio on;
directio 4k;
directio_alignment 4k;
output_buffers 1 128k;
}
當(dāng)啟用AIO后,可以看到vmstat中,cache的內(nèi)存消耗迅速降低,這是因?yàn)槭褂肁IO必須使用directio,這就繞過(guò)了vm的diskcache。
實(shí)際性能如何,AIO一定很快么? 這點(diǎn)即便是Igor也不確定。
從我們自己的實(shí)際效果看,AIO并沒(méi)有明顯的性能提升,相反,偶爾會(huì)輕微增加了IO-Wait,這是因?yàn)闊o(wú)法利用diskcache,而如果文件多數(shù)又和directio_alignment有偏差(尤其是斷點(diǎn)續(xù)傳的時(shí)候,多數(shù)文件讀取位置在directio_alignment數(shù)據(jù)邊界外),這部分的數(shù)據(jù)必須使用blocking io讀取,又沒(méi)有disk cache,增加IO-Wait也可以理解。
最終,結(jié)論是,與其使用不那么靠譜的Nginx AIO, 不如多開(kāi)一些Nginx的worker,重復(fù)利用vm disk cache, 當(dāng)內(nèi)存100%利用率的時(shí)候,nginx的靜態(tài)文件分發(fā)效率是高于AIO模式的。
BTW,這個(gè)實(shí)際用例也重新印證了我的一個(gè)觀點(diǎn),不要輕信網(wǎng)上那些毫無(wú)測(cè)試數(shù)據(jù)的忽悠,多數(shù)都是copy & paste的傳說(shuō), 各個(gè)說(shuō)好,其實(shí)多數(shù)都沒(méi)實(shí)際印證過(guò)。
- nginx緩存頁(yè)面后 串會(huì)話問(wèn)題的解決方法
- nginx緩存不起作用問(wèn)題解決方法
- nginx、Apache、IIS服務(wù)器解決 413 Request Entity Too Large問(wèn)題方法匯總
- Apache、Nginx下Font Awesome在 Firefox 中不顯示問(wèn)題解決方法
- 權(quán)限問(wèn)題導(dǎo)致Nginx 403 Forbidden錯(cuò)誤的解決方法
- Nginx中使用gzip_http_version解決CDN只支持http 1.0問(wèn)題
- 總結(jié)Nginx 的使用過(guò)程中遇到的問(wèn)題及解決方案
相關(guān)文章
nginx臨時(shí)搭建rtmp服務(wù)器的方法實(shí)現(xiàn)
nginx是一款優(yōu)秀的反向代理工具,通過(guò)Nginx自帶的rtmp模塊,也可以實(shí)現(xiàn)rtmp服務(wù)器的搭建,本文主要介紹了nginx臨時(shí)搭建rtmp服務(wù)器,具有一定的參考價(jià)值,感興趣的可以了解一下2024-02-02
Nginx利用Logrotate實(shí)現(xiàn)日志分割的詳細(xì)過(guò)程
nginx日志分割是很常見(jiàn)的運(yùn)維工作,下面這篇文章主要給大家介紹了關(guān)于Nginx利用Logrotate日志分割的詳細(xì)過(guò)程,文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-05-05
詳解Nginx中的Rewrite的重定向配置與實(shí)踐
這篇文章主要介紹了詳解Nginx中的Rewrite的重定向配置與實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03
nginx配置SSL證書(shū)實(shí)現(xiàn)https服務(wù)的方法
這篇文章主要介紹了nginx配置SSL證書(shū)實(shí)現(xiàn)https服務(wù)的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-05-05
nginx里的rewrite跳轉(zhuǎn)的實(shí)現(xiàn)
這篇文章主要介紹了nginx里的rewrite跳轉(zhuǎn)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11

