ぼくのかんがえたさいきょうのwordpress

※タイトルは一度使ってみたかっただけで、深い意味はありません。

# 前置き

[今年イチ！お勧めしたいテクニック by ゆめみ feat.やめ太郎 Advent Calendar 2019](https://qiita.com/advent-calendar/2019/yumemi_no1) ってのに参加しております。

ワイ「なんか睡眠が捗りそうな椅子もらえるらしいねんナー」
ワイ「やめ太郎って人、よくしらんけどなんとなくポチっとしといたろうかしら」
ワイ「ちょうど業務関連で深掘りしときたいこっとあるしな」

・・みたいな感じで気楽にエントリしたわけですが、・・なんか一人称が**ワイ**じゃなくちゃアカンのか、ってくらいのノリの記事が多く、正直尻込みしております。。

が、せっかくだし何か書かねば。
気を入れなおしてこっからは普通のノリでお送りいたします。

# 本題

ちょっと前にお仕事にて、

- 高速化
- 冗長化
- コスト最適化

をテーマに、既存のwordpressの移行を行ったりしてみたりしました。
ただ、ちょっとやり残した事があるというか、検証したかった事があったので試すだけためしてみようという記事です。

# 目次

- システム構成
- before構成
- いざ構築
 - KUSANAGI
 - FSx for Luster
 - cloud front
 - Lambda@Edge

# システム構成

![bokunosaikyou.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308709/4d345eee-b64f-637a-73a2-1f01699c56d2.png)

こんな感じの事をしたい。

- Lambda@Edge
- cloudFront
- ALB
- EC2
- KUSANAGI
- FSx for Luster
- S3
- RDS
- wordpress plugin ewww

## 背景設定
- そこそこ稼いでる(or 稼ぎたい)メディアサイト
- イベント的な要因で瞬間的にアクセスが跳ね上がる事がある
- ユーザーから書き込み(コメント)はない
- 数分でも落ちたら嫌。冗長性必須。

今回は簡略化して、autoscaleとRDS省きます。
冗長構成を考えると当然必要なんですけど、ボリューム的な都合により。
~~wordpressについてはKUSANAGIパッケージに乗っかっているやつを使います。~~
↑と思ってたけど、bitnamiってやつでいくことにしました。

## bitnami
Bitnamiは、Webアプリケーションとソリューションスタック、および仮想アプライアンス用のインストーラーまたはソフトウェアパッケージのライブラリです。

これをbeforeでもafterでも使います。

# before環境

比較用にbefore相当の環境を作っておきます。

## wordpress instance
まずは比較のためのsimpleなwordpressを立ててみます。
めんどいのでwordpress入りのamiでさくっと立てましょう。
正直、どれがいいのかわかんないけど、
**WordPress Certified by Bitnami and Automattic**
っていうamiにしてみました。ubuntuがちょっと古いけど。
インスタンスタイプは・・あまりちっちゃいと比較しにくいかもしんないので、t3a.smallくらいにしときましょう。

| Key| Value |
|:-----------------|:------------------|
| AMI             |              ami-0b631dddc01e136d5 | 
| OS | ubuntu 16.04 |
| instance type | t3a.small |
| ストレージ | gp2 20GB |
| wordpress | 5.3 |
| apache | 2.4.41 |
| php | 7.3.11 |
| mysql | 8.0.18 |
| port | 今回はめんどいので80番 |

単なるwordpressです。
インスタンス起動してブラウザでアクセスするとあっさり繋がります。

1. http://xx.xx.xx.xx/bitnami/wp-admin/ からログインする。ユーザーはuserで、パスワードは/var/log/syslogに出てる
2. [テーマユニットテストデータ](https://wpdocs.osdn.jp/%E3%83%86%E3%83%BC%E3%83%9E%E3%83%A6%E3%83%8B%E3%83%83%E3%83%88%E3%83%86%E3%82%B9%E3%83%88) をインポートしておきます

こんな感じになります

![スクリーンショット 2019-12-01 16.08.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308709/7ca2725a-13e1-0feb-458c-6200c7758df7.png)

## JMeter

高速化だとかほざいておりますので、当然負荷テストをかけておかないといけないです。（ただし、awsに申請が必要なレベルではやらない。インスタンス的にもNGだし）
今回、cloudfrontだとか画像最適化も考慮したいので単一のページではなく、ページに付随するcssやらjsも考慮したいところ。よってJMeterを使います。
こちらもめんどいのでAMI探してさっくりと。

**JMeter Master-20130206**

とりあえずこれにしてみました。
さっくりとJMeterを使えればなんでもいい。

JMeterの設定についてはこちらを参照させていただきました。
https://devlog.arksystems.co.jp/2019/01/23/6596/

![スクリーンショット 2019-12-01 17.34.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308709/027d6b25-7c76-0b8f-e6db-703a8e96a16a.png)

※ **全てのイメージとアプレットを繰り返しダウンロードする** のチェックがポイント

スレッド数はこんな感じ。

![スクリーンショット 2019-12-01 19.08.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308709/778d168f-0652-bf0a-6959-c1eefa6dd92f.png)

ざっくりと1000x3アクセス？リクエスト数は静的ファイルの分だけ増えると思う。

ロードアベレージはグイグイあがる。

![スクリーンショット 2019-12-01 18.07.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308709/64f42d73-ac34-fcb0-a8bd-27bf57aadccf.png)

アクセスログみた感じだとちゃんと静的ファイルにもアクセスしてる

![スクリーンショット 2019-12-01 17.57.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308709/dd5b1e82-52bf-bf41-7b88-bd09dc639d4c.png)

ただ、304がいっぱい返ってるのでブラウザキャッシュは効いてますね。

正直、見方はあまりわからんのですが・・
Error: 5.03%, スループット: 10.0/sec、　KB/sec: 2303.6あたりが指標か。
これを5分で捌いてる。（ただロードアベレージ的にこれが限界かなー)

![スクリーンショット 2019-12-01 19.12.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308709/41d6340a-f10f-4afb-5563-52c7e38c539b.png)


とりあえず素のwordpressはこんな感じ。bitnamiってとこのAMI使ったけど、これけっこうチューニングされてるのかもしれんなぁ。

あとLight Houseも

![スクリーンショット 2019-12-01 18.19.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308709/92893eb6-a938-16d9-ec66-ef79b45f9327.png)

これはだいたい予想通り。プラグインとかほぼ空だし、逆にスコアはいいだろうなと思ってました。




## KUSANAGI

**※これは没案！**
**Fsx for lusterのmountがうまくいかず本記事では諦めました。。**

プライムストラテジーさんのKUSANAGI AMIを使ってみます。Businessとそうじゃないのと、Premiumなんかもありますが、今回は普通の使います。

**KUSANAGI for AWS (WordPress)**

インスタンスサイズとかは先ほどのwordpressと同じにしたかったけど、普通KUSANAGIはt3系に対応してないようなのでt2です。

| Key| Value |
|:-----------------|:------------------|
| AMI             |              ami-3a5a415d | 
| OS | centos 7.2 |
| instance type | t2.small |
| ストレージ | gp2 50GB |
| wordpress | 5.3 |
| nginx | 1.17.6 |
| php | 7.3.12 |
| mariadb | 10.0.38 |
| port | 今回はめんどいので80番 |

ちょっと今回ボリュームが多いので細かいことは省きますが、まずはインスタンスにログインし、KUSANAGIをsetupします。
rootユーザーで ```kusanagi init``` ってやった後、 ```kusanagi provision [profilename]``` ってやると完了。
それと ```kusanagi bcache on```ってやってキャッシュを効かせておきます。

で、KUSANAGIのみでJMeter.
Error0%がいいすね。スループットは10.0sec KB/secは2264.4。

![スクリーンショット 2019-12-01 19.24.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308709/b6ae2320-cec8-f5c5-cdc1-b15cce6476b0.png)

**没案ではあるんだけど、せっかく負荷テストもやったので掲載だけ**

## 結局afterもこちらのwordpress

| Key| Value |
|:-----------------|:------------------|
| AMI             |              ami-0b631dddc01e136d5 | 
| OS | ubuntu 16.04 |
| instance type | t3a.small |
| ストレージ | gp2 20GB |
| wordpress | 5.3 |
| apache | 2.4.41 |
| php | 7.3.11 |
| mysql | 8.0.18 |
| port | 今回はめんどいので80番 |

こっちでやることになりました。nginxにしたかったような気はするけど、今のapacheだと遜色ない気はするしまあいっか。
ちなみに、apacheのconfは `/home/bitnami/apps/wordpress/conf` に、documentrootは `/opt/bitnami/apps/wordpress/htdocs` にあるみたい。
`/opt/bitnami/apps/wordpress/conf/`にあるconfも読んでそうだけど。

## page cache
ページキャッシュは必要なので、今回はシンプルなやつを入れておきます。

[Simple cache](https://wordpress.org/plugins/simple-cache/)

## FSx for Luster + S3 + plugin

https://aws.amazon.com/jp/fsx/lustre/

はい。個人的はここが肝です。実はここだけでもよかった。

> Amazon FSx for Lustre では、機械学習、ハイパフォーマンスコンピューティング (HPC)、ビデオ処理、財務モデリング、電子設計オートメーション (EDA) などのワークロードの高速処理用に最適化されたハイパフォーマンスファイルシステムが提供されます。これらのワークロードでは通常、データは高速でスケーラブルなファイルシステムインターフェイスを介して表示される必要があります。また、Amazon S3 などの長期のデータストアには保存されたデータセットがあるのが一般的です。

ってことで・・、wordpressはぜんぜん関係なさそう。
だがしかしかしかし。

>Amazon FSx for Lustre は Amazon S3 とネイティブに連携し、ハイパフォーマンスファイルシステムを使用したクラウドデータセットの処理を簡単にします。S3 バケットとリンクさせると、FSx for Lustre ファイルシステムは S3 オブジェクトをファイルとして透過的に表示します。

やべえ、これほしい。
auto scale考えた場合、なんらかの方法でinstance間のデータを共有しなくちゃいけないわけで、かつ静的ファイルはS3にオフロードしたい。

s3fs or goofys → めっちゃ遅い。不安定？
EFS → やや遅い。S3非連携

って事でちょうど良いサービスがありません・・と思っていたところなんとなく見つけたFSx・・これはドンピシャじゃね？機械学習向けとあるけど、普通にディスク共有用途で使ったらアカンの？

・・というわけで使ってみたいなーと。
ちなみに料金は1 時間あたり 0.000194 USD/GBらしく、最低の容量が1.2TB。おおよそ月2万くらいか。それなりに大きいメディアサイトじゃないときついかな。

FSxのクライアント周りとかはこちらが参考になります。
https://dev.classmethod.jp/cloud/aws/reinvent2018-amazon-fsx-for-lustre-2/
なお、クライアントはhttps://downloads.whamcloud.com/public/lustre/lustre-2.12.3/el7/client/RPMS/x86_64/　にあるあたりのやつにしました。

なお、mount pointは複数指定してもいけるっぽい。冗長化にもなるって事？
> mount -t lustre \
  192.168.227.11@tcp1:192.168.227.12@tcp1:/demo \
  /lustre/demo

http://wiki.lustre.org/Mounting_a_Lustre_File_System_on_Client_Nodes

試しにやってみたらmountできた。

```
# mount -t lustre -o noatime,flock fs-xxxxxx.fsx.ap-northeast-1.amazonaws.com@tcp:fs-xxxxxx.fsx.ap-northeast-1.amazonaws.com@tcp:/fsx /fsx
# mount -l | grep 'fsx'
172.31.10.53@tcp:172.31.39.131@tcp:/fsx on /fsx type lustre (rw,noatime,flock,lazystatfs)
```

1. S3バケット作成 (wp-static-fsx-lusterとした）
2. FSxクライアント設定
3. FSx create
4. wordpress reboot
5. `cp -a /opt/bitnami/apps/wordpress/htdocs /tmp/`
5. ```sudo mount -t lustre -o noatime,flock,uid=`su bitnami -c 'id -u'` fs-xxxxxx.fsx.ap-northeast-1.amazonaws.com@tcp:fs-xxxxxx.fsx.ap-northeast-1.amazonaws.com@tcp:/fsx  /opt/bitnami/apps/wordpress/htdocs
6. rsync -a /tmp/htdocs /opt/bitnami/apps/wordpress/htdocs
``

今回はhtdocsをまるっとマウントしてしまう。

なおfstabには`fs-xxxxxx.fsx.ap-northeast-1.amazonaws.com@tcp:/fsx /opt/bitnami/apps/wordpress/htdocs lustre noatime,flock 0 0`みたいに書くといけると思う。

![スクリーンショット 2019-12-01 20.02.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308709/ed45ca43-25b2-2cef-c7f6-a92dc8d16d7e.png)

あと、`bitnami`ってコンテンツが別にあるみたいで、ひとまず、`cp -a /opt/bitnami/apps/bitnami/banner/htdocs htdocs/bitnami`しておきました。この中のimagesとかもS3に置きたいので。そしてそれだけでは足りなくて、`/opt/bitnami/apache2/conf/httpd.conf`からmodpagespeedのとこをコメント化してます。画像ファイル名とか動的に変換されちゃってもS3上のファイル名は変わらないので。

### Data repository

https://docs.aws.amazon.com/ja_jp/fsx/latest/LustreGuide/import-data-repository.html

S3との連携ってもっとリアルタイムなのかと思いきや、いちいちコマンドを実行しないといけないらしい。

exportしたいファイルに対して下記を実行する

```
sudo lfs hsm_archive path/to/export/file
sudo lfs hsm_action path/to/export/file
```

実際にexportするのがarchiveで確認がaction？実際確認してみるとarchiveの段階でS3にファイル作られてる。

```
sudo lfs hsm_archive /opt/bitnami/apps/wordpress/htdocs/readme.html
```

で、今回はまるごとexportするので再帰的に全部。
実運用時は`gulp`みたいなタスクランナーで変更を拾ってリアルタイムで実行するか、cronで定期的に実行するかのどっちでしょうか。ただ、今回は手動のみでやってます。
WP OFFLOAD LITEみたいなプラグイン使ってもいいし。

```
nohup find /opt/bitnami/apps/wordpress/htdocs -type f -print0 | xargs -0 -n 1 sudo lfs hsm_archive &
```

![スクリーンショット 2019-12-08 15.41.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308709/1bd6411b-c88a-da8c-7879-0721ba0910d4.png)

s3からimportする時は `sudo lfs hsm_restore path/to/file` らしい。

### EBS vs FSx for luster

簡単に性能比較してみます。

```apt-get install dbench```

**FSx for Luster**

```
# dbench -D /opt/bitnami/apps/wordpress/htdocs -t 30 64
dbench version 4.00 - Copyright Andrew Tridgell 1999-2004

Running for 30 seconds with load '/usr/share/dbench/client.txt' and minimum warmup 6 secs
53 of 64 processes prepared for launch   0 sec
64 of 64 processes prepared for launch   0 sec
releasing clients
   0         1     0.00 MB/sec  warmup   1 sec  latency 1000.025 ms
  59        53    72.27 MB/sec  warmup   2 sec  latency 1999.727 ms
  64       142   131.16 MB/sec  warmup   3 sec  latency 246.338 ms
  64       222   137.71 MB/sec  warmup   4 sec  latency 152.742 ms
  64       301   142.26 MB/sec  warmup   5 sec  latency 152.906 ms
  64       467   172.32 MB/sec  execute   1 sec  latency 170.971 ms
  64       581   202.93 MB/sec  execute   2 sec  latency 273.271 ms
  64       673   159.14 MB/sec  execute   3 sec  latency 341.279 ms
  64       757   122.67 MB/sec  execute   4 sec  latency 258.467 ms
  64       837   100.58 MB/sec  execute   5 sec  latency 353.219 ms
  64       903    85.61 MB/sec  execute   6 sec  latency 183.500 ms
  64       966    75.88 MB/sec  execute   7 sec  latency 206.277 ms
  64      1037    71.84 MB/sec  execute   8 sec  latency 378.735 ms
  64      1105    65.94 MB/sec  execute   9 sec  latency 193.713 ms
  64      1171    59.77 MB/sec  execute  10 sec  latency 162.291 ms
  64      1240    55.90 MB/sec  execute  11 sec  latency 200.001 ms
  64      1338    58.85 MB/sec  execute  12 sec  latency 225.814 ms
  64      1428    60.73 MB/sec  execute  13 sec  latency 337.389 ms
  64      1489    56.55 MB/sec  execute  14 sec  latency 198.007 ms
  64      1554    53.02 MB/sec  execute  15 sec  latency 205.202 ms
  64      1620    49.95 MB/sec  execute  16 sec  latency 215.090 ms
  64      1691    47.23 MB/sec  execute  17 sec  latency 225.859 ms
  64      1766    44.82 MB/sec  execute  18 sec  latency 297.534 ms
  64      1839    42.68 MB/sec  execute  19 sec  latency 229.806 ms
  64      1906    40.74 MB/sec  execute  20 sec  latency 236.403 ms
  64      1985    39.06 MB/sec  execute  21 sec  latency 249.424 ms
  64      2059    37.60 MB/sec  execute  22 sec  latency 208.590 ms
  64      2125    36.17 MB/sec  execute  23 sec  latency 221.537 ms
  64      2199    35.28 MB/sec  execute  24 sec  latency 247.253 ms
  64      2280    35.09 MB/sec  execute  25 sec  latency 313.954 ms
  64      2348    34.88 MB/sec  execute  26 sec  latency 282.232 ms
  64      2397    34.00 MB/sec  execute  27 sec  latency 192.056 ms
  64      2451    33.45 MB/sec  execute  28 sec  latency 373.561 ms
  64      2514    33.17 MB/sec  execute  29 sec  latency 220.548 ms
  64  cleanup  30 sec
  64  cleanup  31 sec
   0  cleanup  32 sec

 Operation      Count    AvgLat    MaxLat
 ----------------------------------------
 NTCreateX      23728    26.458   378.731
 Close          20485    15.152   299.935
 Rename          1018    55.923   353.211
 Unlink          2466    18.322   217.230
 Qpathinfo      21975    12.610   310.630
 Qfileinfo       6155     0.066    18.913
 Qfsinfo         2823     0.048    10.331
 Sfileinfo       3128    27.681   332.187
 Find            7524    59.454   337.382
 WriteX         21971     1.642   190.287
 ReadX          27888     0.656    67.567
 Flush           2177     7.575    56.194

Throughput 33.1705 MB/sec  64 clients  64 procs  max_latency=378.735 ms
```

**EBS (gp2)**

```
# dbench -D / -t 30 64
dbench version 4.00 - Copyright Andrew Tridgell 1999-2004

Running for 30 seconds with load '/usr/share/dbench/client.txt' and minimum warmup 6 secs
28 of 64 processes prepared for launch   0 sec
64 of 64 processes prepared for launch   0 sec
releasing clients
  64       136   363.25 MB/sec  warmup   1 sec  latency 73.456 ms
  64       199   251.62 MB/sec  warmup   2 sec  latency 40.216 ms
  64       251   202.58 MB/sec  warmup   3 sec  latency 415.909 ms
  64       327   190.02 MB/sec  warmup   4 sec  latency 104.348 ms
  64       391   177.53 MB/sec  warmup   5 sec  latency 350.702 ms
  64       518   121.67 MB/sec  execute   1 sec  latency 1092.738 ms
  64       595   114.03 MB/sec  execute   2 sec  latency 330.788 ms
  64       703   112.75 MB/sec  execute   3 sec  latency 321.848 ms
  64       939   104.16 MB/sec  execute   4 sec  latency 255.418 ms
  64      1292    99.61 MB/sec  execute   5 sec  latency 185.949 ms
  64      1636   107.89 MB/sec  execute   6 sec  latency 351.779 ms
  64      2029   112.46 MB/sec  execute   7 sec  latency 349.697 ms
  64      2433   110.81 MB/sec  execute   8 sec  latency 351.496 ms
  64      2904   113.41 MB/sec  execute   9 sec  latency 400.277 ms
  64      3180   117.83 MB/sec  execute  10 sec  latency 337.155 ms
  64      3517   120.44 MB/sec  execute  11 sec  latency 358.347 ms
  64      3925   123.73 MB/sec  execute  12 sec  latency 360.577 ms
  64      4268   120.65 MB/sec  execute  13 sec  latency 417.560 ms
  64      4796   120.98 MB/sec  execute  14 sec  latency 116.217 ms
  64      5416   129.68 MB/sec  execute  15 sec  latency 212.721 ms
  64      6148   133.86 MB/sec  execute  16 sec  latency 270.346 ms
  64      6727   140.66 MB/sec  execute  17 sec  latency 292.476 ms
  64      7204   143.24 MB/sec  execute  18 sec  latency 231.951 ms
  64      7781   146.07 MB/sec  execute  19 sec  latency 262.479 ms
  64      8402   147.27 MB/sec  execute  20 sec  latency 160.860 ms
  64      9018   151.23 MB/sec  execute  21 sec  latency 221.926 ms
  64      9633   152.24 MB/sec  execute  22 sec  latency 226.788 ms
  64     10233   156.89 MB/sec  execute  23 sec  latency 303.108 ms
  64     10738   158.04 MB/sec  execute  24 sec  latency 253.192 ms
  64     11276   159.37 MB/sec  execute  25 sec  latency 360.300 ms
  64     11793   158.72 MB/sec  execute  26 sec  latency 286.530 ms
  64     12557   162.84 MB/sec  execute  27 sec  latency 247.856 ms
  64     13123   163.39 MB/sec  execute  28 sec  latency 256.391 ms
  64     13765   165.91 MB/sec  execute  29 sec  latency 278.303 ms
  64  cleanup  30 sec
   0  cleanup  30 sec

 Operation      Count    AvgLat    MaxLat
 ----------------------------------------
 NTCreateX     150681     0.577   213.189
 Close         112136     0.002     8.547
 Rename          6475     3.679   170.335
 Unlink         29123     4.221   236.396
 Qpathinfo     137873     0.182   182.372
 Qfileinfo      25818     0.003    13.626
 Qfsinfo        24911     0.002     4.906
 Sfileinfo      12828     7.851   201.909
 Find           52720     0.058   211.347
 WriteX         82143     3.749   321.845
 ReadX         238881     0.407   234.490
 LockX            504     0.003     0.042
 UnlockX          504     0.001     0.003
 Flush          11026   105.031  1092.733

Throughput 165.912 MB/sec  64 clients  64 procs  max_latency=1092.738 ms
```

圧倒的にEBS。。ただ、FSxは容量大きくするほどスループットが上がる。

![スクリーンショット 2019-12-08 16.22.00.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308709/c0626094-12fb-c822-8e8f-e0340c1a72d6.png)

![スクリーンショット 2019-12-08 16.23.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308709/794ffb24-6542-5d26-5c75-55cb00b65f0d.png)

7.2TBにすると単純に6倍？
なんにせよ、EBSが使えない冗長構成のwordpressだと考えると十分なスペックではなかろうか。

## cloudfront

そんなわけでごっそりとS3にエクスポートしました。
一部の静的ファイルはS3見るようにする。
`uploads` だとか`wp-content`だとかpath毎にbehaiveor設定したいところだけど、今回はざっくりと拡張子で振り分けます。
TTL(default)は適当

| patern| route | TTL | Lambda@Edge |
|:-----------------|:------------------|------------------:|:------------------:|
| /wp-admin*           |  ALB(EC2) |  0 | |
| /wp-login.php           |  ALB(EC2) |  0 | |
| *.png             |  S3 |  3600 |○|
| *.jpg             |  S3 |  3600 |○|
| /wp-content/themes/*            |  ALB(EC2) |  3600 | |
| *.js             |  S3 | 3600 | |
| *.css             |  S3 |  3600 | |
| *.gif             |  S3 |  3600 | |
| *.svg             |  S3 |  3600 | |
| *            |  ALB(EC2) |  0 | |

ALB(EC2)側はwordpress側に任せる。
themesに関してはS3を参照するとなぜかうまくいかなかったのでとりあえずELBをみつつ、キャッシュもする方向にしました。cssかjsだとは思うけど。

## Lambda@Edge

### 事前準備 プラグインのインストール

画像の軽量化のためにwebpフォーマットを使いたい。
そこでewwwってプラグインにて画像ファイルを変換します。

![スクリーンショット 2019-12-08 15.51.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308709/bbdb45d7-f08f-27f4-fe80-a5f186618ec3.png)

インストールしたら、`メディア>一括最適化`ってメニューから画像を全部最適化しておきます。
終わったらまたS3に上げておく。

![スクリーンショット 2019-12-14 23.37.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308709/c01297a2-3297-177e-7258-ac16d1c74c55.png)

cloudFront側のBehaiviorにてAcceptのHeaderを渡すのを忘れずに。

![スクリーンショット 2019-12-15 15.05.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308709/797974ba-767f-1347-9f83-ade172c11dd3.png)

```find /opt/bitnami/apps/wordpress/htdocs -mmin -10 -type f -print0 | xargs -0 -n 1 sudo lfs hsm_archive```

### lambda

こういう事をやります

[CloudFrontにおけるWebPの選択的レスポンス](https://qiita.com/miyanaga/items/e9c7eed19ea16652f04d)

ざっくり言うと、cloudfrontの手前でブラウザを確認してwebp対応してたらwebpのURIに切り替えて対応する。

1. us-northeast-1に`nodejs10`を指定しつつLambda functionを一つ作ります。`cloudfront-modify-response-header `ってblueprint使うと近いかも。(isukudasaiって名前にしました)
2. コードを埋めます。上記の記事のコードでほぼそのままいけます。S3のendpoint変えるくらいかな。
3. なおroleの信頼関係に追記が必要になる(https://docs.aws.amazon.com/ja_jp/AmazonCloudFront/latest/DeveloperGuide/lambda-edge-permissions.html)
4. Lambda@Edgeにデプロイします。`アクション▼`からLambda@Edgeにデプロイを選択し、destributionを選択しbehaviorで*.pngや*.jpgを選択する。bodyはいらない
5. *.jpgも*.pngも両方やります。

![スクリーンショット 2019-12-15 0.02.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308709/8de3460a-62ad-a2e3-d20f-42db476d73f9.png)

これでwebpがあればwebpを参照するはず。

## サイトURLの変更

~~サイトURLはcloudfrontの**xxxxx.cloudfront.net**的なやつに変更しておきます。~~
とおもったけどbitnamiはwp-config.phpでdefineしてた。ホスト名は固定じゃない感じになってました。
なのでcloudfrontのURLで普通にアクセスできるはず。

## ALB

80番ポートで通信するALBを挟んでおきます。
ターゲットグループにはwpのインスタンスで、クラウドフロントのoriginとして登録する。
auto scalingの部分はスルーするけど、インスタンス複数台では試しておきたいので。

ひとまず、起動してるwpからAMIを作って、それも起動しておきます。
そのインスタンスをターゲットグループに追加して2台構成にしましょう。

![スクリーンショット 2019-12-15 13.17.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308709/da4faaf3-f4a3-8f20-e2a0-6f67e37e984e.png)

![スクリーンショット 2019-12-15 14.58.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308709/0eab293d-3fc7-a9b5-94c9-b833fcdad4b3.png)


#完成！

そんなわけで完成！

![スクリーンショット 2019-12-15 16.01.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308709/4b8234c5-41f3-20d6-95c1-384ced6b7b3f.png)


対象の画像ファイルが少なくて効果は微妙ですが、一応webp返ってきてます。
![スクリーンショット 2019-12-15 15.59.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308709/2e6e3b40-6481-f9ce-ecd9-9000a9643ccb.png)


## ベンチマーク的な

Light Houseのスコアは変わりなかったです。コンテンツ自体が変わってないしな。あとhttpsに統一できればたぶん上がる。
pagespeed insightはモバイル99, PC100。まあ、コンテンツが少ないので。

そして、またJMaterで負荷テストします。
ちなみにcloudfrontは秒間1000とかがテストしていいMAXだったはず。
今回は大した負荷かけないのでawsへの申請とか不要なレベルかと思いますが、もっと巨大なインスタンスでがっつりやりたい場合にはawsへ申請しないといけないのでお気をつけくださいませ。

### 3000rec/5min

まずは前回と同様の数値。1分で600セッション、つまり1秒で10セッション。1セッションでおよそ30リクエストぐらい発生してる。多めにみても秒間300リクエストぐらいか。意外とおおい。

前回のEC2インスタンスで全部さばいてる時は、
`Error: 5.03%, スループット: 10.0/sec、　KB/sec: 2303.6`
で、ロードアベレージも10超えてたし限界の数値と思われる。

今回はロードアベレージ的にはこの程度。
![スクリーンショット 2019-12-15 16.29.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308709/f708521f-b17a-af46-d53d-49e22028138a.png)

はっきり言ってまだまださばけますね。いい感じ。
そしてJMater的にはというと・・、
`Error: 0.00%, スループット: 5.6/sec、　KB/sec: 1451.3`

・・・・・・。

・・・・・・。

**え？！**

スループットぜんぜん出てないんですけど。
結局、1800くらいしか捌けませんでした。
EC2はまだ頑張れると思うので、ボトルネックはCloudfrontとS3になるのか？、とおもってalbのdns名でアクセスしてみたらもっと落ちるという結果。

ためしに単一インスタンスにipアドレスでアクセスしてみたら数値は出る。
ただ、ALBにipアドレスでアクセスしてみても数値出ない。。

そんなわけでいろいろ試してみたところ、ALBをすっとばして、cloudfront+Ec2にしたら速くなりました。
ALBがボトルネックだったか。ALBは自動的にスケールアウトするはずだけど、こういうレベルの話ではないんだろうな。もっと大量のクライアントで一斉にアクセスしないとスケールしないのかも。
ALB使うと複数台構成にできるし、大規模サイトでは必要だし、普通はクライアントがたくさんいるから本来であれば使うべきなんだけど、ちょっと今回の検証環境だと良いとこを出して上げられないので、今回は省きますか。

そんなわけで改めて。
clounfrontの背後のec2は一台になりました。

結果、
`Error: 0.00%, スループット: 10.0/sec、　KB/sec: 4450.7`

ちゃんと3000req/5minはクリア。
では倍にしてみますね。

## 6000req/5min

![スクリーンショット 2019-12-15 19.22.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308709/bb0a6895-bde0-afe9-3632-0a7b12ad2a67.png)

`ERROR: 20.72% Throughput: 15.2/sec KB/sec`

3200捌いたあとぐらいからエラーが出始めました。LoadAverageも10前後まで上がってたし、限界超えてたか。

## 4800req/5min

これくらいが閾値かなぁ。
うん、捌けた。

![スクリーンショット 2019-12-15 19.32.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308709/1040143d-963c-ab4f-62c4-68e5e03dc486.png)

しかし、LoadAverage的には限界。

![スクリーンショット 2019-12-15 19.31.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308709/33a8c25f-c326-1651-5d62-912712b7f34d.png)

つまり、t3a.small一台で5分間に4800人がアクセスしてきても耐えられるって感じです。
DBがRDSだったらもうちょい捌けそう。
あと、実際にはブラウザキャッシュとかあるしもっと平気だと思う。
あとはcloudfrontのbehaviorで`Default(*)`にもキャッシュを効かせられればもっと余裕でしょうね。
最後にそれだけやっときますか。

## 9000req/5min かつ、indexをキャッシュ

こうしてしまいます。
![スクリーンショット 2019-12-15 19.37.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308709/7ce9a7c6-5d76-d3df-329e-a332cdbc3dfa.png)

こうなるともうほぼcloudfrontが応答を返してるだけなので超余裕。

![スクリーンショット 2019-12-15 19.58.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/308709/3963231c-54a9-a9e3-5ad3-b6754dde5a53.png)

ちなみに`ab -n 1000 -c 100`をぶっぱなしてみるとこんな感じ。

```
Document Path:          /
Document Length:        144197 bytes

Concurrency Level:      100
Time taken for tests:   70.223 seconds
Complete requests:      1000
Failed requests:        0
Total transferred:      144699090 bytes
HTML transferred:       144197000 bytes
Requests per second:    14.24 [#/sec] (mean)
Time per request:       7022.298 [ms] (mean)
Time per request:       70.223 [ms] (mean, across all concurrent requests)
Transfer rate:          2012.27 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:       80 3065 744.5   3002    6170
Processing:  1320 3802 1363.3   3649    8292
Waiting:        7  926 500.6    843    3465
Total:       3460 6868 1684.8   6441   11406
```

# まとめ

- 冗長化とかいいつつ結局Ec2一台で検証する記事となりました
- wordpressはキャッシュしてなんぼ
- Lambda@Edge、けっこうお手軽
- FSx for luster、札束で殴ると最強
- 結局のところ、モンスターEC2があればそれが最強かもしれない




ワイ「今回のリソースのお片づけ忘れんようにせんとな。」
ワイ「記事書いてる間、じわじわと従量課金されてくし、生きた心地せんかったわ…。」


※ちょくちょく、伏せた方が良さそうな情報乗ってるけどリソース毎消してるのでもーまんたい