勉強会のレポート(メモ)です。
参加したのはこちら、「スマホゲームサーバーのしくみを知ってみよう 」
会場はサポーターズです。
10/31日追記
資料が公開されました
2020/7/27追記
サーバサイドわからんという方には、@izmさんのこちらもオススメ
スマホゲームサーバーのしくみを知ってみよう
1. スマホゲームの特徴
特に売り上げが高い(ランキング上位)ゲームには共通点があります。
1-1. ゲームサイクル
・基本は育成 → バトル/クエスト → 育成 → ・・・の繰り返し
・バトル部分はシングル+マルチプレイ
・マルチプレイではリアルタイム性が求められる
1-2. 課金モデル
・基本無料+アプリ内課金(ガチャ、スタミナ回復、時短)
・ガチャが引きたいのに引けない、時短したのにサーバー障害!
→高可用性が求められる
1-3. サーバーの特徴
・ユーザ数が多いのでアクセスが多い
・リアルタイム性が求められるのでデータ更新頻度が高い
・リリース自はピーク時と平常時の求められる性能の差が大きい
・メンテナンスをなるべくしない
・リリース後も頻繁にコンテンツや機能を追加していく
1-4. データの特徴
・ユーザデータ
レベルや所持、アイテムなど、ユーザの資産となるデータ
・マスタデータ
ゲームのステージやきゃら 運営が管理するデータ
・ログデータ
KPI分析 や障害調査に使うデータ(行動のログなど)
2. システム構成 処理の流れ
ゲームモードによって求められるものはかわる。
アウトゲームとインゲームで分かれる。
2-1. アウトゲーム
・育成やガチャ・バトル開始・終了など
・リアルタイム性が求められない、一般的なWEBの構成に近い
・HTTP(S)通信
2-2. インゲーム(マルチプレイ)
・バトル中の位置、攻撃、チャットなど
・リアルタイム性が高い
・Webソケット、P2Pなどの双方向通信
アウトゲームのサーバー構成
2-3. APIサーバ
・一般的なWebアプリと同じ構成
・スケラビリティが求められる(スケールアウト・インを柔軟にしたいため)
・機能ごとに分割したサーバーを用意することもある
・特定の機能に特化することが開発に専念できる 開発が楽
2-4. データストア
DB・KVS・ログの用途で使い分ける
・DB
消えてほしくない永続データを使う(MySQLやポスグレSQL)
・KVS
キャッシュするために使うアクセス頻度が高く消えても問題ないデータを置く(最終ログイン日時など)
・ログ BigQuery
2-5. アセットサーバー
・静的ファイルの配信用サーバー(音楽や画像、3Dモデルなど)
・CDNでキャッシュさせる
・毎回クライアントがダウンロードするのはコストがかかるのでバージョン管理をしておく
2-6. アセット取得の流れ
・アセットの種別ごとにバージョンを管理するDBを用意する
・新しいアセットをデブロイしたらDBのバージョンを上げる
・クライアントがアセットのバージョンを確認するリクエストをする
・サーバーはDBのバージョンをかえす
・クライアントはそれを比較し違ったらダウンロード
2-7. アウトゲームの処理の流れ
・画面遷移、データ更新時にサーバーにリクエスト
・サーバーがデータを取得更新(転送回数を抑えるため)1度のリクエストでデータの追加や更新、取得
・リクエストメソッドの使い分けはほぼGETかPOST
xRESTfulAPIなど
2-8. インゲーム(C/S)
battleサーバー:リアルタイム性の処理をするサーバー(会社によって呼び方が違う)
・接続先はバトル開始前にAPIサーバーで割り振られる
・そのサーバーでパケットのやりとりをする
(Photonやモノビットなどリアルタイムゲームエンジンを使う(C++/Node.js/Go)
・サーバー集中型とクライアント分散でわかれる この辺はゲームで特色がでる
2-8-1. サーバー集中型
・サーバー側でゲームロジックやゲーム進行を行う
・バトル中にサーバー側でデータを保持
・端末間でずれるとまずい処理で使われる(対戦ゲームでの位置や当たり判定)
・協力バトルのボスの位置やHP(雑魚や他プレイヤーはあまり重要ではない)
・サーバーの判定処理を待つ必要がある(欠点)
・クラアントとサーバーの行動結果がずれる(ラグ)ことも
2-8-2. クライアント分散型
・それぞれの端末で進行を行う
・端末間のずれが気にならない場合に使う(協力バトルの雑魚的など)
・不正対策はしづらい
・遅延が気になるもの、サーバーを待ってられない場合に使う
・コマンド単位で同期する
・疑似的なP2P、パケットのブロードキャストに専念する
2-9.インゲームの処理の流れ
パーティを組んで戦うアクションバトルの例
1、パーティ作成参加
2、ルーム(バトル空間(終わったら消滅するような空間))を作成、バトル開始
3、ルーム内でバトル
4、終了、ルーム削除、パーティ解散
2-9-1. 入場からバトル開始
CLはクライアントの意。
CL→APIサーバーにパーティ参加のリクエスト
APL→DBにパーティがあるか確認 なければ作成
API→CLにBattkeサーバーの接続先を返す
CL→ battleサーバーにルーム接続リクエスト
CL→ APIサーバーにBattle開始を通知
ここは同期する必要はない
2-9-2. バトル中
CL→Battleサーバーにコマンドを送信(攻撃した、ダメージを受けたなどのアクション 入力情報)
Battel→CLにバトル情報を返す(攻撃した結果敵を倒した など)
Battle→CLにイベント発生を通知(イベントの進行など、時間経過で発生するイベントなど)
2-9-3. バトル終了
CL→Battleサーバーにバトル終了リクエスト
Battle→CLにルーム削除、切断処理
CL→APIサーバーにリザルトのリクエスト(バトルの報酬など
CL→APIサーバーにパーティを解散を通知
これがインゲームの流れ
2-10. その他、運営に必要なシステム
・リポジトリサーバー
ソースコードやアセットの管理、Gitが使われる
・デプロイサーバー
Gitからプルし、ソースコードのビルドやデプロイをする
・運営やカスタマーサポート用の管理ツール
データの確認、お知らせ、バナーの繁栄補填など、Webサーボスのダッシュボードてきな
・KPI基盤
ログなど 社内共通で見られる
3.運用開発で気を付けるべきこと
3-1. DBの負荷を考慮しよう
・負荷のボトルネックになりがち
・オンラインでスキーマやテーブルの変更をしづらい(データが多くなると特に
・インデックスやパーティショニングを区切る
。なるべく少ないクエリ数でやる
3-2. DBの負荷分散
(水平分割)
・ユーザのIDをキーにしたアクセスが多い(IDごとにDBサーバーを振り分ける)
・期間限定のDBを日付でパーティショニング
・マスタースレーブ構成で参照をあげる
・この辺はアプリへの負荷がかかるので内部でやってくれるマネージドサービスもあり
3-3. オンラインメンテ
・なるべくメンテしたくない場合にやる
・DBのデータ設計を変えたときや再起動をかけたい場合にやる
・マスタースレーブのマスターがネックになりがち
・解決するにはマスタースレーブ切り替え、あるいはオンラインスキーマチェンジなど(この辺は調べて)
・マネージドサービスを使うのもあり
3-4. リリース後のアラート監視
・サーバーが止まる前に対処する
・各種サーバーのエラー
・レスポンスタイム
・大事なのはお客様のお問合せ、Twitterでエゴサ
3-5. ゲーム運用で便利なツールを作る
・データ管理の仕組みを作ろう
クエストやステージを作るとき、エクセルやスプレッドからSQLに変換するツール
・デバック機能や管理ツールを作ろう
開発スピードが格段にあがる
管理ツールの権限管理は重要 (本番のデータに影響に出るような管理ツールは特に)
4. まとめ
・ゲームシステムの構成は基本的にWebアプリと一緒
・リアルタイム性が求められる構成はゲームによってことなる
・高い可用性を保つためにオンラインメンテ・アラート監視など工夫が必要
5. 質問タイム
Q-1. サーバーのエリア分割などはしてる?
特定のエリアが動かなくなったら、他のサーバーに移行させるなど
A. やってます、私がやるのは複数のリージョンを使い分けるなど
会社によってはマルチクラウドで使い分けたり、+オンプレの構成などあります
一般的にはこういうのがあります。
Q-2. 北海道の地震がありましたが対応などはあった?
A. 特になかった。
ただ、特定のユーザができないので、イベント延期などの対応は必要
Q-3. リアルタイム通信でパケットロスの対策は?
Aシーケンス番号などをパケットにふってそこがふっとんでいたらそこでロスが発生したと見抜けるので、そこで検知するなど。
Q-4. ゲームリリース時のアクセスの見積もりは想定できる?してても無理?妥協してしまう?
A. いくつかあります
・見積もりミス(想定より多くのユーザーがきた)
・プログラムの実装が悪く、負荷試験を終わった後に変更が入ってバグ発生
・負荷試験などは期間をとってやるのが難しい、しっかり備えましょうというのが教訓
・DBのアクセスが増えるのが問題で、単純のサーバーを増やすだけじゃ足りなくて問題になる
・DBの負荷にはあらかじめ実装段階からパーティションを区切る必要があるので。
一回止まってずっと止まって対応に追われるなどがある、
Q-5. Twitterに不満などを発信されてるとそこが改善されると思うが何処を基準に改善しようと思うのか
A. 不具合やエラーなどを確認する(勘違いやこっちのミスかをしっかり判断してお知らせを出す)
特定のキャラが強すぎる、ゲームバランスがおかしいなどの声が大きい場合はそれを修正する検討をする。
機能追加は運営の方針とあっていれば十分やります
感想
個人開発だとクライアント側ばかりでなかなかサーバーサイドについて知る機会がありませんよね。
オンライン機能の実装はNCMBとかに丸投げだったり。。。
ちゃんと勉強したことがなかったのでなかなか刺激になりました。