輕量級性能測試工具wrk - 使用(提升篇)

上一篇博客解決了GET請求的簡單性能測試,但是無法進行POST請求的模擬用戶使用場景,對於這種需求,本篇博客通過編寫Lua腳本的方式,在運行壓測命令時,通過參數 --script 來指定Lua腳本,來滿足個性化需求。

一、wrk對Lua腳本的支持

wrk支持在三個階段對壓測進行個性化,分別是啓動階段、運行階段和結束階段。每個測試線程,都擁有獨立的Lua運行環境。

啓動階段:

function setup(thread)

在腳本文件中實現setup方法,wrk就會在測試線程已經初始化,但還沒有啓動的時候調用該方法。wrk會爲每一個測試線程調用一次setup方法,並傳入代表測試線程的對象thread作爲參數。setup方法中可操作該thread對象,獲取信息、存儲信息、甚至關閉該線程。

thread.addr             - get or set the thread's server address
thread:get(name)        - get the value of a global in the thread's env
thread:set(name, value) - set the value of a global in the thread's env
thread:stop()           - stop the thread

運行階段:

function init(args)
function delay()
function request()
function response(status, headers, body)

1.init(args):由測試線程調用,只會在進入運行階段時,調用一次。支持從啓動wrk的命令中,獲取命令行參數;

2.delay():在每次發送請求之前調用,如果需要定製延遲時間,可以在這個方法中設置;

3.request():用來生成請求,每一次請求都會調用該方法,所以注意不要在該方法中做耗時的操作;

4.response(status,headers,body):在每次收到一個響應時被調用,爲提升性能,如果沒有定義該方法,那麼wrk不會被解析headers和body。

結束階段:

function done(summary, latency, requests)

done()方法在整個測試過程中只會被調用一次,我們可以從給定的參數中,獲取壓測結果。生成定製化的測試報告。

自定義Lua腳本中可訪問的變量以及方法:

變量:wrk

wrk = {
    scheme  = "http",
    host    = "localhost",
    port    = 8080,
    method  = "GET",
    path    = "/",
    headers = {},
    body    = nil,
    thread  = <userdata>,
  }

以上定義了一個table類型的全局變量,修改該wrk變量,會影響所有請求。

方法:

    1.wrk.fomat

    2.wrk.lookup

    3.wrk.connect

上面三個方法解釋如下:

function wrk.format(method, path, headers, body)

    wrk.format returns a HTTP request string containing the passed parameters
    merged with values from the wrk table.
    # 根據參數和全局變量 wrk,生成一個 HTTP rquest 字符串。

function wrk.lookup(host, service)

    wrk.lookup returns a table containing all known addresses for the host
    and service pair. This corresponds to the POSIX getaddrinfo() function.
    # 給定 host 和 service(port/well known service name),返回所有可用的服務器地址信息。

function wrk.connect(addr)

    wrk.connect returns true if the address can be connected to, otherwise
    it returns false. The address must be one returned from wrk.lookup().
    # 測試給定的服務器地址信息是否可以成功創建連接

二、通過Lua腳本壓測示例

調用POST接口:

wrk.method = "POST"
wrk.body   = "foo=bar&baz=quux"
wrk.headers["Content-Type"] = "application/x-www-form-urlencoded"

注意:wrk是個全局變量,這裏對其做了修改,使得所有請求都使用POST的方式,並指定了body和Content-Type頭。

自定義每次請求的參數:

request = function()
   uid = math.random(1, 10000000)
   path = "/test?uid=" .. uid
   return wrk.format(nil, path)
end

在request方法中,隨機生成1~10000000之間的uid,並動態生成請求URL。

每次請求前,延遲10ms:

function delay()
   return 10
end

請求的接口需要先進行認證,獲取token後,才能發起請求,處理如下:

token = nil
path  = "/auth"

request = function()
   return wrk.format("GET", path)
end

response = function(status, headers, body)
   if not token and status == 200 then
      token = headers["X-Token"]
      path  = "/test"
      wrk.headers["X-Token"] = token
   end
end

上面的腳本表示,在token爲空的情況下,先請求/auth接口來認證,獲取token,拿到token以後,將token放置到請求頭中,再請求真正需要壓測的/test接口。

壓測支持HTTP pipeline的服務:

init = function(args)
   local r = {}
   r[1] = wrk.format(nil, "/?foo")
   r[2] = wrk.format(nil, "/?bar")
   r[3] = wrk.format(nil, "/?baz")

   req = table.concat(r)
end

request = function()
   return req
end

通過在init方法中將三個HTTP請求拼接在一起,實現每次發送三個請求,以使用HTTP pipeline。

三、Lua腳本測試場景

POST+header+body

1.首先創建一個post.lua的文件:

wrk.method = "POST"  
wrk.body   = "foo=bar&baz=quux"  
wrk.headers["Content-Type"] = "application/x-www-form-urlencoded"  

2.輸入命令執行:

wrk -t 12 -c 100 -d 30s -T 30s --script=post.lua --latency http://www.baidu.com  

3.壓測結果如下:

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章