php设置backlog,高并发调优backlog多大合适?
么對于nginx,對于php-fpm,backlog應(yīng)該設(shè)置多大,是越大越好嗎?backlog怎么設(shè)置合適?這是上篇文章中遺留的幾個(gè)問題
接著上篇文章Nginx高并發(fā)調(diào)優(yōu)中常被忽略的參數(shù)中,最后部分,通過查看nginx源碼發(fā)現(xiàn)nginx源碼中定義backlog為511,其實(shí)在php-fpm配置文件中,同樣默認(rèn)backlog是511
包括redis,在默認(rèn)配置文件中也有backlog配置,默認(rèn)也是511
其實(shí)在redis注釋中已經(jīng)解釋很清楚了,當(dāng)你需要處理高并發(fā)得場景時(shí),需要較大得backlog來處理堆積得請求,上篇文章對原理已經(jīng)做了較全面的解釋,網(wǎng)上也有很多大牛關(guān)于tcp全連接、半連接的文章講解,今天主要想測試下,backlog在優(yōu)化設(shè)置時(shí),應(yīng)該怎么設(shè)置
為了盡量排除帶寬影響,我這里直接用兩臺內(nèi)網(wǎng)的機(jī)子,一臺作為客戶端用ab去請求,另外一臺作為服務(wù)端,服務(wù)端是一臺centos7,沒有優(yōu)化過的系統(tǒng)
首先說一下ss的Recv-Q和Send-Q
在ss命令的結(jié)果中,如果該條記錄為監(jiān)聽端口,則Recv-Q表示accept隊(duì)列中元素的個(gè)數(shù),Send-Q表示accept隊(duì)列中隊(duì)列的容量,所以從監(jiān)聽端口這行正好可以看到隊(duì)列的情況
接著開始測試,第一步,先就默認(rèn)backlog為128的情況下,用ab進(jìn)行測試
直接開了兩個(gè)窗口,用watch執(zhí)行ss命令,0.1s刷新,在客戶端用ab 200并發(fā)請求,開始瞬間php的Recv-Q就滿了(因?yàn)槲疫@里nginx連接php用的是socket的方式,所以監(jiān)聽的是socket,不是端口),接著查看ab結(jié)果
69次失敗請求
查看nginx錯(cuò)誤日志,69條錯(cuò)誤日志,都是sock文件資源不可用,如果是用端口的形式,應(yīng)該是請求超時(shí)或連接被重置,這個(gè)具體根據(jù)php執(zhí)行時(shí)間已經(jīng)nginx配置超時(shí)時(shí)間決定
接著調(diào)大內(nèi)核somaxconn,讓somaxconn大于nginx和php的默認(rèn)backlog,也就是511,這里設(shè)置為1024,在接著測試
查看php-cgi的Send-Q,注意這里nginx或者php-fpm都要restart才能生效
接著查看nginx的Send-Q
接著ab進(jìn)行測試,同時(shí)實(shí)時(shí)查看Recv-Q情況,我先仍然用剛才的ab參數(shù)進(jìn)行測試
截圖有點(diǎn)慢了,打的時(shí)候Recv-Q已經(jīng)到198了,接著快速下降,看下ab測試結(jié)果
已經(jīng)沒有失敗請求了,接著調(diào)大ab參數(shù),再進(jìn)行同樣的測試
手慢了,ab打的瞬間Recv-Q是512,隊(duì)列打滿了,接著查看結(jié)果,不出意外肯定會有失敗請求
從目前測試的結(jié)果來看,最直觀的就是,backlog增大,對于能處理的并發(fā)請求來說也在增大,所以backlog優(yōu)化是必須的,接著繼續(xù)增加backlog進(jìn)行測試
還是用600并發(fā)
沒有問題,都能夠正常處理,繼續(xù)增加并發(fā)到1025
查看結(jié)果
接著想看下backlog太大會不會有什么影響,進(jìn)行如下配置
接著ab測試(測試服務(wù)器不一定能扛住,這里ab最大并發(fā)2w)
從結(jié)果來看,沒有問題,backlog越大越好
但其實(shí)這里有個(gè)問題,就是我這里測試的只是單php腳本,并沒有涉及到業(yè)務(wù)代碼,也不查詢數(shù)據(jù)庫,所以php能夠快速處理,服務(wù)器不會崩,那么為什么nginx、php-fpm、redis,都默認(rèn)設(shè)置511,而不設(shè)置很大的值,其實(shí)在php歷史上,backlog是修改過的(從其他文章看到的),也是從511,修改到65535,提交者也是認(rèn)為backlog數(shù)量越大越好,即便出現(xiàn)timeout也比syn隊(duì)列滿了后,內(nèi)核忽略掉TCP SYN請求要好
但是在后面又將backlog改回511
其中理由是“backlog值為65535太大了。會導(dǎo)致前面的nginx(或者其他客戶端)超時(shí)”,而且提交者舉例計(jì)算了一下,假設(shè)FPM的QPS為5000,那么65535個(gè)請求全部處理完需要13s的樣子。但前端的nginx(或其他客戶端)已經(jīng)等待超時(shí),關(guān)閉了這個(gè)連接。當(dāng)FPM處理完之后,再往這個(gè)SOCKET ID 寫數(shù)據(jù)時(shí),卻發(fā)現(xiàn)連接已關(guān)閉,得到的是“error: Broken Pipe”,在nginx、redis、apache里,默認(rèn)的backlog值都是511。故這里也建議改為511
所以我的建議是,用壓測的方法,持續(xù)調(diào)整測試,取一個(gè)適合你業(yè)務(wù)的最大backlog值,一定要以業(yè)務(wù)代碼進(jìn)行測試,而不是單純的調(diào)大backlog。
總結(jié)
以上是生活随笔為你收集整理的php设置backlog,高并发调优backlog多大合适?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: A是AJ B是乔丹 C是篮球 D是什么?
- 下一篇: Php中数组sort举例,php数组排序