Slide 1

Slide 1 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri [スタディサプリ] Railsアプリケーションのモジュールとして存在していた Darklaunch (Feature Toggles) を Goアプリケーションとしてフルスクラッチでマイクロサービス化した話 @tooooooooomy AWS Dev Day 2023 Tokyo @ujihisa

Slide 2

Slide 2 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri 自己紹介 @tooooooooomy 小中高プロダクト基盤開発部 Tech Lead @ujihisa 小中高プロダクト基盤開発部 Senior Product Platform Engineer

Slide 3

Slide 3 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri Agenda | 01 02 03 04 05 Darklaunchとスタディサプリの歴史 WebAPIとして作り直した2つの理由 Go言語でのアプリケーション開発 6週間で初期APIを公開した開発プロセス アプリケーションの性能要件

Slide 4

Slide 4 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri Darklaunchとスタディサプリの歴史 01

Slide 5

Slide 5 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri スタディサプリの開発と、DeployとRelease ● https://studysapuri.jp/ スタディサプリ大学受験講座、中学講座は同じシステム ● https://link.studysapuri.jp/ スタディサプリ for TEACHERSも同じシステム ● リリース用のbranchにmergeすることでdeployするので、QAの関係でreleaseが鈍足化 ● DeployとReleaseを分離する必要がある

Slide 6

Slide 6 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri Feature toggles ● 環境変数やDBの値などに基づき、ソースコード内の単なる条件分岐で、 新機能のリリースを制御する設計パターン ● スタディサプリでは、 Rubyで "Darklaunch" というモジュールで表現 ○ 環境変数ではなくDBの値に基づく ○ 全ユーザに一括公開や、社内などの特定ユーザに限定公開や、団体などの粒度 ○ 権限としては活用しない。あくまで新機能のリリースの単位 ○ バグ修正やパフォーマンス改善など内部的な修正でとくに愛用

Slide 7

Slide 7 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri Darklaunch v1 ● スタディサプリのRuby on Railsの分断されたモノリス (後述)の1モジュール ● リリースする機能の単位に名前をつけたものを keyとよぶ ○ "enable-foo-bar" みたいな文字列で表現 ● データは共用MongoDBのうちの1 collection ● Web backendのRailsアプリから 直接使うことを想定 ● 共有の管理画面に、 Darklaunchのkeyと その公開範囲の設定画面を提供

Slide 8

Slide 8 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri WebAPIとして作り直した2つの理由 02

Slide 9

Slide 9 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri 背景: Darklaunch v1でスコープアウトしていたこと ● Web frontendからの利用 ● モノリス以外のweb backendからの利用 (Ruby, Go, Elixir) ● 複雑な条件 (本トークの範囲外) 最初からすべてのケースを想定して汎用的に設計するのではなく、意図的に小さく始めた 5年ほど運用して、社内でのユースケースがどんどん明確になっていった

Slide 10

Slide 10 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri WebAPIとして作り直した2つの理由 ● web frontendから直接利用可能 ○ 認証についてはいろんなユースケースを考慮した結果認証なしとした ○ このサービスは個人情報を一切所持しない ● 共有dbのデータを消し、データは Darklaunchサービス内で完結 ○ 全社的な課題として、肥大化しつづける MongoDBからの独立性の高いデータの分離が あった ○ ここは独立してAmazon Aurora Serverless

Slide 11

Slide 11 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri Go言語でのアプリケーション開発 03

Slide 12

Slide 12 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri なぜGoなのか ➔ スタディサプリ開発組織として、マイクロサービス化を進めていきたい ➔ 長期的なメンテナンス性を考慮して 安全な(でもやりすぎない)言語を選びたい

Slide 13

Slide 13 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri マイクローサービス化を進めたい ➔ スタディサプリ5年前からの悲願(もっと前かも) ◆ Quipper における「関心の分離」の歴史 by @kyanny ➔ モノリスに依存しない独立したサービスを作る ◆ Ruby以外の言語で作ることで将来的な独立性を担保したい

Slide 14

Slide 14 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri なぜGoなのか ➔ スタディサプリ開発組織として、マイクロサービス化を進めていきたい ➔ 長期的なメンテナンス性を考慮して 安全な(でもやりすぎない)言語を選びたい

Slide 15

Slide 15 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri 長期的なメンテナンス性を担保したい ➔ せっかくなのでRubyにはない性質(型安全)の言語にしたい ➔ コンパイルが大変でそれに気を取られすぎる言語は避けたい ➔ 社内に確かなユーザーコミュニティがある

