作者:燒雞太子爺
簡介
前面一篇文章裡(詳見 很好用的壓測工具 - Apache Bench工具)有講到因為項目需要,在對比了jmeter和ab以後使用了ab測試工具來測試伺服器的性能,今天我們就來講講ab和jmter的并發模型,就是他如何保證能夠模拟高并發用戶端的場景的。
其實我們一說到并發,我們首先想到的就是服務端系統的并發模型,而為了能測試到這樣的伺服器系統的并發能力,性能測試工具也需要支援與之相應的并發包能力。而充分了解性能測試工具的并發模型,可以更好地幫助你選擇适合自己的性能測試工具。其中 JMeter&&ab,Locust 和 Gatling 就選擇了三種不同的發模型,這個應該是和開發者當時的技術背景,業務需求,資源情況等密切相關的。是以沒必要去探究當時作者為什麼要選擇這個模型,但是可以嘗試去了解這些不同模型的特點,進而選擇到适合自己的模型。今天我們主要講的jmeter和ab的模型,其他的我們後面有時間在做分析。
并發模型的相關概念
同步、異步、阻塞、非阻塞
要講并發模型,我們繞不開以下四個名詞:
- 同步(Synchronous)
- 異步(Asynchronous)
- 阻塞 (Blocking)
- 非阻塞(Nonblocking)
目前你能通過百度找到的、能查找到很多關于這些的解釋,每個人都會有自己的一些了解。我這邊不班門弄斧地來解釋這四個詞的差别,隻是提一些大部分資料中忽視的點:
- 要區分同步、異步,必須講清楚其所處的層,比如架構、使用者空間、核心、IO模型
- 同步調用發起後,沒有得到結果不傳回,那麼毫無疑問就是被阻塞了
- 異步調用發起後直接傳回,毫無疑問,這個程序沒有被阻塞
在Operating System Concepts [9th Edition](作業系統概念第9版本)該書中描述對程序間通信進行了一些描述

也就是說,站在程序通信緯度上來看,阻塞、非阻塞與同步、異步是同義詞,但是需要區分發送方、接收方:
- 阻塞發送
- 非阻塞發送
- 阻塞接受
- 非阻塞接受
上述不同類型的發送方法和不同類型的接收方法可以自由組合
另外,我們還知道Linux有五種I/O模型:
- 阻塞式IO(Blocking I/O)
- 非阻塞式IO(Nonblocking I/O)
- IO複用(I/O multiplexing)
- select
- poll
- epoll
- 信号驅動式IO(Signal Driver I/O)
- 異步IO(Asynchronous I/O)
- AIO
除了Asynchronous I/O以外,其餘4種都是同步IO
多程序/多線程
做開發的兄弟應該都能了解:
- 多程序:同一時刻執行多個程式。如,你打開電腦運作微信,釘釘,chrome等就是多程序(程序清單裡能看到多個程式在運作);
- 多線程:同一時刻執行多個線程。如,用chrome一邊看新聞,一邊聽歌,一邊看下載下傳(隻啟一個浏覽器程序,運作多線程任務);
了解上面的概念以後呢,然後我們再來講講ab和jmeter的并發模型
基于多線程并發的ab、jmeter
ab、JMeter分别是用C、Java開發的、基于多線程并發模型的壓測工具,也是目前最流行的開源壓測工具,兩者的工作原理類似,如下圖:
- 不管ab還是JMeter,其所謂的虛拟使用者(vuser)就是對應一個線程
- 在單個線程中,每個請求(query)都是同步調用的,下一個請求要等待前一個請求完成才能進行
- 一個請求(query)分成三部分:
- send - 施壓端發送開始,直到承壓端接收完成
- wait - 承壓端接收完成開始,直至業務處理結束
- recv - 承壓端傳回資料,直至施壓端接收完成
- 同一線程中連續的兩個請求之間存在等待時間這種概念,即圖中的空白處
總的來說,多線程模型的優劣勢總結有如下 :
(1)重度依賴于開發語言和作業系統對多線程的支援
(2)多線程切換的時候資源消耗比較多,在同等資源的情況下,産生的有效并發數量小;
(3)多線程也相對容易産生錯誤,比如死鎖,共享資料錯亂;
(4)可以通過豐富的界面來減少二次開發導緻上面的一些錯誤;
參考
- [作業系統概念第9版]
- <聊聊ab、wrk、JMeter、Locust這些壓測工具的并發模型差别>