コロプラのリアルタイム通信基盤/ColoplTech-03-01
by
COLOPL Inc.
×
Copy
Open
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Slide 1
Slide 1 text
コロプラの リアルタイム通信基盤 2022/03/17
Slide 2
Slide 2 text
自己紹介 ● R.Y. ○ 最近ニックネームが欲しくなってきた ● 2020年4月 新卒入社 ● 技術基盤本部 第2バックエンドエンジニア部 prizmチーム 2
Slide 3
Slide 3 text
前提: コロプラでよくあるリアルタイム通信 ● 部屋を作りその中でプレイヤー同士で対戦や協力などをするゲーム ○ MMO のように一つの大きなワールドを管理するようなゲームではない Room A Room B Room C こんなイメージ 3
Slide 4
Slide 4 text
リアルタイム通信を実現するために ● 最初はそれぞれのプロジェクトで独自に実装していた ○ WebSocket を利用したものや C++ によるサーバー実装など多様 ● リアルタイム通信を扱うプロジェクトが増えたことなどを理由に prizm の前身となるリアルタイム通信のフレームワークを作成 ○ Node.js 製 ● メンテナンス性や並行性などの理由から Go でリアルタイム通信の フレームワークを作り直すことにして現在に至る 4
Slide 5
Slide 5 text
prizm に求められた要求事項 ● TCP と UDP の両方を使える ○ 入室時のユーザー情報やゲームの結果の同期など TCP が欲しい場面も存在 ● サーバー側にロジックを書ける ● GKE 上で動作する ● チームで開発されている ○ ドキュメント・サポートが手厚い 5
Slide 6
Slide 6 text
prizm とは ● コロプラで開発している対人や協力などリアルタイム性のある ゲームのためのフレームワーク ○ サーバー(Go): いわゆるリアルタイムサーバーを作るためのフレームワーク ○ クライアント(Unity, C#): リアルタイムサーバーと通信するクライアントの基盤ライブラリ ● 部屋内でのメッセージのやり取りをすることを想定しているシンプルな作り ○ 物理演算などはしない ● 開発・運用で便利な機能や特定のインフラ環境への対応は コア機能からは外している ○ 例えば Kubernetes 環境を前提にするとローカル環境の構築が面倒 6
Slide 7
Slide 7 text
prizm のコア機能 prizm Server クライアント Message Message Message Message Message Message Message クライアント・サーバー間でメッ セージを送り合う 7
Slide 8
Slide 8 text
prizm のコア機能 prizm Server func OnChatMessage(...) { BroadcastChatMessage(...) } Message受信時の処理を サーバー側に実装 8
Slide 9
Slide 9 text
prizm のコア機能 ● メッセージ送信 ○ クライアント→サーバー ○ サーバー→クライアント ● メッセージ受信時の処理をサーバーに実装 9
Slide 10
Slide 10 text
prizm の特徴 ● コード生成 ● モック環境 ● 可観測性 ● Kubernetes インフラ ● サポート体制 ● その他方針・考えていることなど 10
Slide 11
Slide 11 text
prizm の特徴 ● コード生成 ● モック環境 ● 可観測性 ● Kubernetes インフラ ● サポート体制 ● その他方針・考えていることなど 11
Slide 12
Slide 12 text
コード生成 ● クライアント・サーバーの開発を効率化するため CLI ツールによるコード生成を多用 ○ プロジェクト全体の生成 ○ メッセージ定義の生成 ○ リレーメッセージの生成 12
Slide 13
Slide 13 text
プロジェクト生成 ● CLI ツールでプロジェクトの雛形を作成 $ prizm new ... 13
Slide 14
Slide 14 text
プロジェクト生成 ● CLI ツールでプロジェクトの雛形を作成 $ prizm new ... ロギング用のパッケージや テスト用の bot なども生成 14
Slide 15
Slide 15 text
メッセージ定義とコード生成 ● .proto ファイルをもとに C# / Go のコードを自動生成 ○ メッセージ構造の定義 ○ メッセージ送信やメッセージ受信時のハンドラの実装に必要なスタブコード syntax = "proto3"; service GameService { rpc SendMessage() ... } message TestMessage { string body = 1; } GameService.cs gameservice.go 15
Slide 16
Slide 16 text
メッセージ定義とコード生成 ● .proto ファイルをもとに C# / Go のコードを自動生成 ○ メッセージ構造の定義 ○ 送受信に必要なスタブコード $ mkdir -p pkg/proto $ prizm generate Generating proto/prizm.proto Generating pkg/proto/message.go Generating pkg/proto/chatservice.go Generating pkg/proto/chatservice_client.go ... 16
Slide 17
Slide 17 text
リレーメッセージの生成 ● 部屋全体にそのままメッセージを転送(リレー)するメッセージの生成 ● サーバー側にロジックが不要な場合の実装コストを減らせる ○ 前述したようなやり方だとメッセージを増やすたびにサーバーの再ビルドが必要だった ○ リレーメッセージを使えば クライアントのみの変更 でメッセージを追加できる ChatMessage ChatMessage 17
Slide 18
Slide 18 text
リレーメッセージの生成 ● コード生成用の .proto ファイルにリレー専用の書き方をする syntax = "proto3"; service InGameService { option(bind_relay) = xxx; } message RelayMessage { Move move = 1; Chat chat = 2; } message Move { … } message Chat { … } Chat.Relay.cs chat_relay.go 18
Slide 19
Slide 19 text
prizm の特徴 ● コード生成 ● モック環境 ● 可観測性 ● Kubernetes インフラ ● サポート体制 ● その他方針・考えていることなど 19
Slide 20
Slide 20 text
prizm のモック環境 ● クライアントエンジニアのみでマルチプレイを作りたい!という 要求をもとに常設のモック用サーバーを用意 ○ ゲーム開発初期のモックを開発する段階を意識 ○ Photon Cloud のような感覚で使える ● モック環境では前述のリレーメッセージを利用 ○ リレーメッセージの「クライアントのみの変更でメッセージを追加できる」特性を利用 ○ 開発が進んで専用の prizm サーバーを立てたときにも クライアント側の実装をそのまま使える 20
Slide 21
Slide 21 text
prizm のモック環境 prizm mock server prizmチーム ゲーム開発チーム ① モック準備依頼 21
Slide 22
Slide 22 text
prizm のモック環境 prizm mock server prizmチーム ゲーム開発チーム ① モック準備依頼 ② namespace追加 22
Slide 23
Slide 23 text
prizm のモック環境 prizm mock server prizmチーム ゲーム開発チーム ① モック準備依頼 ② namespace追加 ③ 利用 23
Slide 24
Slide 24 text
prizm の特徴 ● コード生成 ● モック環境 ● 可観測性 ● Kubernetes インフラ ● サポート体制 ● その他方針・考えていることなど 24
Slide 25
Slide 25 text
prizm の可観測性 ● 実装のミスやパフォーマンスの問題を気づきやすくするため、 以下の方法で指標を公開 ○ Prometheus exporter(メトリクス) ○ Opencensus Tracing(分散トレース) ○ pprof / Cloud Profiler(プロファイラ) ● 1月に prizm に Cloud Profiler という GCP が提供しているプロファイラを 導入したときの話を発表しているので良かったらそちらも見てください 25
Slide 26
Slide 26 text
prizm の可観測性 26
Slide 27
Slide 27 text
prizm の特徴 ● コード生成 ● モック環境 ● 可観測性 ● Kubernetes インフラ ● サポート体制 ● その他方針・考えていることなど 27
Slide 28
Slide 28 text
prizm の動作環境 ● ローカル環境 ○ Go でビルド可能な環境であれば OK ○ Windows, Mac, Linux, … ● dev, stg, 本番環境 ○ Kubernetes や Agones を活用できるようにしている ■ Agones: Kubernetes 上でゲームのリアルタイム通信のような ステートフルなサーバーを管理できるようにしてくれる OSS ○ 次の発表でここらへんを詳しく発表してもらいます 28
Slide 29
Slide 29 text
Kubernetes 環境での prizm ● prizm と Agones SDK との間で必要なやりとりを prizm 開発チームでライブラリ化 prizm server Agones sidecar Agones SDKとの やりとりをライブラリ化 29
Slide 30
Slide 30 text
クラウド環境でのログ出力 ● ターミナル上では プレーンテキストで出力 ○ 目で追いやすいように している ● クラウド環境では JSON で出力 ○ GCP Cloud Logging で 処理しやすくしている 30
Slide 31
Slide 31 text
prizm の特徴 ● コード生成 ● モック環境 ● 可観測性 ● Kubernetes インフラ ● サポート体制 ● その他方針・考えていることなど 31
Slide 32
Slide 32 text
prizm のサポート体制 ● prizm の開発や prizm を用いたゲーム開発をサポートするチームを編成 ● prizm や prizm を用いたゲーム開発をサポートするために 2種類のドキュメントを整備 ○ ゲーム開発ガイド(ゲーム開発者向け) ○ 内部仕様ドキュメント(ライブラリ開発者向け) ● また、 prizm を利用したゲーム開発のイメージを掴んでもらうための サンプルを用意 ○ ターン制のゲーム(リバーシ) ○ マッチングの骨組み 32
Slide 33
Slide 33 text
prizm のサポート体制 ● ゲーム開発ガイド(ゲーム開発者向け) 33
Slide 34
Slide 34 text
prizm のサポート体制 ● 内部仕様ドキュメント(ライブラリ開発者向け) 34
Slide 35
Slide 35 text
prizm の特徴 ● コード生成 ● モック環境 ● 可観測性 ● Kubernetes インフラ ● サポート体制 ● その他方針・考えていることなど 35
Slide 36
Slide 36 text
複数のプレイヤーを prizm へ接続させる ● マルチプレイを提供するためにはサーバーやルームを用意するだけでは だめで、用意したルームに他のプレイヤーが入れるようにする必要がある ● これを実現するためには以下のものが必要 ○ 存在するサーバー / 部屋を見つける機能( Service Discovery?) ○ プレイヤーを適切な部屋に紐付ける機能(マッチング) ● prizm 自体にはこれらの機能を載せず、 API サーバーなどで実装するようにしている ○ prizm の機能をシンプルにするため 36
Slide 37
Slide 37 text
新しく部屋を作ったとき prizm-server API Server (PHP) Database 等の部屋情報を DBに保存 37
Slide 38
Slide 38 text
既存の部屋に参加するとき prizm-server API Server (PHP) マルチの部屋に参加した い 部屋番号: 12345 Database 38
Slide 39
Slide 39 text
既存の部屋に参加するとき prizm-server API Server (PHP) マルチの部屋に参加した い 部屋番号: 12345 Database 部屋番号: 12345 の部屋データ(IP:Port) を取得 39
Slide 40
Slide 40 text
既存の部屋に参加するとき prizm-server API Server (PHP) のprizm へ接続 Database 部屋番号: 12345 の部屋データ(IP:Port) を取得 40
Slide 41
Slide 41 text
設計方針 ● 自前実装はなるべく避け、広く使われている実装があればそれを使う ○ JWT(認証) ○ TLS(暗号化) ○ Prometheus(メトリクス) ● パフォーマンスよりも使いやすさを重視 ○ パフォーマンスを軽視しているわけではないです ■ 使い勝手の悪くなるパフォーマンスチューニングはしない、といった感じ ○ コード以外の面でも使いやすさを追求 ■ ドキュメントやサポートを充実させて間違った使い方を防ぐ ■ プロファイリングを充実させて実装ミスに素早く気付けるようにする 41
Slide 42
Slide 42 text
設計方針 ● テストをちゃんとやる ○ テスト内で実際に TCP / UDP サーバーを立てて通信してみる ○ パケットの損失や遅延、順序入れ替えをシミュレートする ○ C# クライアントと Go サーバーでの結合テストもする ○ make test ですべてのテストが実行されるし、 CI でもテストが回る ⇒新機能追加時・リファクタリング時の安心感につながる! 42
Slide 43
Slide 43 text
現状の課題 ● 依存ライブラリの追従 ○ Kubernetes 関連は動きが早いのでついていくのが大変 ● 異常系を考慮した設計の共有 ○ 切断などからの復帰やサーバー障害への考慮など ○ ゲームの仕様によってやりたいことが変わってくるのでライブラリ化が難しい ● コロプラのメイン言語(PHP)と異なる言語での開発 ○ ゲーム開発チームへのレクチャー・サポートが必要 ○ ドキュメントを頑張って書く、積極的にサポートしにいく ● 運用が始まったばかり ○ 実際に運用していく中で知見を貯めていく、課題を解決していく 43
Slide 44
Slide 44 text
まとめ ● コロプラ内製のリアルタイム通信基盤 prizm を紹介 ○ 合わせてコード生成やクラウド環境への対応など開発・運用に必要なものも紹介 ● 優れた設計・パフォーマンスよりも使う側にとっての分かりやすさを重視 ○ 最終的なゴールはゲームを作って良いものにしていくこと ● 技術力だけでなく使い手側の気持ちになることが大事 ○ ドキュメント ○ サポート体制 44