ECS Fargate上で動作するSpringBootとGinのスループット比較

# はじめに
Golangってめちゃくちゃ高速だし最高！という話があるものの、Webフレームワークを扱うにあたっては、まだまだ情報も事例も少ないという状況で、実際に高速とは言え実運用に持ち込むにはリスクがあるかもしれない。
一方で、SpringBootはWebフレームワークとしては充分に実績があるので、速度差次第では充分に採用するメリットはある。

というわけで、今回は「実際にどれくらい速度違うの？」というのを確かめてみた。

条件としては

- DynamoDBから1アイテムをGetItemするトラフィックをかける
- DynamoDBへのアクセスはVPCエンドポイント経由
- FargateのCPU割り当てを256ユニット→512ユニットで垂直スケールするかを確認する(水平スケールは充分に実績がある前提として確認しない)
- GolangのWebフレームワークはGinを使用
- GolangのSDKはv2を使用(プレビューだが、v1は全然スループットが出なかった)

といったところか。

なお、測定ツールにはlocustを用いていて、画面キャプチャを使っているので、各項目の目盛りのスケールがあっていないのはご了承いただきたい……。

# Golang編
## 256CPUユニット
10ユーザ単位で増加させた。
スループットは最大で250rps程度。
それを超えると、CPUが高騰してスループットが激減する。300rpsは安定しなそう。

![golang_cpu256_number_of_users_1602387969.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111314/1604829e-e105-43ee-4b90-2cff72758763.png)
![golang_cpu256_total_requests_per_second_1602387969.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111314/b1f7a250-ab80-5d68-a637-45addd8be986.png)
![golang_cpu256_response_times_(ms)_1602387969.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111314/5279da55-3228-72a1-67c4-10fe4dad8233.png)

上記の時間帯のCloudWatchメトリクスのCPU Utilizationは以下。
![golang_cpu256_ecs_cpu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111314/59b73085-36da-a576-3d6e-d0614b60373c.png)


## 512CPUユニット
20ユーザ単位で増加させた。
スループットは最大で440rps程度。
それを超えると、CPUが高騰してスループットが激減する。

CPUユニット数を倍にしているのにスループットが倍にならず垂直スケールしないのが謎。
AWS Go SDK v1でもv2でこの傾向は同じだが、v2の方がCPUユニットあたりのスループットは出る。

![golang_cpu512_number_of_users_1602386315.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111314/0fe9890f-a85e-1255-b1c4-b528593e57ee.png)
![golang_cpu512_total_requests_per_second_1602386315.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111314/25c4048a-bfd5-0ebb-cb06-d2c124a0b138.png)
![golang_cpu512_response_times_(ms)_1602386315.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111314/d2dc349c-ff87-7f99-796d-03f860be2bd6.png)

上記の時間帯のCloudWatchメトリクスのCPU Utilizationは以下。

![golang_cpu512_ecs_cpu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111314/f4bccf57-c1a4-83b0-7962-adef8654d430.png)

# Java編
## 256CPUユニット
JavaはJavaでなかなか安定しないグラフになる。
20ユーザ単位で増加させた。
スループットは最大で450rps程度出ているが、このタイミングでは95%タイルや中央値が悪化しているので、安定を目指すなら380rps程度出ているポイントを目指すべきだろう。


![java_cpu256_number_of_users_1602389530.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111314/87faa6d8-a4d7-b4d6-d60a-588051c12223.png)
![java_cpu256_total_requests_per_second_1602389530.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111314/4f6cb356-7d3d-e8dc-4d9a-7f2062428b1f.png)
![java_cpu256_response_times_(ms)_1602389530.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111314/e14460ea-b0ec-f73f-2823-1701c0950843.png)

上記の時間帯のCloudWatchメトリクスのCPU Utilizationは以下。
380rpsのポイントでもCPUは80%以上使えているので、まずまず充分に使えている。

![java_cpu256_ecs_cpu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111314/6b5fd767-e1c1-f34b-380f-3e8a3425b9b1.png)


## 512CPUユニット
やっぱりこちらも安定しない。
80rpsをスタートにして、20ユーザ単位で増加させた。
Ginと違い、こちらは垂直にスケールしている。だいたい850rpsを超えると95%タイルが悪化しているので、このあたりのポイントが良いだろう。この時点でのCPU使用率は80%以上なので、こちらも充分に使いきれてると言える。

![java_cpu512_number_of_users_1602393927.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111314/f5aa5d0f-cc8c-e2ab-63a2-7009e18cdcee.png)
![java_cpu512_total_requests_per_second_1602393927.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111314/4e84eef2-7b03-1a14-1f87-569e2a8db7c5.png)
![java_cpu512_response_times_(ms)_1602393927.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111314/187affbb-3d97-1160-349b-4e5c4d235401.png)

上記の時間帯のCloudWatchメトリクスのCPU Utilizationは以下。

![java_cpu512_ecs_cpu.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/111314/f93a8c20-418c-c66a-5ae0-99eac8b1e00d.png)

# 結論
Ginの方がトラフィックが安定するものの、垂直スケールしない点が気になる。
SpringBootについては、スレッド数やGC頻度を調整すればもう少し安定しそう。
もうちょっと実績が出てドキュメントが増えればGinは全然アリだが、現時点では何かがあっても調べようがないのが厳しいところだ。