見出し画像

【新卒 Engineers' Blog】#1 メンテナンスって何やってるの?

はじめに

初めまして!
去年の4月に新卒としてグリーに入社し、現在ポケラボの運用タイトルにてサーバーエンジニアをしている23卒の清水です!
2年目に突入し新卒では無くなってしまった&最近大腸検査を受けたりと、かなりナーバスですが、新卒の一年を振り返る+技術的なブログを書いてみようというお話をいただいたので、最後に新卒らしいフレッシュさ溢れるブログを書きたいと思います!

入社当初を振り返る

入社当初はサーバーエンジニアに求められるような、基礎的なサーバーの知識やプログラミング言語経験、DBやクラウドの知識はほぼ0でした。
大学の授業で少し学びましたが、主に研究のためにunityばかり触っていたので、どちらかというとクライアント側の知識の方がある状態でした笑
しかし、将来クライアントとサーバーどちらもできるエンジニアになりたい、またどのようにしてスマホゲームが動いているのかを知るにはサーバーから学んだ方が良いのではと思い、まずはサーバーエンジニアとしてキャリアを歩むことを決めました。
どちらのエンジニアになるかの選択を自由にさせていただいたこと、未経験の自分を温かく迎え入れていただいたこと、圧倒的感謝しかありません。

この一年やってきたサーバーエンジニアの仕事

サーバーエンジニアとしてこの一年の仕事を振り返ると
・新機能開発
・運用保守業務
・サーバー負荷監視と台数調整
・お客様対応
・データ分析
・メンテナンス業務
色々業務はあるものの、基本は新機能開発しながら、その他の業務をやや定期的にこなしていく感じでした。
これらの中でもっとも定期的に行っていたのがメンテナンス業務でした。
メンテナンス業務って何してるの?そもそもメンテナンスってなんなの?
そんな疑問を解決すべく、ブログのタイトルにもある通り、ここからはメンテナンス業務について書いていきたいと思います!!!

メンテナンスとは

メンテナンスとは、建築・土木構造物、自動車や家電製品などの機械類、情報通信システム、施設の整備・維持・保守・点検・手入れ等の意味で使われる。(wikipedia参照)
個人的にはスマホゲームのメンテナンスは、手入れの意味が大きいのかなと思います。
新しい機能の追加はもちろん、新しいキャラクターやスキルの追加、メインストーリー追加等を行い、アプリケーションのバージョンアップをお客様に促します。
いわゆる計画メンテナンスがほとんどで、事前にお客様にゲーム内お知らせやSNSで告知します。
ユーザー接続数がめちゃめちゃに増えてサーバーがパンクしたり、致命的なバグが起きてゲーム進行不能やデータが壊れたり、整備・保守の意味合いのメンテナンスもありますが、このような事態が起きないように計画メンテナンスを行っている面もあります。
要するに普段のメンテナンスで何をしているかというと、新規コンテンツをリリースするためプログラムやデータを更新するといった感じです。

なぜメンテナンスするのか

メンテナンスで行なっている事はわかったけど、なぜわざわざメンテナンスの時間を設けるのか?という疑問があるかと思います。
今のプロダクトでは大体週一回に3時間程度のメンテナンスを行っており、その間お客様はプレイできない状態になります。メンテナンスの時間帯はおおよそ固定していますが、その時間によくログインしていたり、その日はその時間にイベントを回そうと思っていたお客様のプレイの機会を奪ってしまうことになります。このようなデメリットはありつつ、メンテナンス時間を設けることで、何かをリリースする際にはしっかり確認をとってからお客様に届けることができるというメリットもあります。この辺は各社、各プロダクトの運営方針で変わります。
自分が担当していたプロダクトでは、データベースのスキーマ更新、新規機能の追加や改修でのサーバ・クライアント更新によるお客様への影響を最小限に抑えるため、メンテナンスは必要という方針となっています。
例えばユーザーデータ系のスキーマ更新はデータ量が多いため時間がかかります。その間はユーザーデータの更新が止まってしまう可能性があり、その結果タイムアウトやデータ不整合に繋がってしまいます。

