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í)際上要有錢(qián)也不會(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代理多次302的解決方法(nginx Follow 302)
這篇文章主要介紹了nginx代理多次302的解決方法(nginx Follow 302),詳細(xì)的介紹了解決方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-12-12阿里云ssl證書(shū)如何通過(guò)Nginx部署到服務(wù)器
這篇文章主要介紹了阿里云ssl證書(shū)通過(guò)Nginx部署到服務(wù)器的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-03-03Nginx強(qiáng)制跳轉(zhuǎn)Https(Http訪問(wèn)跳轉(zhuǎn)Https)
這篇文章主要為大家介紹了Http訪問(wèn)強(qiáng)制跳轉(zhuǎn)到Https的幾種方式詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10為nginx設(shè)置默認(rèn)虛擬主機(jī)(空主機(jī)頭,默認(rèn)主機(jī)頭)
nginx的默認(rèn)虛擬主機(jī)在用戶通過(guò)IP訪問(wèn),或者通過(guò)未設(shè)置的域名訪問(wèn)(比如有人把他自己的域名指向了你的ip)的時(shí)候生效2010-11-11Nginx location 和 proxy_pass路徑配置問(wèn)題小結(jié)
本文是基于 location 的匹配末尾是否配置 / 和 proxy_pass 末尾是否配置 / ,進(jìn)行測(cè)試,完全還原了整個(gè)測(cè)試過(guò)程,本文給大家介紹Nginx location 基本配置及相關(guān)配置文件,感興趣的朋友跟隨小編一起看看吧2021-09-09