Slide 16

Slide 16 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri Rails使いがGoの開発をする上で開発速度向上に貢献したもの ➔ Composite Design Patternでの実装経験 ◆ データモデルとロジックを別々に管理することを意識できる ➔ Table Driven Testingのお勉強 ◆ rspecに慣れきった脳にテストの書き方の指針を教えてくれる ➔ Sqlboilerなどのコードジェネレーター各種 ◆ ドメインロジックに集中できるのはやはり重要

Slide 17

Slide 17 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri 6週間で初期APIを公開した開発プロセス 04

Slide 18

Slide 18 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri 6週間でやったこと ➔ 機能開発 ➔ システム設計レビュー ➔ 負荷試験 ➔ モニタリング設計 ➔ 本番デプロイ

Slide 19

Slide 19 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri 6週間でやったこと ➔ 機能開発 ➔ システム設計レビュー ➔ 負荷試験 ➔ モニタリング設計 ➔ 本番デプロイ やるべきことに集中する必要がある

Slide 20

Slide 20 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri 6週間で初期APIを公開をするには ➔ 開発を行っている期間中、迷いが生じたら間に合わない ◆ 対象外の開発プロセス改善は済んでいる前提で以下を明確にする ● 何故やるのか ● 何を作るのか ● どこまでやるのか

Slide 21

Slide 21 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri 6週間で初期APIを公開をするには ➔ 開発を行っている期間中、迷いが生じたら間に合わない ◆ 対象外の開発プロセス改善は済んでいる前提で以下を明確にする ● 何故やるのか ● 何を作るのか ● どこまでやるのか

Slide 22

Slide 22 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri スタディサプリインフラ基盤の簡単なご紹介 ➔ Amazon EKS + argoCD + GitHub Actions によるデプロイ ◆ サービス用のyamlファイル一式を用意するだけで環境構築可能 ➔ Terraform によるリソース管理・デプロイ ◆ 主要リソースはほぼ全てIaC化が済んでいる

Slide 23

Slide 23 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri スタディサプリインフラ基盤の簡単なご紹介 ➔ Amazon EKS + argoCD + GitHub Actions によるデプロイ ◆ サービス用のyamlファイル一式を用意するだけで環境構築可能 ➔ Terraform によるリソース管理・デプロイ ◆ 主要リソースはほぼ全てIaC化が済んでいる めっちゃ便利 (SREチームありがとう)

Slide 24

Slide 24 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri 開発速度を出すには ➔ What, Why, Howの合意を取ってスタートする ◆ 検証・フィードバックのサイクルを予め回しておく ● 開発者が自信を持って開発できる ● 開発を始めるときには、もっともコアな部分のデザインはできている

Slide 25

Slide 25 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri 開発速度を出すには ➔ What, Why, Howの合意を取ってスタートする ◆ 検証・フィードバックのサイクルを予め回しておく ● 開発者が自信を持って開発できる ● 開発を始めるときには、もっともコアな部分のデザインはできている プロトタイプ開発

Slide 26

Slide 26 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri プロトタイプ開発 ➔ 自分たちが作ろうとしているものがユーザーに必要とされているかを知る

Slide 27

Slide 27 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri プロトタイプ開発 ➔ 自分たちが作ろうとしているものがユーザーに必要とされているかを知る ◆ とりあえず「動くもの」を作ってユーザーに使ってもらえる

Slide 28

Slide 28 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri プロトタイプ開発 ➔ 自分たちが作ろうとしているものがユーザーに必要とされているかを知る ◆ とりあえず「動くもの」を作ってユーザーに使ってもらえる ◆ ユーザーにフィードバックをもらえる

Slide 29

Slide 29 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri プロトタイプ開発 ➔ 自分たちが作ろうとしているものがユーザーに必要とされているかを知る ◆ とりあえず「動くもの」を作ってユーザーに使ってもらえる ◆ ユーザーにフィードバックをもらえる ◆ 仮説が間違っていたり、検証が済んだら捨てる

Slide 30

Slide 30 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri プロトタイプ開発を通して得た知見例 ➔ Darklaunchのデータ構造は意外と複雑で、RDBを使ったほうがよい ➔ 想定していなかった便利ケースが見つかった ◆ 「特定日時になったら以後常に有効」機能が欲しい ◆ 一方「特定日時になったら特定の値に変更」だと過剰 ➔ 必要な属性情報を裏付けとともに確定できた ◆ オーナー情報はkeyの属性として絶対必要