また、ポケラボはギルド対ギルドの大人数のリアルタイムバトルを一番の売りにしていて、このバトルに対して熱量が高いお客様が多いです。そのバトルの最中に直近でリリースしたスキルに不具合があり、期待していた効果が発揮できずバトルに勝てなかった、最悪の場合エラーでゲームが止まってしまったとなるとお客様に多大なご迷惑をかけることになります。バトルに限らずですが、お客様が安心してゲームを遊んでいただけるように、メンテナンスを設けて最終チェックを行い、万全な状態でリリースしています。

リリースまでの流れ

新規コンテンツを開発しリリースするにあたって、自分の担当プロダクトでは以下の環境を用意しています。
・開発環境
・QA環境
・ステージング環境(本番とほぼ同じ環境)
・本番環境(お客様がプレイしている環境)
開発環境はその名前の通り、エンジニアが開発するための環境です。複数の環境があり、今後のリリースバージョンを振り分けて開発しています。
開発が終わったら、QA環境にデプロイしQAを行います。
そしてリリース日直前(前日や2日前)になったら、ステージング環境にデプロイし動作確認をします。
問題なければリリース日にステージングに反映したのと同じものを本番に反映するといった流れになります。

これらの環境はAWSのEKSを用いて構成しています。
開発とQA環境は開発用のクラスター、ステージングと本番は本番用のクラスターで構成されていて、環境に応じてnamespaceを作成しています。
開発環境ではエンジニアとプランナー、QA環境ではテスターが動作確認を行い、ステージング環境でリリース前の確認、そして本番環境での最終チェックを経て、ようやくリリースされます。本番環境でもリリースした後、メンテナンス時間内でなるべく動作確認を行います。

メンテナンスの業務の詳細

ステージング、本番環境をリリースするバージョンに合わせて構築するのがメンテナンス業務になります。

リリース日の作業は以下になります
・メンテナンス時間を設定
 →メンテナンス中にお客様がゲームにアクセスできないようにします

・データベースのスキーマ更新
 →データベースはAWSのAurora MySQLを用いていて、phpmigというマイグレーションツールを用いてスキーマ更新をしています。

・サーバーのコードデプロイ
 →リリースするブランチでdocker imageを作成し、ECR(Elastic Container Registry)にpushします。imageを環境にapplyすれば完了です

・マスタデータのインポート
 →プランナーさんがcsvで作成したアイテムやガチャデータなどをバッチを用いて、データベースに反映します。

・リソース(AssetBundleやimageファイルの静的データ)の反映
 →新しいデータをメンテナンス後にダウンロードするようにデータを構築します。

・Google Playストア、appleのApp Storeに新バージョンを公開
 →クライアントエンジニアの方に対応していただいています。

・動作確認
 →メンテナンス中でもゲーム可能なテストアカウントを用いて動作確認します

・メンテナンス後
    →テストアカウントではないアカウントでちゃんとゲームができるようになっているか確認します

コードやリソースの反映はjenkinsを用いてある程度自動化していて、手作業が発生するのは反映先の環境を指定するだけで終わります。マスタデータをインポートするバッチもjenkinsを用いて実行しています。

~~~サーバーのコードデプロイのjenkinsの例~~~
概要:
「docker imageをビルドしてpushするjob」 + 「kubectl applyをするjob」のpipeline

指定するパラメータ:
反映先の環境(変数 TARGET_NAMESPACE: qa,staging,productionなどから選択)反映先のコンテナ(変数 TARGET_ROLE: app,batchなどから選択)

中身の説明:
前者のjobでは、TARGET_NAMESPACEで指定した環境のECRにログインした後、TARGET_ROLEで指定したコンテナのimage build&pushを行う。
以下、設定しているシェルスクリプトを一部抜粋

