某IPスマホゲーム

OVERVIEW

某IPスマホゲームの開発/運用/保守/分析

YEAR 2018 - 2019

## 課題:「ユーザーのページが多岐に渡っているので動的にログが切り替わる管理画面ページが欲しい」を Vue の導入で解決

### 背景

- 元々の管理画面は bootstrap + jQuery のシンプルな web アプリケーションとして実装されている管理画面でした

- プランナーさんの要望の中で、こちらの課題を始めとして、jQuery で立ち向かうには工数的にもつらくなってきました


### 検証

- シンプルに jQuery で実装することも検討しましたが、直接のDOM操作を行うコーディングではどうしても保守コストが高くなっていくように感じました

- そこで流行っている仮想DOMについて調べ導入することを検討することにしました

- riot や React, そして Vue などが候補として上がりました


### Vue を選んだ理由

- 公式ドキュメントが充実していて学習コストが低い

    - 当時はまだプロジェクトチーム内に学生アルバイトもいて、チームメンバーも流動的でした

    - 社内での仮想DOM利用チームがほぼ無い状態で、新しくチームにアサインされた人でも比較的容易に書き始められるようにとするためには学習コストの面はかなり大きいように感じました

- 学習コスト面から React は今回は除外しました

- riot は学習コスト面から魅力的でしたが、社内では IDE として PHPStorm を推奨おりそちらに強力なサポートがあるのは Vue だったため Vue を選択しました


## 課題:「本番環境に施策が上がっていなかった問題」を ChatWork への通知等で解決

### 背景

- 本番リリースから数ヶ月経ってから本番環境に施策が上がっていない問題が発生したことがありました


### 原因

- 原因は、マスターデータ作成時の考慮漏れです


### 提案

- 各々問題点を上げていく中、僕はサーバー側として、マスターデータを作成しているプランナーさんが、本番環境にアップロード済みの施策を気軽に常時確認出来ないことが原因の一旦であり、自分が対応できる範囲の箇所と考えました

- そこで解決策として提示させてもらったのが、普段の業務のやり取りに使っている ChatWork へスケジュールの通知を行う bot の作成、及び管理画面から特定環境のスケジュールをガントチャートで確認できるツールです

    - ChatWork は業務で使っていて常に誰かしら目を通しているのでここに通知しておけば取り敢えず誰かしらの目に入るだろうと思いました

    - 管理画面からプランナーさんでも分かりやすいようなガントチャートとしてスケジュールが参照できれば間違いにもすぐ気付けるように思いました


### 実装

- スケジュールデータを参照用途にまとめました

    - マスターデータは sql 定義されたものです

    - スケジュールを管理するマスターには共通のインターフェースがなく、自由なカラム名が設定されていました(開始日が start_date だったり, started_at だったり ... etc)

    - 通知に当たって使いやすい中間テーブルを用意すれば、この問題が解決できるように考えました

    - 具体的には、date, hours, summary, id を持つ schedule_{start, end} の view を用意、各種テーブルから inner join して作成した概要を union all することで実現しました

- ChatWork bot の実装しました

    - ゲームAPIがPHPで書かれているため、PHPで実装しました

    - ChatWork は API が公開されていたため Guzzle を使えばすぐ実装できるように考えそちらで実践しました

    - 上記で下準備したデータを ChatWork の [info] タグ等でくくって表示、プランナーさんが分かりやすいような加工を心がけました