Slide 31

Slide 31 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri プロトタイプ開発を通して得た知見例 ➔ Darklaunchのデータ構造は意外と複雑で、RDBを使ったほうがよい ➔ 想定していなかった便利ケースが見つかった ◆ 「特定日時になったら以後常に有効」機能が欲しい ◆ 一方「特定日時になったら特定の値に変更」だと過剰 ➔ 必要な属性情報を裏付けとともに確定できた ◆ オーナー情報はkeyの属性として絶対必要 準備を万端にすることが大切

Slide 32

Slide 32 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri アプリケーションの性能要件 05

Slide 33

Slide 33 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri アーキテクチャ図

Slide 34

Slide 34 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri アーキテクチャ図

Slide 35

Slide 35 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri アーキテクチャ図 ● darklaunch-v2-api ○ 世界からのリクエストを常時 受け付ける ● darklaunch-v2-backend-api ○ 管理者によるkeyの登録情 報変更のリクエストをたまに 受け付ける darklaunch-v2-api の 性能検証が重要

Slide 36

Slide 36 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri 一般的なRead Heavyなアプリケーションのイメージ ➔ databaseとともにcacheも使う ◆ 本当に必要なのか?

Slide 37

Slide 37 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri 一般的なRead Heavyなアプリケーションのイメージ ➔ databaseとともにcacheも使う ◆ 本当に必要なのか? 性能要件 + 検証結果次第

Slide 38

Slide 38 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri アプリケーションの性能要件の決め方 ➔ darklaunch-v1モジュールの計測結果を元に試算 ◆ 289 req/sec (Rubyアプリケーションからのアクセスのみ) ➔ 今後Webフロントエンドからも使われることを考えると、多めに見積もっておく に越したことはない ◆ 10,000 req/sec(約30倍) をベースラインとする

Slide 39

Slide 39 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri 負荷試験 ➔ Gatling を使った負荷試験を実施 ◆ EKS基盤をフル活用 ◆ https://gatling.io/docs/gatling

Slide 40

Slide 40 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri Amazon Aurora Serverless v2 ➔ コスト削減のため部内で導入の機運があった ➔ darklaunch-v2 で扱うRDSとして、実験的に採用して負荷試験を行った ➔ 急激なreadの負荷の上昇に耐えられるのか? ◆ 結果としてはv2なら全然余裕 ◆ (但し0% -> 100% ではなく、 10% -> 100% みたいな変化であれば)

Slide 41

Slide 41 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri Gatling Setup例 1. idle状態(1,000rps/sec)で60秒間 2. その後peak(10,000rps/sec)まで 120秒かけて増やしていく 3. その状態でさらに 120秒間リクエストを続ける ● 10% -> 100% の負荷を表現

Slide 42

Slide 42 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri 負荷試験結果① ➔ Gatling 結果 ◆ 全てのリクエストが成功 ◆ 99 percentileが目標値 (0.5sec)以下

Slide 43

Slide 43 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri 負荷試験結果② ➔ アーキテクチャ ◆ 追加キャッシュ層なしのシンプルな構成で問題なし Good for now!

Slide 44

Slide 44 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri 負荷試験結果③ ➔ Kubernetes Resource requests ◆ Replicas: Min 5 pods, Max 50 pods ◆ cpu: 250m ◆ memory: 256 Mi ➔ Amazon Aurora Serverless ◆ ACU capacity 0.5 ~ 20

Slide 45

Slide 45 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri まとめ ➔ Darklaunch(FeatureToggles)コンポーネントの社内公開API化 ◆ 数年の運用で見えた課題の解決 ➔ Web APIとして作った2つの理由: ◆ web frontendから直接利用可能 ◆ 共有dbのデータを消し、データは Darklaunchサービス内で完結 (独立してAmazon Aurora Serverless) ➔ Goの開発 ◆ なぜGoを選んだか ◆ Rails使いがGoの開発する上で開発速度向上に貢献したもの ➔ 6週間で初期APIを公開した開発プロセス ◆ プロトタイプ開発 ➔ アプリケーションの性能要件 ◆ 性能要件の決め方 ◆ 負荷試験

Slide 46

Slide 46 text

#awsdevday [スタディサプリ]Railsアプリケーションのモジュールとして存在していた Darklaunch(FeatureToggles)をGoアプリケーションとしてフルスクラッチでマイクロサービス化した話 #studysapuri ご清聴ありがとうございました