使用 Twisted Python 和 Treq 進行 HTTP 壓力測試
從事API相關的工作很有挑戰性,在高峰期保持系統的穩定及健壯性就是其中之一,這也是我們在Mailgun做很多壓力測試的原因。
這麼久以來,我們已經嘗試了很多種方法,從簡單的ApacheBench到複雜些的自定義測試套。但是本貼講述的,是一種使用python進行“快速粗糙”卻非常靈活的壓力測試的方法。
使用python寫HTTP客戶端的時候,我們都很喜歡用 Requests library。這也是我們向我們的API使用者們推薦的。Requests 很強大,但有一個缺點,它是一個模組化的每執行緒一個呼叫的東西,很難或者說不可能用它來快速的產生成千上萬級別的請求。
Treq on Twisted簡介
為解決這個問題我們引入了Treq (Github庫)。Treq是一個HTTP客戶端庫,受Requests影響,但是它執行在Twisted上,具有Twisted典型的強大能力:處理網路I/O時它是非同步且高度併發的方式。
Treq並不僅僅限於壓力測試:它是寫高併發HTTP客戶端的好工具,比如網頁抓取。Treq很優雅、易於使用且強大。這是一個例子:
>>> from treq import get >>> def done(response): ... print response.code ... reactor.stop() >>> get("http://www.github.com").addCallback(done) >>> from twisted.internet import reactor >>> reactor.run() 200
簡單的測試指令碼
如下是一個使用Treq的簡單指令碼,用最大可能量的請求來對單一URL進行轟炸。
#!/usr/bin/env python from twisted.internet import epollreactor epollreactor.install() from twisted.internet import reactor, task from twisted.web.client import HTTPConnectionPool import treq import random from datetime import datetime req_generated = 0 req_made = 0 req_done = 0 cooperator = task.Cooperator() pool = HTTPConnectionPool(reactor) def counter(): '''This function gets called once a second and prints the progress at one second intervals. ''' print("Requests: {} generated; {} made; {} done".format( req_generated, req_made, req_done)) # reset the counters and reschedule ourselves req_generated = req_made = req_done = 0 reactor.callLater(1, counter) def body_received(body): global req_done req_done += 1 def request_done(response): global req_made deferred = treq.json_content(response) req_made += 1 deferred.addCallback(body_received) deferred.addErrback(lambda x: None) # ignore errors return deferred def request(): deferred = treq.post('http://api.host/v2/loadtest/messages', auth=('api', 'api-key'), data={'from': 'Loadtest <test@example.com>', 'to': 'to@example.org', 'subject': "test"}, pool=pool) deferred.addCallback(request_done) return deferred def requests_generator(): global req_generated while True: deferred = request() req_generated += 1 # do not yield deferred here so cooperator won't pause until # response is received yield None if __name__ == '__main__': # make cooperator work on spawning requests cooperator.cooperate(requests_generator()) # run the counter that will be reporting sending speed once a second reactor.callLater(1, counter) # run the reactor reactor.run()
輸出結果:
2013-04-25 09:30 Requests: 327 generated; 153 sent; 153 received 2013-04-25 09:30 Requests: 306 generated; 156 sent; 156 received 2013-04-25 09:30 Requests: 318 generated; 184 sent; 154 received
“Generated”類的數字代表被Twisted反應器準備好但是還沒有傳送的請求。這個指令碼為了簡潔性忽略了所有錯誤處理。為它新增超時狀態的資訊就留給讀者作為一個練習。
這個指令碼可以當做是一個起始點,你可以通過擴充改進它來自定義特定應用下的處理邏輯。建議你在改進的時候用 collections.Counter 來替代醜陋的全域性變數。這個指令碼執行在單執行緒上,想通過一臺機器壓榨出最大量的請求的話,你可以用類似 mulitprocessing 的技術手段。
願你樂在壓力測試!
相關文章
- JMeter使用jar進行壓力測試JMeterJAR
- webbench進行壓力測試Web
- 使用Jmeter進行RPC壓力測試JMeterRPC
- 使用ab對nginx進行壓力測試Nginx
- 在Rainbond上使用Locust進行壓力測試AI
- 使用orastress!進行資料庫壓力測試(zt)AST資料庫
- HTTP/FTP壓力測試工具siegeHTTPFTP
- 如何對你Mac進行壓力測試?Mac
- 用mysqlslap對MySQL進行壓力測試MySql
- .net core 使用ConcurrentTest元件對方法進行壓力測試元件
- 如何對 ElasticSearch 叢集進行壓力測試Elasticsearch
- 對 Linux 核心進行壓力測試(轉)Linux
- 使用Jmeter進行http介面測試JMeterHTTP
- 【SWINGBENCH】使用SwingBench對Oracle進行壓力測試Oracle
- 對node工程進行壓力測試與效能分析
- Http壓力測試工具HttpTest4NetHTTP
- 壓力測試工具ab - Apache HTTP server benchmarking toolApacheHTTPServer
- ORACLE壓力測試Oracle
- laravel壓力測試Laravel
- MACOSXApacheab壓力測試MacApache
- NGINX壓力測試Nginx
- mysqlslap壓力測試MySql
- 壓力測試工具
- postman進行http介面測試PostmanHTTP
- 軟體壓力測試流程和測試工具分享,讓你寫壓力測試報告再也不愁測試報告
- 使用LoadRunner進行壓力測試時如何選擇要錄製的協議?協議
- nginx壓力測試方法:Nginx
- 壓力測試指令碼指令碼
- 分散式測試工具Beetle.DT的部署並進行HTTP,SQL,TCP壓測分散式HTTPSQLTCP
- Linux下使用壓力測試工具stressLinux
- (一)效能測試(壓力測試、負載測試)負載
- RestCloud測試平臺,支援壓力測試RESTCloud
- 多執行緒伺服器壓力測試執行緒伺服器
- 讓測試事半功倍軟體壓力測試工具分享,壓力測試報告怎麼收費?測試報告
- Taurus.MVC 效能壓力測試(ap 壓測 和 linux 下wrk 壓測):.NET 版本MVCLinux
- Apache Bench Web 壓力測試ApacheWeb
- oracle壓力測試之orastress!OracleAST
- 壓力測試工具之FIO