- ガントチャートの実装をしました

    - ガントチャート自体は開始当初は Google の Gantt Charts で良いように考えていました

    - 利用料が無料である点、GANTTplanner のように、Google カレンダーと連携すれば比較的工数削減した上でガントチャートを提供できるように思い採用してみました

    - 結果としては、プランナーさんの要望に応えられず代替案として探したのが [gantt-elastic](https://github.com/neuronetio/gantt-elastic) というライブラリです

    - 前述させてもらった Vue で使えるライブラリをというていで調べた結果上が見つかりました

    - 余談

        - ライブラリで使って覚えた技術を基に対象ライブラリに [PRを投げたり](https://github.com/neuronetio/gantt-elastic/pull/24)

        - タスク管理システム[ ClickUp と連携してタスクをガント化できるツール](https://github.com/somen440/cup-gantt) を作ってみたり、アウトプットも欠かさず行いました


## 課題: ローカル開発環境の立ち上がりが遅い等の問題を dockernize で解決

### 背景

- ローカル開発環境は vagrant VM で構成されていました

- provision として ansible が採用されていて、専用の public IP を申請する必要があったりで、構築完了で 1 人日が終わってしまっていた

- 開発中も smb による同期は不安定だったり同期が遅い問題もありました

- 会社としてIDE phpstorm が推奨されていて提供されていましたが、せっかくのIDEの恩恵(xdebug と連携してユニットテストをステップ実行する、git 関連の同期など)を受けづらい問題もありました


### 対応

- 既に稼働している本番環境と同等のコンテナを立ち上げ稼働させることができれば、開発効率アップだけでなく、本番構成特有の現象も未然に対応できるかもしれないと考えました

- amazon linux の web に必要なミドルウェアを入れた api コンテナを用意し mysql, redis, memcached などのコンテナを docker-compoe で動くよう対応しました


## 課題: 全容が見えていない海外版引き継ぎ対応を担当

### 背景

- プロジェクトリリース当初から海外版の話はあり、国内版と並行する形で海外版対応が進んでいました

- ある程度進んだところでお客様都合により、海外版対応が凍結されました

- どこまでできているのか、何をすれば良いか全容が見えない段階で担当者としてアサインすることになりました


### まず何をしたか

- どこまで出来ているか、何が用意されているかを把握するところから始めました

    - ローカル開発環境の把握

    - dev環境の把握

    - 国内版との差分の把握

    - ローカライズ対応についての把握

- 把握した内容を順に足りてない部分を補う形で対応を進めました


### 対応

- ローカル環境について

    - 国内版では dockernize が進んでいて開発効率が上がっていたところ vagrant VM のままでした

    - 国内<->海外でアサインされるメンバーが共通していることを鑑みて、ローカル開発環境の効率アップは最優先事項と考え、国内版で対応した dockernize から移植を進めました

- AWS で構築されていた dev 環境を把握し、デプロイ改善も行いました

    - 引き継ぎ段階では直列で時間がかかりすぎてしまい開発が滞ってしまう問題がありました

    - 複数言語分のアセットをS3に上げる必要があって、並列処理によって解決しました

- 国内版よりも扱うマスターデータが増える都合上、環境間の差分がより気になる要件が出てきました

    - 環境間のデータ差分を取って ChatWork に通知することで解決できるように考えました

    - 特に何で実装しても同じような感じだろうと考えました。そのため後述の locust シナリオを組む上でのステップアップとしてもちょうど良いと考え、python の練習として実装しました

- 本番環境を立ち上げるにあたり、本番同等の負荷試験環境を立てて負荷試験を行いました

    - 元々の国内版は jMeter でシナリオが組まれていました

    - 工数面や保守コストを考え、python でシナリオを構成できる locust を採用することが効率的であるように考え、locust について調べました

    - 社内における locust 負荷試験実績は少なかったものの、前例があったため、別チームの方の助力を得つつ、シナリオを構築しました

    - 最終的には秒間 7222 rps をこなすための攻撃サーバーの用意、耐えるための本番構成を提供することが出来ました

    - 負荷に耐えるに辺り、ベースは国内版からの移植作業で構築ベースはそのまま利用しました

    - ベースから試験を行い、要件に合わせた負荷をかけていく中でスケールさせていくよう対応を行いました

    - 万が一の負荷があってもスケールできる構成であれば問題ないように考え上のように対応しました


## 課題: お客様の要望で全テーブルを対象としたダンプを GCS へ送る対応を golang で解決

### 背景


- お客様がプロジェクトを跨いだ分析を行う要件があり、全テーブルデータを特定の形式に変換しなおし、お客様管理の Google Cloud Storage へ送信する必要がありました。


### 検討

- 当初はシェルから下手にエクスポート -> 加工とすることで対応できるように考えました

- しかし、変換要件が思った以上に複雑であり、シェルでは厳しいことが判明しました

- 言語として型があり厳格であること、lint や cs などが標準でついていてサポートが優秀であること、エディタの恩恵も熱く、何より興味があったので golang で実装することを検討しました

- 興味本位だけでなく、国内版の実績から、1 日あたり相当数のデータが来ることが予想できたため、GCなどが標準でついていてメモリセーフにも実装できる golang が魅力的に写り採用に至りました

### 結果

- 予想通り 1 日辺りのデータ量は多く、多いテーブルで 10 GB を超えるものもありました

    - 大容量データとの戦い方のコツも掴めたような気がします...

- golang により処理できたおかげでサーバーが死ぬことなく処理を捌けました

- 余談: golang を学ぶに辺り、アウトプットとして、koazee という [OSS へのPR](https://github.com/wesovilabs/koazee/pull/50) も行いました