qileilove

          blog已經轉移至github,大家請訪問 http://qaseven.github.io/

          使用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 的技術手段。

            愿你樂在壓力測試!

            本文出自:http://www.oschina.net/translate/stress-testing-http-with-twisted-python-and-treq

          posted on 2013-05-10 09:30 順其自然EVO 閱讀(278) 評論(0)  編輯  收藏 所屬分類: 性能測試

          <2013年5月>
          2829301234
          567891011
          12131415161718
          19202122232425
          2627282930311
          2345678

          導航

          統計

          常用鏈接

          留言簿(55)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 同江市| 土默特左旗| 武定县| 句容市| 松江区| 永胜县| 涿鹿县| 扬州市| 平昌县| 华阴市| 玛多县| 通州区| 新竹市| 视频| 奉贤区| 交口县| 沧源| 宽城| 新营市| 乌兰县| 綦江县| 韶关市| 应城市| 葫芦岛市| 灵石县| 屏山县| 内乡县| 左云县| 泸水县| 柳河县| 郁南县| 兴化市| 巫溪县| 牡丹江市| 开远市| 和政县| 五原县| 缙云县| 荥阳市| 潼关县| 嘉黎县|