はじめに
はじめまして、otofune と申します。
9/6 から 9/24 の3週間、株式会社アカツキでプラットフォームエンジニアリングを行うチームでのインターンシップに参加させて頂きました。
といっても祝日が2日あり、新型コロナワクチンの摂取が被って副反応で1日休み、さらに社内イベントもあり、実質2週間でした。
その中で、私は GAE/Go 上で動作するサービスについて、運用に関わる以下の成果を出すことができました。
- API レスポンスのリファクタリング
- 蓄積されたアクセスログを解析し利用状況を可視化
この記事では関わったサービスについて軽く説明したあと、行った改善について紹介し、終わりに全体を通した感想を書きます。
もくじ
- はじめに
- もくじ
- インターンに参加する動機と方針
- ゲーム内仮想通貨管理サービス
- 1. API レスポンスのリファクタリング
- 2. 蓄積されたアクセスログを解析し利用状況を可視化
- インターンに参加して
- 終わりに
インターンに参加する動機と方針
メンターだった id:takanakahiko と以前からの知り合いで会社の良いところを聞いたことがきっかけに、会社の雰囲気を体験したくなり応募していました。
そのため顔合わせの 1on1 で「レールを敷いてもらうか、自分でやること決めるかだったらどっちがいい?」と聞かれた際に、メンバーにより近い後者にすることを決め、なるべく自発的に動くようにしていました。
ゲーム内仮想通貨管理サービス
モバイルゲーム開発では決済・石*1管理機能がタイトルに関わらず必要となります。実装するには法的要件を理解し、チート対策やプラットフォームの API 変更についていかなければならないなど大変であるにも関わらず、ゲームの楽しさにはあまり影響しません。
このゲーム開発者からしてみると“面倒くさい”と感じる機能を代わりに提供し、集中してゲーム開発を行えるようにするサービスが「ゲーム内仮想通貨管理サービス」です。
1. API レスポンスのリファクタリング
オンボーディングの一環としてリファクタリングを行いました。緊急ではないが影響範囲の広い変更を行うことでコードベースに慣れるためです。
具体的には7月にインターンしていた id:task4233 さんが作ったキーローテーション API と重複する機能を削除しました。鍵のデータを個別に返せる API が追加されており、これまで関連リソースのレスポンスに同時に含めていた鍵を削除するという内容でした。
レイヤードアーキテクチャでわかりやすく、API の実装を見つけ削除するまでは簡単でした。しかしテストコードに大きく修正が必要で、かつエラーが見つけにくく難航しました。*2
といっても粛々と原因特定を進め、3日ほどでマージまで持っていくことができました。
2. 蓄積されたアクセスログを解析し利用状況を可視化
このサービスはゲームサーバーから使われる関係上、レスポンス速度は速ければ速いほどよく、待たせることはゲームユーザーにとって明確なマイナスになります。
このため利用者であるゲームサーバーの中には、レスポンス速度を問題にしてキャッシュを持っているものもあります。
そういうこともあり遅いらしいことは肌感としてありつつ、現状を把握できておらず実際に問題が存在するのか知る必要がありました。
初日の躓き
先ほどは問題が存在するか知ることを目的と書きましたが、当初は「パフォーマンスに課題感がある、蓄積されているトレースをうまく活用できないか」程度にしかまとまっていませんでした。そこで初日はヒアリングをした後、パフォーマンスを高めることを目的としてトレースの活用法を調べていました。
ただ調べていても納得感がなく、これでいいのか自信が持てませんでした。
知識不足が原因で正しい判断ができていないのではないかと考え、『入門 監視』を読むことを許してもらい、一日インプットに充てることとしました。
『入門 監視』を読んで
この本は具体的なツールには言及しないことで厚くならないようにしながら、原則や考え方を示してくれます。そのときの自分に適した内容でした。
"監視は、質問を投げかけるためにある" (P28)
"「銀の弾丸はない」この本からこれだけは覚えていてください"(P4)
"計測する必要がありそうな箇所はたくさんありますが … まず監視を追加すべきなのは、ユーザーがあなたのアプリケーションとやり取りをするところです。… アプリケーションの詳細をユーザーは気にしません。" (P29)
これを踏まえて「実際にどう使われていてなにが遅いのか見ることができるようにしてからチューニングしたほうがよい」と目的を考え直すことができました。
方法についても「全体を通してのトレースをまとめる」という方法ではユーザーにとっての問題を知ることができるかは怪しいだろう*3と判断し、ユーザーにとって重要な API を特定しそれに絞ってトレースを見る必要があるのではと考え直しました。
現状のモニタリングダッシュボードでは全体を通したアクセス回数、エラーレートやレイテンシしかわからなかったため、まずはアクセスログを用いて API 毎にそういった指標を取れるようにして実際にどの API が使われていて遅いのか気付けるようにすることを目標にしました。
できたもの
将来のため、加工しやすいフォーマットで統計を出力するシンプルな CLI を作りました。BigQuery に sink された App Engine のログをルート定義ごとにうまく纏め、アクセスカウント、エラーレートやレイテンシ (%tile) を吐くだけの機能を持った CLI です。
この実装は https://github.com/aktsk/aealanlys で公開しています。
難所
方針が決まってからは、ほとんどパスをルート定義ごとにうまく纏める方法だけが問題でした。
ログの量が少なければローカルで処理してもよかったのですが、本番環境では 20GB を越えていて、なんとかして BigQuery に処理させる必要がありました。
ゲーム内仮想通貨管理サービスは RESTful API になっていて、すなわちパス内にパラメータを持つことがあります。これをまとめるには複雑なマッチングを行わなければいけません。
ただ、BigQuery はコンピューティングが無料なのでいくらめちゃくちゃな処理をしても制約にひっかからない限りは料金に違いはありません。これに注目し RegExp を処理できることを考えたところ「フレームワークのパスマッチに使われる RegExp を転送して文字列置換すればよいのでは?」という発想が思いつき、うまく実装することができました。
よかったこと
まず、感覚に依らず問題が存在するのかをわかるようにすると軌道修正でき、そのためのツールを実装することができたこと。そして実際にアクセスログを解析してみたらそこまで悪くない*4という結果が出たこと。目的を意識して軌道修正を行なったことがよい結果を導いてくれました。
また、自らタスクを決めて遂行できたこと、補助は受けつつ自走して調査を行い方法の提案ができたこと、チームへ逐次進捗を共有し議論しながら進められたこともよかったと感じています。
インターンに参加して
運用改善という、個人では課題になりにくくアルバイトやインターンでは触れにくい領域に触ることができ、非常によい経験になりました。
決済基盤チームでは毎日昼に進捗を共有する会議があり、時間が余れば雑談をする習慣がありました。リモート下で孤独を感じずに要られたこと、受け入れられていることを実感できたのはこのためです。
また、社員の方を指名して話せる機会があったり、丁度 Akatsuki Dev Meetup という社内技術イベントがあったりと、会社の雰囲気であったりオープンな文化を感じることもできました。短期間しかいないインターンという立場からイベントがあるのはどうなんだろう? とすこし思っていましたが、幅広い業務があることや多種多様なバックグラウンドを感じることができ、このタイミングでよかったと今では思っています。
終わりに
総じて楽しく、学びを得ることもできたインターンでした。関わって頂いた皆様には大変お世話になりました。短い間ではありましたが、本当にありがとうございました。
*1:ゲーム内通貨のこと
*2:例えば t.Error が多用されており panic する、$register に入れ子アクセスする際に変換できなかったときのエラーをわかりやすくしたい · Issue #28 · aktsk/atgen · GitHub など
*3:あまり Span を生成しておらずライブラリ、特に google-cloud-go による情報がほぼであったことなどによる
*4:よく使われている API のレイテンシが想像していたより遅くなかった