Apache BenchとVegetaを使ってLiteSpeed／Nginx／Apacheを性能比較

# はじめに
この記事は[富士通クラウドテクノロジーズ Advent Calendar 2021](https://qiita.com/advent-calendar/2021/fjct)の23日目の記事です。

こんにちは。富士通クラウドテクノロジーズ株式会社でビジネス職をしている@s_aveです。
昨日の記事は@kswさんによる[Gopacketでパケットをキャプチャしたり生成したりしてみる](https://qiita.com/ksw/items/0849d9c02d26266b03b3)でした。わたしはパケットの中身については昔情報処理技術者試験の本で学んだうろ覚えの知識しかないので、今度こちらの記事を参考に試してみたいと思いました。

今日の記事はLiteSpeedとNginxとApacheの性能比較についてになります。
最近新しくサービスを作ることになったのですが、エンジニアからWEBサーバーはLiteSpeedを使うと聞きました。わたしのこれまでの認識ではLinuxで使うWEBサーバーと言えばApacheかNginxで、LiteSpeedというのは初耳だったので試しにインストールと簡単な性能比較をしてみることにしました。

1台のLinuxサーバーにLiteSpeedとNginxとApacheをインストールして別のportで同時起動することで、同一条件での性能比較を行います。


# LiteSpeedとは
調べてみると「Apache」「Nginx」「IIS」に次ぐ第四のWEBサーバーと呼ばれているとのこと。特徴としてはApacheとの互換性が高く、ApacheやNginxよりもパフォーマンスが良いとのことでした。

初版リリース自体は2003年とかなり古いですが、W3TechsのWEBサーバーシェア比較によると昨年くらいから急激に利用が伸びていて、今年になってIISのシェアを上回ったようです。これから新しくWEBサーバーを立てる場合の選択としては旬な感じがします。

![web_share2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2295093/a105da19-a672-a14e-9213-d05a4fd769ca.png)出典：[w3techs](https://w3techs.com/technologies/history_overview/web_server)

わたしがよくサーバーを触っていた10年くらい前まではLinuxのWEBサーバーと言えばApache一択で、Nginxが話題になり始めたくらいだったと記憶していますが、今やApacheのシェアは3割ほど。知らぬ間に大きくシェアが変わっていたようです。


# WEBサーバーの準備
#### LiteSpeedのインストールと起動
今回使用したOSはCentOS8.3です。CentOSのリポジトリにはLiteSpeedがないので追加が必要です。
LiteSpeedが依存するパッケージからインストールします。手順は以下の通りです。

```
# yum -y install epel-release
# rpm -Uvh http://rpms.litespeedtech.com/centos/litespeed-repo-1.2-1.el8.noarch.rpm
# yum -y install openlitespeed
```

インストールが完了したらServiceコマンドで起動して、プロセスの確認を行います。

```
# service lsws start
# ps -ef|grep http
root        4674       1  0 18:11 ?        00:00:00 openlitespeed (lshttpd - main)
nobody      4676    4674  0 18:11 ?        00:00:00 openlitespeed (lshttpd - #01)
nobody      4677    4674  0 18:11 ?        00:00:00 openlitespeed (lshttpd - #02)
root        4850    4814  0 18:13 pts/0    00:00:00 grep --color=auto http
```

無事に起動しました。サーバーを停止するときは`service lsws stop`となります。LiteSpeedはインストール直後はポートが8088番になっていますので通常はWEBコンソールから80番に変更しますが、今回はそのままにしておきます。

#### Nginxのインストールと起動
NginxはCentOSのリポジトリにありますが、最新バージョンではないのでNginx公式リポジトリからインストールします。しかし長くなってしまうのでここでは省略します。インストール方法は以下のサイトなどを参考にしてください。

https://hirooooo-lab.com/development/install-nginx-for-centos/

インストールが完了したらserviceコマンドで起動して、プロセスの確認を行います。

```
# service nginx start
# ps -ef|grep nginx
root        5033       1  0 18:17 ?        00:00:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
nginx       5034    5033  0 18:17 ?        00:00:00 nginx: worker process
nginx       5035    5033  0 18:17 ?        00:00:00 nginx: worker process
```

無事起動しました。サーバーを停止するときは`service nginx stop`となります。Nginxはインストール直後はポートが80番になっていますが、そのまま使用します。

#### Apacheのインストールと起動
ApacheもCentOSのリポジトリのものは古いので、Nginx同様の手順を取ります。
以下のサイトに最新版のインストール方法の詳細の記述がありました。

https://w.atwiki.jp/sanosoft/pages/196.html

インストール直後はApacheも80番ポートを使う設定になっていますが、80番はNginxが使用しているので以下の手順でポートを8008番に変更します。

```
# vi /etc/httpd/conf/httpd.conf
```

```/etc/httpd/conf/httpd.conf
~

# Listen: Allows you to bind Apache to specific IP addresses and/or
# ports, instead of the default. See also the <VirtualHost>
# directive.
#
# Change this to Listen on specific IP addresses as shown below to
# prevent Apache from glomming onto all bound IP addresses.
#
#Listen 12.34.56.78:80
Listen 8008

~
```

インストールが完了したらserviceコマンドで起動して、プロセスの確認を行います。

```
# service httpd start
# ps -ef|grep http
root        8925       1  0 18:48 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache      8926    8925  0 18:48 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache      8927    8925  0 18:48 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache      8928    8925  0 18:48 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache      8929    8925  0 18:48 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
```

無事起動しました。サーバーを停止するときは`service httpd stop`となります。

#### ドキュメントルートにダミーファイルの設置
後述のベンチマークテストの際にファイル容量別のパフォーマンスを検証したいので、各WEBサーバーのドキュメントルートに以下のコマンドで作成したダミーファイルを設置します。`容量は上から順に1KB、1MB、10MB`です。

```
# dd bs=1K count=1 if=/dev/zero of=1KB.html
# dd bs=1M count=1 if=/dev/zero of=1MB.html
# dd bs=10M count=1 if=/dev/zero of=10MB.html
```

デフォルトのドキュメントルートの場所はそれぞれ以下の通りです。

|WEBサーバー|パス|
|:-:|:-:|
|LiteSpeed|/usr/local/lsws/Example/html/|
|Nginx|/usr/share/nginx/html/|
|Apache|/var/www/html/|

これでWEBサーバーの準備は完了です。

# ベンチマークツールの準備
#### ベンチマークツールの選定
WEBでいろいろ調べてみたところ、Apacheに同梱されているApache Benchというツールがインストールの必要もなく気軽に使えて良さそうです。

また、ほかにも選択肢がないか調べていたところ以下の記事を見つけました。

https://github.com/denji/awesome-http-benchmark

この中でstarの数から評判がよく、Apache Bench同様簡単に使えて、さらにApache Benchとは視点の違うレポートが得られるVegetaというツールも試してみることにしました。

https://github.com/tsenart/vegeta

ということで、今回の性能比較はApache BenchとVegetaを併用して行ってみたいと思います。

#### Apache Benchの実行テスト
前述の通り、Apacheがインストールされた時点で使えるようになっているため事前準備はいりません。使い方は、nオプションで総リクエスト数を指定し、cオプションで並列実行数を指定します。例えば以下のようにコマンドした場合、10ユーザーが同時接続してそれぞれ30リクエストします。

```
# ab -n 300 -c 10 http://kakarot:8088/1KB.html
This is ApacheBench, Version 2.3 <$Revision: 1879490 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/

Benchmarking kakarot (be patient)
Completed 100 requests
Completed 200 requests
Completed 300 requests
Finished 300 requests


Server Software:        LiteSpeed
Server Hostname:        kakarot
Server Port:            8088

Document Path:          /1KB.html
Document Length:        1024 bytes

Concurrency Level:      10
Time taken for tests:   0.024 seconds
Complete requests:      300
Failed requests:        0
Total transferred:      379200 bytes
HTML transferred:       307200 bytes
Requests per second:    12600.81 [#/sec] (mean)
Time per request:       0.794 [ms] (mean)
Time per request:       0.079 [ms] (mean, across all concurrent requests)
Transfer rate:          15554.12 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.1      0       1
Processing:     0    0   0.1      0       1
Waiting:        0    0   0.1      0       1
Total:          0    1   0.1      1       1

Percentage of the requests served within a certain time (ms)
  50%      1
  66%      1
  75%      1
  80%      1
  90%      1
  95%      1
  98%      1
  99%      1
 100%      1 (longest request)
```

WEBサーバーのパフォーマンスを見るための主な項目は、以下のあたりになるかと思います。

|項目|概要|実行テスト時の値|
|:-:|:-:|:-:|
|Requests per second|1秒間あたりのリクエスト処理可能件数|12600.81/sec|
|Time per request   |1リクエスト当たりの処理時間|0.794ms|


#### Vegetaの実行テスト
こちらはインストール作業からになります。
vegetaはgo言語で動くので、まずはgoをインストールします。

```
# wget https://storage.googleapis.com/golang/go1.17.5.linux-amd64.tar.gz
# tar -C /usr/local/ -xzf go1.17.5.linux-amd64.tar.gz
# export PATH=$PATH:/usr/local/go/bin
```

続いてvegetaさんをインストール

```
# wget https://github.com/tsenart/vegeta/releases/download/v12.8.4/vegeta_12.8.4_linux_amd64.tar.gz
# tar -C /usr/local/vegeta -zxvf vegeta_12.8.4_linux_amd64.tar.gz
# chmod +x vegeta
# export PATH=$PATH:/usr/local/vegeta
```

使い方は「vegeta attack」でリクエスト実行となります。rateオプションで1秒間のリクエスト数、durationオプションで何秒attackを継続するか指定できます。下記の例だと`1000リクエスト×3秒間＝3000リクエスト`を送信しています。コマンドの実行結果はバイナリデータとして返ります。このバイナリデータはパイプでつないだ「vegeta report」で出力できます。

```
# echo "GET http://kakarot:8088/1KB.html" | vegeta attack -rate=1000 -duration=3s | vegeta report
Requests      [total, rate, throughput]         3000, 1000.34, 1000.29
Duration      [total, attack, wait]             2.999s, 2.999s, 139.008µs
Latencies     [min, mean, 50, 90, 95, 99, max]  104.564µs, 141.779µs, 134.95µs, 157.983µs, 170.424µs, 343.462µs, 1.257ms
Bytes In      [total, mean]                     3072000, 1024.00
Bytes Out     [total, mean]                     0, 0.00
Success       [ratio]                           100.00%
Status Codes  [code:count]                      200:3000  
Error Set:
```

vegetaのレポートで確認できる性能指標はパーセンタイルごとのレイテンシーのみとなりますが、Apache Benchと違ってリクエストの成功率という項目があります。これは秒間のリクエスト数が100とか1000くらいのうちはほぼ100%となりますが、数千リクエスト以上の負荷をかけた場合に失敗するリクエストが出てきました。

#### Apache Benchとvegetaの特徴比較

Apache Benchとvegetaのレポート項目を比較してみます。

| レポート項目 | Apache Bench | vegeta |
|:-:|:-:|:-:|
|リクエスト処理時間|〇|〇|
|パーセンタイル別リクエスト処理時間|〇|〇|
| 秒間処理リクエスト数 | 〇 | × |
| リクエスト成功率 | ×  | 〇 |

WEBサーバーの基本性能を比較するにはApache Benchのレポート項目の秒間処理リクエスト数（Requests per second）がわかりやすいかなあと思いました。一方vegetaで秒間指定で大きなリクエストを投げてその成功率（Success）を見ることで、スパイク時の耐性確認ができるかなと思いました。次項ではこの辺りを組み合わせて、実際に性能比較を実施してみたいと思います。


# 性能テスト結果
#### Apache Benchでの性能テスト結果
リクエスト数は100、リクエスト時の同時接続は10で固定しています。

|ファイル容量| Requests per second(LiteSpeed) | Requests per second(nginx) | Requests per second(Apache) |
|:-:|:-:|:-:|:-:|:-:|
|1KB|12586.53|11689.98|7035.32|
|1MB|2891.26|2860.90|2771.31|
|10MB|362.12|372.71|334.20|

これを見ると軽いファイルが対象だとLiteSpeedがもっとも秒間に処理できるリクエスト数は多いようですが、ファイル容量が大きくなるにつれて差分は小さくなっていっているようです。特に10MBのファイルではNginxの方が上回ることが多いようでした。何度かテストしましたが、ファイル容量にかかわらずApacheのほうが良い数値が出ることはたまにしかありませんでした。

#### vegetaでの性能テスト結果
こちらは容量の大きいファイルを対象に実行するとエラーが頻発してしまったため、ファイル容量は1KBで固定しました。またdurationは3sで固定しています。

|秒間リクエスト数| Success(LiteSpeed) | Success(Nginx) | Success(Apache) |
|:-:|:-:|:-:|:-:|:-:|
|10,000|100%|100%|63.59%|
|15,000|34.15%|100%|18.44%|
|20,000|33.13%|37.88%|24.52%|

高負荷耐性についてはどうやらNginxがもっとも優秀なようです。

# まとめ
評判通りLiteSpeedの方がApacheよりもパフォーマンスが高いということがわかりましたが、Nginxとは条件によって変わるので一概に優劣はつけがたいという結果になりました。ただしこれはあくまで限られた条件でのベンチマークとなりますのでご参考までということで。

明日（12/24）の[富士通クラウドテクノロジーズ Advent Calendar 2021](https://qiita.com/advent-calendar/2021/fjct)は、@u-kojiさんの記事です。お楽しみに！