Nginx的c30k問題解決方法
最近我們的下載服務(wù)遭遇了c30k,導(dǎo)致nginx的下載服務(wù)近乎停滯。原因嘛,很簡單,服務(wù)器部署在國外,眾所周知的原因,SL機(jī)房的線路不穩(wěn),加上不同地區(qū)出口速率抖動很厲害,為了加速下載,我們放開了限制,允許用戶使用多線程的下載工具。這樣一來,自然產(chǎn)生了c10k問題。下載文件都不小,每個用戶至少使用4線程,同時下載若干個素材。。。很自然并發(fā)鏈接數(shù)30k以上。
更受限于手頭money,無法擴(kuò)容(實際上要有錢也不會跑國外)。因此,必須提高單機(jī)并發(fā)能力和吞吐量。
我們的下載服務(wù)是使用Perl寫的一個Plack應(yīng)用,典型的PSGI,實現(xiàn)下載驗證,實時防火墻,用戶下載跟蹤等等,無法直接使用靜態(tài)文件分發(fā)(實際上Perl的性能還是很高效的,部署于Starman,對比PHP的實現(xiàn),是后者(PHP-FPM)的10倍左右)。
Starman是一個很不錯的PSGI Server,它使用傳統(tǒng)的Prefork模式。即便高效,但Prefork確實無法有效應(yīng)對c10k,我無法把Starman的worker增大到幾百上千個。在以前的文章曾經(jīng)提到Evented IO是能夠應(yīng)付c10k的一個方案。因此,我使用Twiggy換下了Starman。Twiggy是基于AE(AnyEvent)的一個PSGI Server,單進(jìn)程。在低并發(fā)下,單進(jìn)程的Twiggy的qps是弱于Starman,不過到了高并發(fā),Twiggy的優(yōu)勢就顯現(xiàn)出來了。在實際部署中,我啟動了多個Twiggy進(jìn)程,分別監(jiān)聽獨(dú)立的端口,nginx則使用upstream進(jìn)行負(fù)載均衡。 10個Twiggy的吞吐量已經(jīng)遠(yuǎn)遠(yuǎn)超過了50個Starman worker。 Twiggy的開銷也不大,因此可以很放心的增加Twiggy的進(jìn)程。
感謝PSGI的接口規(guī)范,從Starman切換到Twiggy,應(yīng)用程序無需做任何改動。(前提是程序內(nèi)不能有阻塞io的操作)。
另一個問題是服務(wù)器的IO-Wait比較高,畢竟下載這個是IO-Bound的任務(wù)。
Nginx支持Linux Native AIO,因此我考慮是否使用AIO能夠大大降低IO-Wait? 性能應(yīng)該有比較明顯的提升?
網(wǎng)上有一些資料,吹噓的Nginx AIO性能提升,神奇云云。我有點(diǎn)將信將疑,因為都沒有任何的測試數(shù)據(jù)比較,均是人云亦云。另外,多數(shù)配置都是或多或少有問題的。
我使用的CentOS, Nginx AIO要使用,必須是CentOS 5.5以上。因為只有5.5的kernel才有AIO的backport,nginx并沒有使用libaio。
此外,Nginx的AIO本來是為FreeBSD開發(fā),Linux固然可以使用,不過受到了Linux AIO的很多限制。
1. 必須使用Direct IO. 這樣一來,導(dǎo)致無法使用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,而對于XFS,注意,如果你沒有修改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)存消耗迅速降低,這是因為使用AIO必須使用directio,這就繞過了vm的diskcache。
實際性能如何,AIO一定很快么? 這點(diǎn)即便是Igor也不確定。
從我們自己的實際效果看,AIO并沒有明顯的性能提升,相反,偶爾會輕微增加了IO-Wait,這是因為無法利用diskcache,而如果文件多數(shù)又和directio_alignment有偏差(尤其是斷點(diǎn)續(xù)傳的時候,多數(shù)文件讀取位置在directio_alignment數(shù)據(jù)邊界外),這部分的數(shù)據(jù)必須使用blocking io讀取,又沒有disk cache,增加IO-Wait也可以理解。
最終,結(jié)論是,與其使用不那么靠譜的Nginx AIO, 不如多開一些Nginx的worker,重復(fù)利用vm disk cache, 當(dāng)內(nèi)存100%利用率的時候,nginx的靜態(tài)文件分發(fā)效率是高于AIO模式的。
BTW,這個實際用例也重新印證了我的一個觀點(diǎn),不要輕信網(wǎng)上那些毫無測試數(shù)據(jù)的忽悠,多數(shù)都是copy & paste的傳說, 各個說好,其實多數(shù)都沒實際印證過。
相關(guān)文章
nginx代理多次302的解決方法(nginx Follow 302)
這篇文章主要介紹了nginx代理多次302的解決方法(nginx Follow 302),詳細(xì)的介紹了解決方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-12-12Nginx強(qiáng)制跳轉(zhuǎn)Https(Http訪問跳轉(zhuǎn)Https)
這篇文章主要為大家介紹了Http訪問強(qiáng)制跳轉(zhuǎn)到Https的幾種方式詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10為nginx設(shè)置默認(rèn)虛擬主機(jī)(空主機(jī)頭,默認(rèn)主機(jī)頭)
nginx的默認(rèn)虛擬主機(jī)在用戶通過IP訪問,或者通過未設(shè)置的域名訪問(比如有人把他自己的域名指向了你的ip)的時候生效2010-11-11Nginx location 和 proxy_pass路徑配置問題小結(jié)
本文是基于 location 的匹配末尾是否配置 / 和 proxy_pass 末尾是否配置 / ,進(jìn)行測試,完全還原了整個測試過程,本文給大家介紹Nginx location 基本配置及相關(guān)配置文件,感興趣的朋友跟隨小編一起看看吧2021-09-09