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

E704514df1d69d511c4c74771a40c8f5?s=128

COLOPL Inc.

March 17, 2022
Tweet

More Decks by COLOPL Inc.

Other Decks in Technology

Transcript

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

  2. 自己紹介 • R.Y. ◦ 最近ニックネームが欲しくなってきた • 2020年4月 新卒入社 • 技術基盤本部

    第2バックエンドエンジニア部 prizmチーム 2
  3. 前提: コロプラでよくあるリアルタイム通信 • 部屋を作りその中でプレイヤー同士で対戦や協力などをするゲーム ◦ MMO のように一つの大きなワールドを管理するようなゲームではない Room A Room

    B Room C こんなイメージ 3
  4. リアルタイム通信を実現するために • 最初はそれぞれのプロジェクトで独自に実装していた ◦ WebSocket を利用したものや C++ によるサーバー実装など多様 • リアルタイム通信を扱うプロジェクトが増えたことなどを理由に

    prizm の前身となるリアルタイム通信のフレームワークを作成 ◦ Node.js 製 • メンテナンス性や並行性などの理由から Go でリアルタイム通信の フレームワークを作り直すことにして現在に至る 4
  5. prizm に求められた要求事項 • TCP と UDP の両方を使える ◦ 入室時のユーザー情報やゲームの結果の同期など TCP

    が欲しい場面も存在 • サーバー側にロジックを書ける • GKE 上で動作する • チームで開発されている ◦ ドキュメント・サポートが手厚い 5
  6. prizm とは • コロプラで開発している対人や協力などリアルタイム性のある ゲームのためのフレームワーク ◦ サーバー(Go): いわゆるリアルタイムサーバーを作るためのフレームワーク ◦ クライアント(Unity,

    C#): リアルタイムサーバーと通信するクライアントの基盤ライブラリ • 部屋内でのメッセージのやり取りをすることを想定しているシンプルな作り ◦ 物理演算などはしない • 開発・運用で便利な機能や特定のインフラ環境への対応は コア機能からは外している ◦ 例えば Kubernetes 環境を前提にするとローカル環境の構築が面倒 6
  7. prizm のコア機能 prizm Server
 クライアント
 Message
 Message
 Message
 Message
 Message


    Message
 Message
 クライアント・サーバー間でメッ セージを送り合う 7
  8. prizm のコア機能 prizm Server
 func OnChatMessage(...) { BroadcastChatMessage(...) } Message受信時の処理を

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

    9
  10. prizm の特徴 • コード生成 • モック環境 • 可観測性 • Kubernetes

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

    インフラ • サポート体制 • その他方針・考えていることなど 11
  12. コード生成 • クライアント・サーバーの開発を効率化するため CLI ツールによるコード生成を多用 ◦ プロジェクト全体の生成 ◦ メッセージ定義の生成 ◦

    リレーメッセージの生成 12
  13. プロジェクト生成 • CLI ツールでプロジェクトの雛形を作成 $ prizm new ... 13

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

    bot なども生成 14
  15. メッセージ定義とコード生成 • .proto ファイルをもとに C# / Go のコードを自動生成 ◦ メッセージ構造の定義

    ◦ メッセージ送信やメッセージ受信時のハンドラの実装に必要なスタブコード syntax = "proto3"; service GameService { rpc SendMessage() ... } message TestMessage { string body = 1; } GameService.cs gameservice.go 15
  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
  17. リレーメッセージの生成 • 部屋全体にそのままメッセージを転送(リレー)するメッセージの生成 • サーバー側にロジックが不要な場合の実装コストを減らせる ◦ 前述したようなやり方だとメッセージを増やすたびにサーバーの再ビルドが必要だった ◦ リレーメッセージを使えば クライアントのみの変更

    でメッセージを追加できる ChatMessage
 ChatMessage
 17
  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
  19. prizm の特徴 • コード生成 • モック環境 • 可観測性 • Kubernetes

    インフラ • サポート体制 • その他方針・考えていることなど 19
  20. prizm のモック環境 • クライアントエンジニアのみでマルチプレイを作りたい!という 要求をもとに常設のモック用サーバーを用意 ◦ ゲーム開発初期のモックを開発する段階を意識 ◦ Photon Cloud

    のような感覚で使える • モック環境では前述のリレーメッセージを利用 ◦ リレーメッセージの「クライアントのみの変更でメッセージを追加できる」特性を利用 ◦ 開発が進んで専用の prizm サーバーを立てたときにも クライアント側の実装をそのまま使える 20
  21. prizm のモック環境 prizm mock server prizmチーム
 ゲーム開発チーム
 ① モック準備依頼
 21

  22. prizm のモック環境 prizm mock server prizmチーム
 ゲーム開発チーム
 ① モック準備依頼
 ②

    namespace追加
 22
  23. prizm のモック環境 prizm mock server prizmチーム
 ゲーム開発チーム
 ① モック準備依頼
 ②

    namespace追加
 ③ 利用
 23
  24. prizm の特徴 • コード生成 • モック環境 • 可観測性 • Kubernetes

    インフラ • サポート体制 • その他方針・考えていることなど 24
  25. prizm の可観測性 • 実装のミスやパフォーマンスの問題を気づきやすくするため、 以下の方法で指標を公開 ◦ Prometheus exporter(メトリクス) ◦ Opencensus

    Tracing(分散トレース) ◦ pprof / Cloud Profiler(プロファイラ) • 1月に prizm に Cloud Profiler という GCP が提供しているプロファイラを 導入したときの話を発表しているので良かったらそちらも見てください 25
  26. prizm の可観測性 26

  27. prizm の特徴 • コード生成 • モック環境 • 可観測性 • Kubernetes

    インフラ • サポート体制 • その他方針・考えていることなど 27
  28. prizm の動作環境 • ローカル環境 ◦ Go でビルド可能な環境であれば OK ◦ Windows,

    Mac, Linux, … • dev, stg, 本番環境 ◦ Kubernetes や Agones を活用できるようにしている ▪ Agones: Kubernetes 上でゲームのリアルタイム通信のような ステートフルなサーバーを管理できるようにしてくれる OSS ◦ 次の発表でここらへんを詳しく発表してもらいます 28
  29. Kubernetes 環境での prizm • prizm と Agones SDK との間で必要なやりとりを prizm

    開発チームでライブラリ化 prizm server
 Agones
 sidecar
 Agones SDKとの やりとりをライブラリ化 29
  30. クラウド環境でのログ出力 • ターミナル上では プレーンテキストで出力 ◦ 目で追いやすいように している • クラウド環境では JSON

    で出力 ◦ GCP Cloud Logging で 処理しやすくしている 30
  31. prizm の特徴 • コード生成 • モック環境 • 可観測性 • Kubernetes

    インフラ • サポート体制 • その他方針・考えていることなど 31
  32. prizm のサポート体制 • prizm の開発や prizm を用いたゲーム開発をサポートするチームを編成 • prizm や

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

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

  35. prizm の特徴 • コード生成 • モック環境 • 可観測性 • Kubernetes

    インフラ • サポート体制 • その他方針・考えていることなど 35
  36. 複数のプレイヤーを prizm へ接続させる • マルチプレイを提供するためにはサーバーやルームを用意するだけでは だめで、用意したルームに他のプレイヤーが入れるようにする必要がある • これを実現するためには以下のものが必要 ◦ 存在するサーバー

    / 部屋を見つける機能( Service Discovery?) ◦ プレイヤーを適切な部屋に紐付ける機能(マッチング) • prizm 自体にはこれらの機能を載せず、 API サーバーなどで実装するようにしている ◦ prizm の機能をシンプルにするため 36
  37. 新しく部屋を作ったとき prizm-server API Server (PHP) Database <IP:port> 等の部屋情報を DBに保存 37

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

    38
  39. 既存の部屋に参加するとき prizm-server API Server (PHP) マルチの部屋に参加した い 部屋番号: 12345 Database

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

    12345 の部屋データ(IP:Port) を取得 40
  41. 設計方針 • 自前実装はなるべく避け、広く使われている実装があればそれを使う ◦ JWT(認証) ◦ TLS(暗号化) ◦ Prometheus(メトリクス) •

    パフォーマンスよりも使いやすさを重視 ◦ パフォーマンスを軽視しているわけではないです ▪ 使い勝手の悪くなるパフォーマンスチューニングはしない、といった感じ ◦ コード以外の面でも使いやすさを追求 ▪ ドキュメントやサポートを充実させて間違った使い方を防ぐ ▪ プロファイリングを充実させて実装ミスに素早く気付けるようにする 41
  42. 設計方針 • テストをちゃんとやる ◦ テスト内で実際に TCP / UDP サーバーを立てて通信してみる ◦

    パケットの損失や遅延、順序入れ替えをシミュレートする ◦ C# クライアントと Go サーバーでの結合テストもする ◦ make test ですべてのテストが実行されるし、 CI でもテストが回る ⇒新機能追加時・リファクタリング時の安心感につながる! 42
  43. 現状の課題 • 依存ライブラリの追従 ◦ Kubernetes 関連は動きが早いのでついていくのが大変 • 異常系を考慮した設計の共有 ◦ 切断などからの復帰やサーバー障害への考慮など

    ◦ ゲームの仕様によってやりたいことが変わってくるのでライブラリ化が難しい • コロプラのメイン言語(PHP)と異なる言語での開発 ◦ ゲーム開発チームへのレクチャー・サポートが必要 ◦ ドキュメントを頑張って書く、積極的にサポートしにいく • 運用が始まったばかり ◦ 実際に運用していく中で知見を貯めていく、課題を解決していく 43
  44. まとめ • コロプラ内製のリアルタイム通信基盤 prizm を紹介 ◦ 合わせてコード生成やクラウド環境への対応など開発・運用に必要なものも紹介 • 優れた設計・パフォーマンスよりも使う側にとっての分かりやすさを重視 ◦

    最終的なゴールはゲームを作って良いものにしていくこと • 技術力だけでなく使い手側の気持ちになることが大事 ◦ ドキュメント ◦ サポート体制 44