いくつかのWebフレームワークのベンチマークを雑にとってみた


この記事は、富士通クラウドテクノロジーズ Advent Calendar 2018 の18日目の記事です。

17日目は @abej さんの 海外ITカンファレンス動画のすすめ でした!

🌞はじめに

NIFCLOUD の API を開発している @kzmake です。最近、趣味で色々なWebフレームワークを触ることにはまってたり。

今日では様々なWebフレームワークが存在しており、それを利用して手軽にWebアプリケーションを開発できるようになっていますよね。ただ、あまりにも種類が多く、Webフレームワークの選定基準に何を選択するか悩む場面もあるのではないでしょうか。

本記事では、負荷検証をのWebフレームワークに対して実施し、それぞれの 「処理能力」に着目して簡単な比較を行ってみたいと思っています。

※下記に影響されて検証してみます

📝注意書き

  • あくまで検証のため綺麗な記述や言語毎に十分な最適化をおこなっているわけではありません。フレームワーク毎適切な記述をすることで改善される場合も十分あります。
  • 言語の宣伝や批判を行うものではありません。 言語やアプリケーションサーバー、フレームワーク毎にそれぞれ優れている点があります。

💡TL;DR

  • jester(Nim) や japronto(python) がとってもはやい
  • 言語的に golang / Scala / Rust / Nim あたりが全体的にはやい
  • flask(python) / Ruby on Rails(Ruby) は他と比べると低RPS

🤔Webアプリケーションの「速さ」とは何をもとに考えるべきか?

Webアプリケーションの「速さ」といえばなんでしょうか?

  • 応答時間の速さ
  • RPS(Requests per second)
  • Time To First Byte (TTFB)

なんかがありますよね。これについては、こちらの記事がとてもわかりやすくまとめてくださっているので、本記事では割愛させてもらいます。

負荷試験のためのノウハウと Webフレームワークの負荷試験 (Python,Node,Go,PHP)

今回は、単純にWebフレームワークの処理能力 を測るので リクエストのスループットとして RPS(Requests per second)に着眼してそれぞれのWebフレームワークを見てみたいと思います。

⚙️検証内容

作成するWebアプリケーション

下記の機能を持つ必要最低限のWebアプリケーションをそれぞれのWebフレームワークを利用して作成する。

機能

  • text/plain としてレスポンスを返却
  • Hello, World! の文字列を返却する

検証方法

今回は、wg/wrk を利用して検証してみたいと思います。
(今回は RPS を測定するのみなので Coordinated Omission補正込みの giltene/wrk2 は使用しません)

本記事では、 5回計測し、 RPS がもっとも良い結果をピックアップするものとします。

環境

今回の検証では NIFCLOUD のクラウドサービスを利用して検証しました。

Webアプリケーションサーバー(負荷試験対象)

  • NIFCLOUD type: large
  • Intel(R) Xeon(R) CPU E5-2697 v3 @ 2.60GHz (4 cores)
  • 4 GB
  • Ubuntu 18.04 LTS

負荷試験用サーバー(wrk実行用)

  • NIFCLOUD type: large
  • Intel(R) Xeon(R) CPU E5-2697 v3 @ 2.60GHz (4 cores)
  • 16 GB
  • Ubuntu 18.04 LTS

Network

PrivateLan を作成し、Webアプリケーションサーバー(AppServer) と 負荷試験用サーバー(Load) 間に Network を構築します。

[AppServer] : 192.168.10.10 ----------- [Load] : 192.168.10.5

Settings

このあたりは適当に。

/etc/sysctl.conf
net.ipv4.ip_local_port_range = 1024 65535
net.ipv4.tcp_tw_reuse = 1
net.ipv4.ip_dynaddr = 1
net.ipv4.tcp_rfc1337 = 1
net.ipv4.tcp_fin_timeout = 10
net.ipv4.tcp_keepalive_probes = 5
net.ipv4.tcp_slow_start_after_idle = 0
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
/etc/security/limits.conf
*    soft nofile 65536
*    hard nofile 65536
root soft nofile 65536
root hard nofile 65536
/etc/pam.d/common-session
session    required     pam_limits.so

検証用アプリケーション

🔥検証結果

Results

同時接続数100のときのRPSでsort。

c: connections

Language Frameworks RPS(c=10) RPS(c=100) RPS(c=1K)
Python japronto 35192.51 182209.20 313111.38
Rust hyper 31478.74 181978.18 250753.83
Nim jester 37875.16 180562.05 267158.10
Golang fasthttp 32896.92 178742.38 272827.53
Scala colossus 30223.88 153630.81 173208.76
Python gunicorn + meinheld 30511.41 142269.85 147096.10
Golang net/http 27543.16 112160.14 126247.31
Golang echo 27501.64 107365.95 121058.50
Golang gin 27195.70 102053.41 117794.30
Scala Finatra 25884.09 101039.92 95836.10
Rust iron 32352.37 79042.21 78359.21
Scala finch 23548.16 67201.73 67690.82
Elixir cowboy 21982.09 62189.22 58050.46
Scala akka-http 14829.31 60694.92 65393.73
Scala Play Framework 2.x + netty 21157.73 54774.22 59055.88
Elixir cowboy + plug 20930.40 48501.17 42336.23
Scala http4s 20936.95 41011.60 41406.29
Elixir cowboy2 + plug 17279.92 33547.23 30558.31
Ballerina Ballerina 13055.05 26570.28 32383.85
Python gunicorn + flask + meinheld 15485.77 21216.30 20185.63
Elixir cowboy + phoenix 15972.04 19897.84 29068.48
Python bjoern + bottle 14890.77 17342.36 16298.68
Elixir cowboy2 + maru 13616.37 15345.62 14410.75
Python gunicorn 7679.21 11505.21 10999.50
Node.js express 9871.12 9844.02 9687.88
Python uwsgi + flask 6575.53 8327.47 8272.04
Python gunicorn + flask 3961.87 7499.01 7328.44
Python gunicorn + django 3459.65 4085.68 5958.89
Ruby Ruby on Rails 5.x + unicorn 3990.49 3748.68 3941.27
Python bottle 2403.29 2318.08 1752.36
Ruby Ruby on Rails 5.x + puma 3075.53 2134.67 2241.91
Python flask 1077.82 1207.28 1205.87

メモ:細かいデータ

🌜おわりに

この記事では、スループットのみに着眼し、できるだけ広い言語で様々なWebフレームワークをテストしてみました。

結果としては、単純にスループットだとGolang、Scala、NimやRustが安定して高RPS、PythonやRubyは他と比べて低RPSとなった。ただ、pythonでもjaprontoが最も高いRPSを記録するといった面白い結果がみられました。

他にも、全体的に低RPSのpythonでもgunicorn + flask + meinheldの組み合わせなどで高いRPSもだせることもわかりました。

今回は単純にPlaintextを返すだけのアプリケーションでしたが、より複雑なベンチマークを行っている

TechEmpower / Web Framework Benchmarks

も見てみるとおもしろいかもしれません!

みなさんの普段使っているWebフレームワークもテストし、比較してみてはいかがでしょうか?
長い記事にお付き合いいただき、ありがとうございました!

明日は @YOMOGItaro さんが 「NIFCLOUD で Elastic Cloud Enterprise」 について書いてくれるみたいです。お楽しみに!