この記事は、富士通クラウドテクノロジーズ 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 |
メモ:細かいデータ
-
kzmake/benchmark-app-servers
- 各言語のVersion情報やwrkの結果
🌜おわりに
この記事では、スループットのみに着眼し、できるだけ広い言語で様々な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」 について書いてくれるみたいです。お楽しみに!