Akatsuki Summer Internship 2021のGo/GCPコースに参加した

2021年8月10日から27日まで、Akatsuki Summer Internship 2021のGo/GCPコースに参加していました。

Akatsukiを選んだ理由

Akatsuki Summer InternshipのGo/GCPコースは、ATLASというチームに参加する就業型インターンシップです。ATLASは、大規模ゲームプロダクトを支える共通基盤の開発などをしているチームです。この共通基盤は、ゲーム内通貨、いわゆる「石」の管理を行うシステムで、ゲームサーバーに対し課金処理サービスを提供するものになります。

そんなGo/GCPコースですが、私がこのコースを選んだ理由は3つあります。

  1. 得意なGoが書ける
  2. クラウドにさわれる
  3. 実際に動いているシステムにさわれる

私はこのインターンシップで2つのタスクに取り組みました。

タスク1:IPアドレスによる認証の追加

課金処理を行うためにゲームサーバーと共通基盤がやりとりするわけですが、現状はトークンだけでゲームサーバーを認証しています。よって、うっかりトークンが漏れてしまった場合、共通基盤を不正操作される可能性があります。定期的な監査により不正検知が行われますが、そもそも不正ができないようにすべきです。こうした背景から、私は追加のセキュリティとしてIPアドレスによる認証を実装するタスクに取り組みました。
具体的に取り組んだこととしては、

  1. IPアドレス範囲を設定するエンドポイントの実装
  2. IPアドレス範囲を保存するビジネスロジックの実装
  3. 接続元IPアドレスが範囲内にあるか確認する認証ミドルウェアの実装
  4. 上3つに対するユニットテスト&E2Eテスト

が挙げられます。

タスク2:新バージョンのデプロイ自動化

共通基盤のデプロイでは、カナリアリリースという手法を採用しています。カナリアリリースでは、新バージョンをデプロイするときに、一気に置き換えるのではなく、一部ユーザーだけに新バージョンを使わせます。その後、エラーや異常事態が発生していないことを確認しながら、徐々に新バージョンを使わせるユーザー数を増やしていきます。これにより、新バージョンにバグがあった場合でも、影響が一部のユーザーに留まります。

一見良さそうな共通基盤のカナリアリリースですが、現状は人間がエラーログや各種の指標を見ながらユーザー数を操作しています。人間による監視ではエラーを見逃してしまう可能性もあるため、監視も自動化したいという要望がありました。そこで、私が自動監視ツールの製作に着手することになりました。
ツールが監視しなければならない指標は以下の6つです。

  • 新バージョンが返したエラーレスポンスの個数 (リリース開始から現在までの総数を集計)
  • 新バージョンが返したレスポンスのうち、特定のエンドポイントが呼び出されたものの個数 (リリース開始から現在までの総数を集計)
  • リクエスト速度 req/s (1分間ごとに集計)
  • 新バージョンが返したエラーレスポンスの個数 ÷ 新バージョンが返したレスポンスの個数 (1分間ごとに集計)
  • 新バージョンのレスポンスレイテンシの95パーセンタイル ÷ 旧バージョンのレスポンスレイテンシの95パーセンタイル (5分間ごとに集計)
  • 新バージョンを動かしているインスタンス数 ÷ 旧バージョンを動かしているインスタンス数 (1分間ごとに集計)

様々なドキュメントを読んだ結果、上2つはBigQueryを用いて監視し、下4つはCloud Monitoringを用いて監視することに決定しました。
共通基盤はApp Engineで動いているため、レスポンスログはCloud Loggingに送信されます。その後、Cloud Loggingに設定されたログルーターによって、ログがBigQueryにもコピーされます。よって、BigQueryに対して特定の条件を満たすレコード数を調べるSELECT文を発行するだけで、各種レスポンス数の集計が可能です。
一方、一定時間ごとに集計すべきものは、Cloud Monitoringを用いた方が簡便に集計できます。なぜならば、Monitoring Query Languageを使用することで、一定時間内のデータだけを取り出したりパーセンタイルや比率の計算したりすることを一度に行うことができるからです。

学べたこと

クリーンアーキテクチャを体験できた

共通基盤はクリーンアーキテクチャを採用していて、エンドポイントの実装とビジネスロジックが分離されています。これにより、ソースコードの見通しが良くなっています。個人開発やISUCONでは、こうした分離は後回しにしたりやらなかったりしがちなので、大きな学びになりました。

E2Eテストを初めて書いた

E2Eテストを書くということを初めてやりました。テストシナリオを書いたyamlファイルからGoコードを生成してくれるツールが用意してあって、とても簡単にテストを書くことができました。

Google Cloud Platformに詳しくなった

特にタスク2に取り組む中で、大量のGCPドキュメントを読むことになり、App Engine、BigQuery、Cloud Logging、Cloud Monitoringの概念を習得することができました。

ミスを防ぐ仕組みやミスの影響を最小限に留める仕組みを体験できた

ATLASには、コードレビュー、CIによるlintやtest、カナリアリリースなどを組み合わせることによって、ミスを防いだりミスの影響を最小限に留める仕組みが用意されています。こうした仕組みにさわれるのは就業型インターンシップならではの体験だと思いました。

大変だったこと

Google Cloud Platformを用いる部分のユニットテスト

GCPを用いる部分のユニットテストのやり方は2通りあります。

  1. モックを用いる
  2. GCPの応答を模倣するフェイクサーバーを書く

Google自身がモックを推奨していないこともあり、フェイクサーバーを書くことにしました。これが結構大変で、ドキュメントの深い部分まで読んだり実際にリクエストを投げたりしながらフェイクサーバーを作りました。

最後に

学びの多いインターンシップになりました。ありがとうございました!