この記事は1100文字約3分で読めます

Elixirを使ってAPIの負荷試験ツールを作りましたな話です。

Table of Contents

負荷試験について本気出して考えてみた

業務のなかで、負荷試験について考える機会が多かった年始明けでしたので、せっかくなのでよりいい負荷試験ツールを自作してみようかと思いました。

負荷といえば並列なリクエスト、並列といえばやっぱジャイアンツElixirということで、Elixirで実装することにしました。

ElixirでHttpリクエストをするならHttpoison

HTTPoisonはElixirで使えるHTTPクライアントです。

使い方もとっても簡単で、GET、POSTは下記のように実施できます。

# GET
HTTPoison.get!("http://example.com",[],[{:timeout, :infinity}, {:recv_timeout, :infinity}])

# POST
payload = Poison.encode!(%{"contentType" => "image/png", "key" => "value"})

ret = HTTPoison.post!("http://example.com", payload, [],[{:timeout, :infinity}, {:recv_timeout, :infinity}])

upload_id = Poison.decode!(ret.body)["upload_id"]

GETはHTTPoison.get()、POSTはHTTPoison.post!() で実施できます。簡単ですね。

! がついているかついていないかは例外を上げるか上げないかの違いです。

ナオキ「例外あ、あげますね・・・。」

1つ目の引数はURLですね。

Payloadは2つ目の引数。Posion.encode!() にMapでKVを入れれば実現できます。これも簡単ですね!!残念ながら、GETのbodyは許容しません。

3つ目はHeader。今回は使いませんね。

4つ目はOptions。Timeoutなどを設定します。

Timeoutは**:recv_timeout:timeout**の2つを指定します。 負荷試験なので、Infinityにしておきます。

ResponseがJsonの場合は**Poison.decode!()**でKVでアクセスできます。簡単ですね!!

Elixirで並列処理するならTask.asyncでしょ

正直ここらへんはElixirのHttpoisonでAPI負荷検証ツールをつくったを参考にしてます。

  def send_requests_parallel(process_num,count) do
    time_total = Enum.map(1..process_num, &Task.async(fn ->
      &1
      send_requests(@url)
    end))
                 |> Enum.map(fn(task) -> Task.await(task,1000_000) end)
                 |> Enum.reduce(0, fn x,total -> total + x end)
    IO.inspect "#{count}, average_time: #{time_total / process_num / 1000} ms, time_total: #{time_total / 1000} ms"
  end

とやることで、並列処理&返ってきた実行時間をreduceで集計できます。すごいすごい。

CSVに出力

こちらも超簡単。CSVという便利なライブラリをmixから落とせば簡単に実現できます。

 def write_csv() do
    file = File.open!("response.csv", [:append, :utf8])
    table_data = [["aaa","bbb", "ccc", "ddd"]]
    table_data |> CSV.encode(headers: false) |> Enum.each(&IO.write(file, &1))
  end

簡単ですね!

完成

完成しました。

elixir_performance_tool

ついでにElixirのドキュメントツールex_docを使ってドキュメントも作ってみました。

Ebook Homebrew: ElixirPerformanceTool

Elixirとっつきにくいかなぁと思いましたが、意外に簡単でした。

こんな感じでAPIのレスポンスタイムを取得できました。

iex> ElixirPerformanceTool.run(10,10)
"0, average_time: 1422.0 ms, time_total: 1422.0 ms"
"2, average_time: 843.0 ms, time_total: 843.0 ms"
"1, average_time: 1969.0 ms, time_total: 1969.0 ms"
"3, average_time: 844.0 ms, time_total: 844.0 ms"
"4, average_time: 844.0 ms, time_total: 844.0 ms"

tubone24にラーメンを食べさせよう!

ぽちっとな↓

Buy me a ramen

 Related Posts

hatena bookmark