Upgrade to Pro — share decks privately, control downloads, hide ads and more …

コロプラのリアルタイム通信基盤/ColoplTech-03-01

 コロプラのリアルタイム通信基盤/ColoplTech-03-01

※資料内の参照リンクを選択し閲覧する場合は、ダウンロードをお願いいたします

\積極的に技術発信を行なっております/
▽ Twitter/COLOPL_Tech
https://twitter.com/colopl_tech

▽ connpassページ
http://colopl.connpass.com

▽ COLOPL Tech Blog
http://blog.colopl.dev

COLOPL Inc.

March 17, 2022
Tweet

More Decks by COLOPL Inc.

Other Decks in Technology

Transcript

  1. コロプラの
    リアルタイム通信基盤
    2022/03/17

    View full-size slide

  2. 自己紹介
    ● R.Y.
    ○ 最近ニックネームが欲しくなってきた
    ● 2020年4月 新卒入社
    ● 技術基盤本部 第2バックエンドエンジニア部 prizmチーム
    2

    View full-size slide

  3. 前提: コロプラでよくあるリアルタイム通信
    ● 部屋を作りその中でプレイヤー同士で対戦や協力などをするゲーム
    ○ MMO のように一つの大きなワールドを管理するようなゲームではない
    Room A Room B Room C
    こんなイメージ
    3

    View full-size slide

  4. リアルタイム通信を実現するために
    ● 最初はそれぞれのプロジェクトで独自に実装していた
    ○ WebSocket を利用したものや C++ によるサーバー実装など多様
    ● リアルタイム通信を扱うプロジェクトが増えたことなどを理由に
    prizm の前身となるリアルタイム通信のフレームワークを作成
    ○ Node.js 製
    ● メンテナンス性や並行性などの理由から Go でリアルタイム通信の
    フレームワークを作り直すことにして現在に至る
    4

    View full-size slide

  5. prizm に求められた要求事項
    ● TCP と UDP の両方を使える
    ○ 入室時のユーザー情報やゲームの結果の同期など TCP が欲しい場面も存在
    ● サーバー側にロジックを書ける
    ● GKE 上で動作する
    ● チームで開発されている
    ○ ドキュメント・サポートが手厚い
    5

    View full-size slide

  6. prizm とは
    ● コロプラで開発している対人や協力などリアルタイム性のある
    ゲームのためのフレームワーク
    ○ サーバー(Go): いわゆるリアルタイムサーバーを作るためのフレームワーク
    ○ クライアント(Unity, C#): リアルタイムサーバーと通信するクライアントの基盤ライブラリ
    ● 部屋内でのメッセージのやり取りをすることを想定しているシンプルな作り
    ○ 物理演算などはしない
    ● 開発・運用で便利な機能や特定のインフラ環境への対応は
    コア機能からは外している
    ○ 例えば Kubernetes 環境を前提にするとローカル環境の構築が面倒
    6

    View full-size slide

  7. prizm のコア機能
    prizm Server

    クライアント

    Message
 Message

    Message

    Message

    Message

    Message

    Message

    クライアント・サーバー間でメッ
    セージを送り合う
    7

    View full-size slide

  8. prizm のコア機能
    prizm Server

    func OnChatMessage(...) {
    BroadcastChatMessage(...)
    }
    Message受信時の処理を
    サーバー側に実装
    8

    View full-size slide

  9. prizm のコア機能
    ● メッセージ送信
    ○ クライアント→サーバー
    ○ サーバー→クライアント
    ● メッセージ受信時の処理をサーバーに実装
    9

    View full-size slide

  10. prizm の特徴
    ● コード生成
    ● モック環境
    ● 可観測性
    ● Kubernetes インフラ
    ● サポート体制
    ● その他方針・考えていることなど
    10

    View full-size slide

  11. prizm の特徴
    ● コード生成
    ● モック環境
    ● 可観測性
    ● Kubernetes インフラ
    ● サポート体制
    ● その他方針・考えていることなど
    11

    View full-size slide

  12. コード生成
    ● クライアント・サーバーの開発を効率化するため
    CLI ツールによるコード生成を多用
    ○ プロジェクト全体の生成
    ○ メッセージ定義の生成
    ○ リレーメッセージの生成
    12

    View full-size slide

  13. プロジェクト生成
    ● CLI ツールでプロジェクトの雛形を作成
    $ prizm new ...
    13

    View full-size slide

  14. プロジェクト生成
    ● CLI ツールでプロジェクトの雛形を作成
    $ prizm new ...
    ロギング用のパッケージや
    テスト用の bot なども生成
    14

    View full-size slide

  15. メッセージ定義とコード生成
    ● .proto ファイルをもとに C# / Go のコードを自動生成
    ○ メッセージ構造の定義
    ○ メッセージ送信やメッセージ受信時のハンドラの実装に必要なスタブコード
    syntax = "proto3";
    service GameService {
    rpc SendMessage() ...
    }
    message TestMessage {
    string body = 1;
    }
    GameService.cs
    gameservice.go
    15

    View full-size slide

  16. メッセージ定義とコード生成
    ● .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

    View full-size slide

  17. リレーメッセージの生成
    ● 部屋全体にそのままメッセージを転送(リレー)するメッセージの生成
    ● サーバー側にロジックが不要な場合の実装コストを減らせる
    ○ 前述したようなやり方だとメッセージを増やすたびにサーバーの再ビルドが必要だった
    ○ リレーメッセージを使えば クライアントのみの変更 でメッセージを追加できる
    ChatMessage

    ChatMessage

    17

    View full-size slide

  18. リレーメッセージの生成
    ● コード生成用の .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

    View full-size slide

  19. prizm の特徴
    ● コード生成
    ● モック環境
    ● 可観測性
    ● Kubernetes インフラ
    ● サポート体制
    ● その他方針・考えていることなど
    19

    View full-size slide

  20. prizm のモック環境
    ● クライアントエンジニアのみでマルチプレイを作りたい!という
    要求をもとに常設のモック用サーバーを用意
    ○ ゲーム開発初期のモックを開発する段階を意識
    ○ Photon Cloud のような感覚で使える
    ● モック環境では前述のリレーメッセージを利用
    ○ リレーメッセージの「クライアントのみの変更でメッセージを追加できる」特性を利用
    ○ 開発が進んで専用の prizm サーバーを立てたときにも
    クライアント側の実装をそのまま使える
    20

    View full-size slide

  21. prizm のモック環境
    prizm mock
    server
    prizmチーム
 ゲーム開発チーム

    ① モック準備依頼

    21

    View full-size slide

  22. prizm のモック環境
    prizm mock
    server
    prizmチーム
 ゲーム開発チーム

    ① モック準備依頼

    ② namespace追加

    22

    View full-size slide

  23. prizm のモック環境
    prizm mock
    server
    prizmチーム
 ゲーム開発チーム

    ① モック準備依頼

    ② namespace追加
 ③ 利用

    23

    View full-size slide

  24. prizm の特徴
    ● コード生成
    ● モック環境
    ● 可観測性
    ● Kubernetes インフラ
    ● サポート体制
    ● その他方針・考えていることなど
    24

    View full-size slide

  25. prizm の可観測性
    ● 実装のミスやパフォーマンスの問題を気づきやすくするため、
    以下の方法で指標を公開
    ○ Prometheus exporter(メトリクス)
    ○ Opencensus Tracing(分散トレース)
    ○ pprof / Cloud Profiler(プロファイラ)
    ● 1月に prizm に Cloud Profiler という GCP が提供しているプロファイラを
    導入したときの話を発表しているので良かったらそちらも見てください
    25

    View full-size slide

  26. prizm の可観測性
    26

    View full-size slide

  27. prizm の特徴
    ● コード生成
    ● モック環境
    ● 可観測性
    ● Kubernetes インフラ
    ● サポート体制
    ● その他方針・考えていることなど
    27

    View full-size slide

  28. prizm の動作環境
    ● ローカル環境
    ○ Go でビルド可能な環境であれば OK
    ○ Windows, Mac, Linux, …
    ● dev, stg, 本番環境
    ○ Kubernetes や Agones を活用できるようにしている
    ■ Agones: Kubernetes 上でゲームのリアルタイム通信のような
    ステートフルなサーバーを管理できるようにしてくれる OSS
    ○ 次の発表でここらへんを詳しく発表してもらいます
    28

    View full-size slide

  29. Kubernetes 環境での prizm
    ● prizm と Agones SDK との間で必要なやりとりを
    prizm 開発チームでライブラリ化
    prizm server

    Agones

    sidecar

    Agones SDKとの
    やりとりをライブラリ化
    29

    View full-size slide

  30. クラウド環境でのログ出力
    ● ターミナル上では
    プレーンテキストで出力
    ○ 目で追いやすいように
    している
    ● クラウド環境では
    JSON で出力
    ○ GCP Cloud Logging で
    処理しやすくしている
    30

    View full-size slide

  31. prizm の特徴
    ● コード生成
    ● モック環境
    ● 可観測性
    ● Kubernetes インフラ
    ● サポート体制
    ● その他方針・考えていることなど
    31

    View full-size slide

  32. prizm のサポート体制
    ● prizm の開発や prizm を用いたゲーム開発をサポートするチームを編成
    ● prizm や prizm を用いたゲーム開発をサポートするために
    2種類のドキュメントを整備
    ○ ゲーム開発ガイド(ゲーム開発者向け)
    ○ 内部仕様ドキュメント(ライブラリ開発者向け)
    ● また、 prizm を利用したゲーム開発のイメージを掴んでもらうための
    サンプルを用意
    ○ ターン制のゲーム(リバーシ)
    ○ マッチングの骨組み
    32

    View full-size slide

  33. prizm のサポート体制
    ● ゲーム開発ガイド(ゲーム開発者向け)
    33

    View full-size slide

  34. prizm のサポート体制
    ● 内部仕様ドキュメント(ライブラリ開発者向け)
    34

    View full-size slide

  35. prizm の特徴
    ● コード生成
    ● モック環境
    ● 可観測性
    ● Kubernetes インフラ
    ● サポート体制
    ● その他方針・考えていることなど
    35

    View full-size slide

  36. 複数のプレイヤーを prizm へ接続させる
    ● マルチプレイを提供するためにはサーバーやルームを用意するだけでは
    だめで、用意したルームに他のプレイヤーが入れるようにする必要がある
    ● これを実現するためには以下のものが必要
    ○ 存在するサーバー / 部屋を見つける機能( Service Discovery?)
    ○ プレイヤーを適切な部屋に紐付ける機能(マッチング)
    ● prizm 自体にはこれらの機能を載せず、
    API サーバーなどで実装するようにしている
    ○ prizm の機能をシンプルにするため
    36

    View full-size slide

  37. 新しく部屋を作ったとき
    prizm-server
    API Server (PHP)
    Database
    等の部屋情報を
    DBに保存
    37

    View full-size slide

  38. 既存の部屋に参加するとき
    prizm-server
    API Server
    (PHP)
    マルチの部屋に参加した

    部屋番号: 12345
    Database
    38

    View full-size slide

  39. 既存の部屋に参加するとき
    prizm-server
    API Server
    (PHP)
    マルチの部屋に参加した

    部屋番号: 12345
    Database 部屋番号: 12345
    の部屋データ(IP:Port)
    を取得
    39

    View full-size slide

  40. 既存の部屋に参加するとき
    prizm-server
    API Server
    (PHP)
    のprizm へ接続
    Database 部屋番号: 12345
    の部屋データ(IP:Port)
    を取得
    40

    View full-size slide

  41. 設計方針
    ● 自前実装はなるべく避け、広く使われている実装があればそれを使う
    ○ JWT(認証)
    ○ TLS(暗号化)
    ○ Prometheus(メトリクス)
    ● パフォーマンスよりも使いやすさを重視
    ○ パフォーマンスを軽視しているわけではないです
    ■ 使い勝手の悪くなるパフォーマンスチューニングはしない、といった感じ
    ○ コード以外の面でも使いやすさを追求
    ■ ドキュメントやサポートを充実させて間違った使い方を防ぐ
    ■ プロファイリングを充実させて実装ミスに素早く気付けるようにする
    41

    View full-size slide

  42. 設計方針
    ● テストをちゃんとやる
    ○ テスト内で実際に TCP / UDP サーバーを立てて通信してみる
    ○ パケットの損失や遅延、順序入れ替えをシミュレートする
    ○ C# クライアントと Go サーバーでの結合テストもする
    ○ make test ですべてのテストが実行されるし、 CI でもテストが回る
    ⇒新機能追加時・リファクタリング時の安心感につながる!
    42

    View full-size slide

  43. 現状の課題
    ● 依存ライブラリの追従
    ○ Kubernetes 関連は動きが早いのでついていくのが大変
    ● 異常系を考慮した設計の共有
    ○ 切断などからの復帰やサーバー障害への考慮など
    ○ ゲームの仕様によってやりたいことが変わってくるのでライブラリ化が難しい
    ● コロプラのメイン言語(PHP)と異なる言語での開発
    ○ ゲーム開発チームへのレクチャー・サポートが必要
    ○ ドキュメントを頑張って書く、積極的にサポートしにいく
    ● 運用が始まったばかり
    ○ 実際に運用していく中で知見を貯めていく、課題を解決していく
    43

    View full-size slide

  44. まとめ
    ● コロプラ内製のリアルタイム通信基盤 prizm を紹介
    ○ 合わせてコード生成やクラウド環境への対応など開発・運用に必要なものも紹介
    ● 優れた設計・パフォーマンスよりも使う側にとっての分かりやすさを重視
    ○ 最終的なゴールはゲームを作って良いものにしていくこと
    ● 技術力だけでなく使い手側の気持ちになることが大事
    ○ ドキュメント
    ○ サポート体制
    44

    View full-size slide