# ECRログイン
YOUR_REGISTRY_URL = ${YOUR_REGISTRY_ID}.dkr.ecr.${YOUR_YOUR_REGION_NAME}.amazonaws.com/${TARGET_NAMESPACE}
aws ecr get-login-password  --region ${YOUR_REGION_NAME} | docker login --username AWS --password-stdin ${YOUR_REGISTRY_ID}.dkr.ecr.${YOUR_YOUR_REGION_NAME}.amazonaws.com/${TARGET_NAMESPACE}

# image build
docker image build -f ${dockerfile} -t ${YOUR_REGISTRY_URL}/${TARGET_ROLE}:${GIT_COMMIT}

# image push
docker image push ${YOUR_REGISTRY_URL}/${TARGET_ROLE}:${GIT_COMMIT}


後者のjobでは、TARGET_NAMESPACEの環境のk8sリソースをapplyし、最新のimageをpullすることでデプロイ完了。
以下、設定しているシェルスクリプトを一部抜粋

WORK_ROOT=$(pwd)

cd ${WORK_ROOT}/kustomize/overlays/${TARGET_NAMESPACE}
kubectl apply -n ${TARGET_NAMESPACE} -k .

上記の通り、反映先を指定してビルドボタンを押したらあとは終わるまで放置なので難しいことはなく正直誰でも作業できます。
ただpipelineの各jenkins jobで何をしているのかを理解していないと、エラーでpipelineが止まった時やメンテナンス中のアクシデントに自身で判断し対応できなくなってしまいます。
このjobの中身を理解するのにも、AWSのサービスやk8s等の知識がないと難しく、これらの知見があるサーバーエンジニアがメンテナンスを担当することが多いです。
知識はもちろん、リリース作業中に不具合を発見してメンテナンス中に間に合うかわからないといった事象が起こったとき、メンテナンスを延期するか、はたまた別の対応をするか、それぞれのメリデメを考え最善の判断を下すということも重要なスキルになります。僕はまだまだ知識も経験も足りないのでこれからもっと頑張りますm。

リリースするコード、マスタ、リソースの最終的なチェックはメンテナンス担当者です。
不具合や反映ミスに気づくことのできる最終防衛ラインなので、ボタンを押すだけとはいえ別の作業を行ったりする余裕は正直あまりありません。
反映の際はダブルチェックを徹底し、とにかく反映をミスらないようにしています。
正直精神がすり減ります笑

こちらはグリーグループの開発本部のインフラごとーさんのありがたきお言葉。ボタンを押すだけでも、ミスってしまったら...と考えると正直本番反映は怖いです。その怖さって何?簡単だけどボタン一つで全て反映できてしまうから?と原因を今一度分解し、解消することで、なるべく精神をすり減らさないようにできたら良いですね。

最後に

かなりざっくりでしたが、メンテナンスについて書いていきました。
記事を通して、メンテナンスってそんなことやってるんだ〜と少しでもメンテナンス業務について知っていただく機会になれば幸いです。
一年間メンテナンス業務を行なってきて、自分の担当プロダクトのシステムの理解が深まり、副次的にメトリクスやインフラ的な知識も学ぶことができました。
また、リリース作業において各職掌と連携しつつ、丁寧に進めていく姿勢は他の業務でも役立っていると感じます。

今後は、先ほど書いたような精神的負担を減らすためにメンテナンスの反映方法を改善したり、幾度の段階を踏んでも出てしまうバグや不具合を減らすためのチェックの方法などの改善を行い、少しでも高品質なものをお客様にお届けできるように頑張りたいと思います。
また、1年目は自分のことで精一杯だったので、2年目はプロダクトの目標に向かって周りに影響を与えられるようなエンジニアになれるよう日々精進していきます!
以上、拙い文章でしたが最後までご覧いただきありがとうございました。