使用webbench對伺服器進行壓力測試,建立1000個客戶端,併發訪問伺服器10s,正常情況下有接近8萬個http請求訪問伺服器。
結果顯示僅有7個請求被成功處理,0個請求處理失敗,伺服器也沒有返回錯誤。此時,從瀏覽器端訪問伺服器,發現該請求也不能被處理和響應,必須將伺服器重啟後,瀏覽器端才能訪問正常。
通過查詢伺服器執行日誌,對伺服器接收http請求連線,http處理邏輯兩部分進行排查。
日誌中顯示,7個請求報文為:get / http/1.0
的http請求被正確處理和響應,排除http處理邏輯錯誤。
因此,將重點放在接收http請求連線部分。其中,伺服器端接收http請求的連線步驟為socket -> bind -> listen -> accept;客戶端連線請求步驟為socket -> connect。
listen
#includeint listen(int sockfd, int backlog)
connect
accept
從上面的分析中可以看出,accept如果沒有將佇列中的連線取完,就緒佇列中剩下的連線都得不到處理,也不能接收新請求,這個特性與壓力測試的bug十分類似。
//對檔案描述符設定非阻塞
int setnonblocking(int fd)
//將核心事件表註冊讀事件,et模式,選擇開啟epolloneshot
void addfd(int epollfd,int fd,bool one_shot)
//建立核心事件表
epoll_event events[max_event_number];
int epollfd=epoll_create(5);
assert(epollfd!=-1);
//將listenfd設定為et邊緣觸發
addfd(epollfd,listenfd,false);
int number=epoll_wait(epollfd,events,max_event_number,-1);
if(number<0&&errno!=eintr)
for(int i=0;i分析**發現,web端和伺服器端建立連線,採用epoll的邊緣觸發模式同時監聽多個檔案描述符。
epoll的et、lt
et邊緣觸發模式
從上面的定位分析,問題可能是錯誤使用epoll的et模式。
嘗試將listenfd設定為lt阻塞,或者et非阻塞模式下while包裹accept對**進行修改,這裡以et非阻塞為例。
for(int i=0;i0)
//todo,邏輯處理
} }
}
將**修改後,重新進行壓力測試,問題得到解決,伺服器成功完成75617個訪問請求,且沒有出現任何失敗的情況。壓測結果如下:
解決方案
該bug的出現,本質上對epoll的et和lt模式實踐程式設計較少,沒有深刻理解和深入應用。
記一次前端bug排查
前言 時隔三年,終於記得要找回賬號密碼開始寫筆記了,這周剛加入了乙個後台管理系統專案,測試反饋系統重新整理時經常會直接登出,嚴詞要求解決這個 重大 bug,so尷尬。更嚴重的是發現系統在ie上直接登不進去,嬸可忍叔不可忍,於是我開啟了苦逼的尋bug之路。既然是登出了,當然會有登出請求,chrome重...
記一次壓力測試
壓力測試方式 1 jmeter單獨使用測試 2 先用badboy生成.jmx檔案,在用jmeter匯入,執行 1.建立執行緒組 指定執行緒數,迴圈次數 2 建立http請求,這裡使用的本地測試 3 可以建立定時器,輸入模擬使用者數量 4 建立報告,結果樹等 隨意 然後先用tomcat預設配置跑一次,...
一次弄懂效能 壓力 負載測試
談到效能測試就不得不說壓力 負載測試,其實叫法有很多種,而且他們所用到的工具以及關注的指標大致相同,所以很容易混淆。太難了!先舉個最通俗易懂的例子 舉例 乙個人扛x斤 負載測試 200斤情況下,能否堅持5分鐘。滿足最基本的要求 壓力測試 200,300,400 情況下,他的表現,什麼時候失敗,失敗之...