Nakagawaエンジニアはじめまして。株式会社トルテでサーバーサイドを担当している中川です。レディーファーストの恋アプリTorteを開発しています。https://sweet-torte.com/今年8月にリリースしたTorteのサーバーサイドのアーキテクチャについて、技術選定の理由やTipsと共にご紹介いたします。Docker以前担当していたサービスで急激な高負荷に耐えられないことが多々あり、EC2を使ったスケールに限界を感じていました。Containerを使ったオートスケールやデプロイに関心があり、今回はDockerと、シングルバイナリで稼働して相性が良いGo言語を採用する運びとなりました。Goという流れがあったので、採用にあたって特に障壁はありませんでした。ServiceクラウドはGCPとAWSを検討しました。Containerサービスが利用できます。結果的には、AWSを採用しました。個人的にはGCPを使ってみたかったのですが、AuroraやS3、ElastiCache、Kinesis、LambdaといったAWSのマネージドサービスを活用しているプロダクトが周りに多く、知見が活かせるということで、開発スピードを重視した結果となりました。次の図は、ざっくりした全体の俯瞰図になります。基本的にAWSのサービスを利用していますが、一部外部のサービスを利用しています。認証、プッシュ通知、リアルタイムDBにFirebase、モニタリングにDatadogを採用しています。53だけはRoadworkerで管理しています。fileを持たず、常に現状との差分を取るのでDNSレコードを管理する上では使いやすいという理由があります。Files静的ファイルはGit管理の上で、S3に同期されています。Proxy)を挟むことで縮小、形式の変換、切り抜きの処理とキャッシュを行っています。(Redis)を採用しています。マッチングサービスに欠かせない、ユーザー検索のロジックの実現にはElasticsearchを用いています。詳しくは以下の資料を参照してください。Serviceそれぞれにオートスケールを設定し、負荷に応じてServiceがスケール(Taskが増減)、残リソースに応じてClusterがスケール(Instanceが増減)します。Clusterのオートスケールの設定についてですが、CPUReservationとMemoryReservationというECSにのみ存在するメトリクスを使うことで、1つのClusterに複数Serviceが相乗りする場合でもシンプルかつ柔軟にスケールさせることが出来ます。ECSの部分を詳細に見ていきます。Clusterが存在します。Roleで権限を分けることができるので、1つのClusterに複数Serviceを混在させることが可能です。Batchの3つのシステムが稼働しています。Serviceになります。Serviceとして登録されオートスケールが設定されています。サービスディスカバリにはALBが使われ、実際にServiceを構成するTaskがClusterを構成するどのInstanceにデプロイされても問題ない仕組みになっています。APIサービスの根幹となる、ネイティブアプリからアクセスされるAPIです。Goで実装されています。go-bindata(github.com/jteeuwen/go-bindata)を使うことでassetを含めてシングルバイナリになっています。Imageにはalpineを採用しました。Goでの実装に関するTipsについては以下の資料を参照してください。Admin管理画面です。(https://github.com/marmelab/admin-on-rest)を採用しています。AdminのAPIは、基盤システムからのリクエストの受け口としても機能しています。Taskが起動します。Eventsがトリガーとなっています。ServiceデプロイApplicationアプリケーションのデプロイについてです。(https://github.com/silinternational/ecs-deploy)を使う方法を採用し、ユースケースに合わせてecs-deployに手を加えています。tagを切るとprd環境に、CircleCI経由でECSに対してローリングアップデートが実行されます。Websiteコーポレートサイト、サービスの公式サイトの管理も自動化しています。アプリケーション同様、masterにマージするだけで確認環境(stg)が更新されるので、手軽で確認しやすいとデザイナーの方に喜ばれています。Log紆余曲折あったログ周りの構成です。深掘りするとログ周りの話だけで1つ記事が書けそうなボリュームがあるので、今回は割愛します。Logsを使う予定でいました。driverにawslogsを指定することで、標準出力、標準エラー出力に吐き出すだけで導入できて大変便利なのですが、ログが欠損しない事といった信頼性の面に於いて懸念があり、アプリケーションから直接Kinesisに投げてバッファリングする形に落ち着きました。Torteでは4つの種類のログを扱っています。Serviceに転送し、Kibanaで可視化しています。後者2つについては基盤システムに送る必要があり、Lambdaからfluent-logger-pythonを使って転送しています。さいごに新規サービスTorteのアーキテクチャについてご紹介いたしました。携わる貴重な経験でした。技術は日々進歩していくので、エンジニアとして常に情報をキャッチアップし、時には新しい技術に挑戦することで、ユースケースに合ったコストパフォーマンスの良い手段を選択していかなければならないと思います。トルテはIT技術で、幸せな出会いをサポートしていきます。Nakagawa2016年度新卒入社のサーバーサイドエンジニアです。GoとJavaScriptを喋ります。趣味は旅行とアニメとお菓子作り。