Railsのassetsファイルなどの静的ファイルをサーバで配信した場合の負荷を検証してみます。
私はassetsファイルなどの静的ファイルをサーバで配信することが多いのですが、本当はS3において、さらにCloudFrontなどのCDNでキャッシュした方が良いよなと思っていました。
が、、ちょっと面倒で後回しになっていたので、実際にサーバ負荷を確認して、静的ファイルをS3に移動させる労力に見合う結果が得られそうか確認したいと思います。
今回の検証では、サーバはECS Fargateで、1vCPU/2GBを使います。
ECS Fargateは以下の記事のようにたてられます。

assets/images配下に、100KBの画像を格納して、その画像ファイルにjmeterで大量アクセスした際の負荷を検証してみます。
準備
以下のようにFargateコンテナを立ち上げます。

assets/images配下に100KBの画像を格納します。
以下のコマンドでビルドします。
docker build -t rails-demo .以下のコマンドでコンテナ起動します。
docker run -d -p 3000:3000 \
-e RAILS_MASTER_KEY=$(cat config/master.key) \
--name my-app \
rails-demo100KBの画像のパスを取得するため、コンテナにbashで入ります
<コンテナID確認>
docker ps -a
<コンテナにbashではいる>
docker exec -it {コンテナID} /bin/bash以下のコマンドでパスを取得できます。
bundle exec rails c
helper.asset_url("100KB.png")jmeter準備
macの場合以下のコマンドでインストールできます
brew install jmeterインストールしたら
jmeterとターミナルに打ち込むとjmeterが起動します。
jmeter設定
以下の設定で1分間かけて50スレッド立ち上がるようにします。そのあとは4分間継続して負荷を描けます
Thread Group
Number of Threads:50
Ramp-up:60
Duration:300
以下の設定で3000アクセスに設定します。1分で3000アクセスなので、秒間50アクセスです。
Constant Throughput Timer
Target throughput:3000以下の設定で画像にアクセスするようにします。
HTTP Request
protocol:https
Server Name or ip:ECSのドメイン
Path:{helper.asset_url("100KB.png")の結果}確認結果
秒間50アクセスを5分間継続したところ、CPU使用率は14%程度になりました。

サーバはECS Fargateで、1vCPU/2GBです。
14%とそれほど高いとも言えず、何とも言えない結果ですが、利用者数が増えるほど無視できない負荷になることも考えられると思います。
そのため、以下のような対応が必要と思われます…!
- CloudFrontなどのCDNでのキャッシュ
- そもそもassetsファイルはS3などにおき、サーバにリクエストが来ないようにする
- S3に置いたうえで、CDNでキャッシュもした方が良さそう

