1. 程式人生 > >使用locust做伺服器壓力測試

使用locust做伺服器壓力測試

高併發的效能測試

對於後臺的壓力效能測試,傳統上有jmeter等工具。但這些工具並不能很好地回答一個問題,那就是,我們的伺服器能同時支援多少個使用者使用?

查看了這篇文章,對比之下,首選locust,原因如下:

  1. python3支援。
  2. 模擬效率高。官方號稱單個process可以模擬上千使用者的同時操作,有使用者提到,通過分散式的方法,模擬了200萬用戶
  3. 通過python程式碼可以靈活地處理高併發邏輯。

我個人比較喜歡它的一個理念,qps不等同於同時線上使用者數,因為使用者可能會等待以判斷接下去的操作,所以,這種效能測試的結果,更能接近實際使用者的情況。

如何使用locust

檢視官方文件,那才是最新最權威的,copy paste不屬於本人的風格。需要注意的一點是,對於http的請求,預設情況下,只要返回的status code是 2XX,它就預設請求成功,其他情況會統計為請求失敗。可以通過 catch_response 修改預設行為模式。

這邊提一些官方文件沒提及的東西:

  1. python3的支援。master分支雖然支援,但是pip的包還不支援,需要在requirements裡面強行指定alpha版本 locustio >= 0.8a2,或者,通過 pip install git+https://github.com/locustio/locust.git
    強行安裝master版本
  2. locust本身大量使用了gevent,但是在框架層面沒有做 monkey patch,這個會引入 gevent的LoopExit問題。
    測試中使用了concurrent.futures.ThreadPoolExecutor做併發的url訪問,結果頻繁出現 gevent的LoopExit問題,說 The operation would block forever。ThreadPoolExecutor是按照官方文件寫得一模一樣的程式碼,後發現原來是gevent的一個坑,locust內部使用了gevent,但看來並沒有做 monkey patch,所以,需要自己在測試程式碼的開頭將這個加上。PS.有些框架在gevent的支援上已經打了monkey patch,比如gunicorn。所以,對於採用 gevent做非同步處理的框架,需要了解這個可能忽略的點。

    from gevent import monkey
    monkey.patch_all()

壓力測試下發現的問題

  1. 壓力下,mysql的使用連線如果不注意釋放,很容易用光。(在mysql下面看 show processlist; 可以看到連結數。)
    網上說 SQLAlchemy在多process下的配置比較tricky,看到flask-sqlalchemy有個相關issue。現實程式碼中,除了通過decorator對於api的呼叫保證有 db.session.remove()之外(因為採用的是flashalchemy,所以,使用remove()比使用close()更優)。
  2. 大量採用 redis快取來減少伺服器的讀,也是一種提高併發量,減少資料庫負擔的方法。