Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Goでゲームサーバーを実装して考えたこと / game server in go
Search
mizkei
May 14, 2018
Programming
2
7k
Goでゲームサーバーを実装して考えたこと / game server in go
IGDA日本 ゲームサーバ勉強会 #8
https://techplay.jp/event/666753
登壇した資料のようなメモ
mizkei
May 14, 2018
Tweet
Share
More Decks by mizkei
See All by mizkei
About: Go Module Proxy: Life of a query
mizkei
0
200
linter for your team rule
mizkei
3
2.4k
Other Decks in Programming
See All in Programming
新メンバーも今日から大活躍!SREが支えるスケールし続ける組織のオンボーディング
honmarkhunt
3
6k
プロダクト志向なエンジニアがもう一歩先の価値を目指すために意識したこと
nealle
0
130
Hypervel - A Coroutine Framework for Laravel Artisans
albertcht
1
110
WindowInsetsだってテストしたい
ryunen344
1
240
20250628_非エンジニアがバイブコーディングしてみた
ponponmikankan
0
660
XP, Testing and ninja testing
m_seki
3
230
『自分のデータだけ見せたい!』を叶える──Laravel × Casbin で複雑権限をスッキリ解きほぐす 25 分
akitotsukahara
2
620
Azure AI Foundryではじめてのマルチエージェントワークフロー
seosoft
0
160
#kanrk08 / 公開版 PicoRubyとマイコンでの自作トレーニング計測装置を用いたワークアウトの理想と現実
bash0c7
1
690
LT 2025-06-30: プロダクトエンジニアの役割
yamamotok
0
720
High-Level Programming Languages in AI Era -Human Thought and Mind-
hayat01sh1da
PRO
0
730
ニーリーにおけるプロダクトエンジニア
nealle
0
780
Featured
See All Featured
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
130
19k
Stop Working from a Prison Cell
hatefulcrawdad
270
21k
Embracing the Ebb and Flow
colly
86
4.7k
The Cost Of JavaScript in 2023
addyosmani
51
8.5k
Principles of Awesome APIs and How to Build Them.
keavy
126
17k
Art, The Web, and Tiny UX
lynnandtonic
299
21k
KATA
mclloyd
30
14k
Facilitating Awesome Meetings
lara
54
6.4k
Side Projects
sachag
455
42k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
3.9k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
15
1.5k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
5
260
Transcript
Goでゲームサーバー実装をして 考えたこと Goを書いて楽しかった思い出
目次 • 自己紹介 • Go • Goとカヤック • Goで開発したサーバーの説明 •
Goの実装で選択したこと • まとめ
自己紹介 • 名前 ◦ 水野 敬太 (@mizkei11) • 所属 ◦
面白法人カヤック • 職種 ◦ サーバーサイドエンジニア
Go
Go Programming Language 下記のような特徴を持つプログラミング言語 • 静的型付け • コンパイルされる • インタプリタ言語のような手軽さ
• 並行処理を単純に扱うための仕組み • 意識することなくマルチコアを使い切る
CLIツール開発におけるGo • ツールの配布が容易 ◦ クロスコンパイルが簡単 ◦ コンパイル早い • ふわっと書いてもそれなりに高速に動作する
Web開発におけるGo • 標準パッケージで簡単にサーバーが書ける • スレッドやプロセスなど考えなくて良い ◦ Goが勝手にCPUを使い切ってくれる
チーム開発におけるGo • 不要な作業の削減 ◦ gofmt, golintによって一つの書き方に収束する • シンプルな文法 ◦ 関数を辿っていけば、大体全部わかる
▪ 魔法のような動作はない ▪ GoはGoで書かれているので標準パッケージの中までわかる ◦ ただし、コード量は多くなる
Goとカヤック
Go言語を推進していく宣言 • 「カヤックは、Go言語を積極的に推進していきます」 ◦ https://www.kayac.com/news/2014/07/golang 社内ツールやインフラ関連ツールは積極的にGoで書かれている (※無理に選択しているという意味ではない)
勉強会 • kamakura.go(in 横浜) ◦ https://connpass.com/event/87417/
Goで実装したゲー ムサーバーの説明
ゲームシステム概要 • PvP ◦ 対戦自体の通信は外部のサーバーを利用 • プレイヤーが集まって形成するグループ ◦ チャット、対戦の共有 •
対戦結果によるランキング ◦ 上位者の報酬配布
API • HTTPのGET/POSTを受け取り、JSONを返す
定期実行処理 • イベントとして発行されるタスクを複数台のサーバーで処理 ◦ 通常のリクエストから発生するバックグラウンドタスクも 同じ流れで処理される
管理画面 • HTMLのページ • ユーザー情報の管理 ◦ 行動履歴、アカウントの引き継ぎ、個別メッセージの送信、 課金履歴など • 運営からのお知らせ管理
マッチング • スコアの近い、待ち時間の長いユーザー • バックグラウンドタスクとして実行して、 マッチング完了でクライアント側にマッチング情報を通信
Goの実装で選択 したこと
Goにおける色々な選択 • カヤックのゲーム開発ですべてGoによる実装は初めて ◦ packageや構成についていろいろ考えなければならない
Web Application Framework • GoのWAF ◦ echo (https://github.com/labstack/echo) ◦ Gin
(https://github.com/gin-gonic/gin) ◦ Goji (https://github.com/zenazn/goji) ◦ ... 他にもたくさん
WAFは使わなかった • net/http ◦ 標準パッケージ ◦ だいたいこれで解決できる ◦ WAFを使わないからと記述量が多くなるわけではない ◦
ミドルウェアも普通に書けば良い ▪ func(http.Handler) http.Handlerとか用意するだけ
ハンドラー周辺で使ったpackage • https://github.com/gorilla/schema ◦ リクエストのパラメータをパースしてstructに詰め込む • https://github.com/julienschmidt/httprouter ◦ 管理画面はhtmlで遷移していくため、パスのパラメータを利用したい
ハンドラーの自動生成 • Baal ◦ 「IDL「Baal」について」 ▪ http://techblog.kayac.com/unity_advent_calendar_2016_20 ◦ クライアントと通信するパス/リクエスト/レスポンスの内容を定義 ▪
型や文字列の長さ、リストの長さなども記述可能
• ほとんど自動生成 ◦ パスパターン ◦ リクエスト/レスポンスのstruct ◦ リクエストの内容をstructに詰め込む ◦ 値の範囲、文字列の長さ、リストの長さのバリデーション
• 手で書かないといけない処理 ◦ リクエストのstructの値をモデルのメソッドに値を渡す ◦ モデルのメソッドの返り値をレスポンスのstructに詰め込む ハンドラーの自動生成
自動生成した副作用 • リクエスト/レスポンスのstructのdecode/encodeがある ◦ apiのテストコードを書く際にテストケース作成が楽 ◦ デバッグ用のシナリオをGoで書くのが楽 ◦ 負荷試験時のシナリオ作成が楽
ORM • GoのORM ◦ https://github.com/jinzhu/gorm ◦ https://github.com/go-gorp/gorp ◦ https://github.com/go-xorm/xorm ◦
… やっぱりたくさんある
ORM使わなかった • 実行されるクエリがどうなるのかわからない • ライブラリである以上、interface{}を扱うしかない場合がある • ORMの気持ちを考えるのは非常に難しい
DB処理周りで利用したパッケージ • https://github.com/Masterminds/squirrel ◦ クエリビルダー ◦ sqlをそのまま書くよりはGoの中の型として扱える部分が増える ▪ でも、そんなに変わらないので普通に sqlも書いている
DBへのクエリ処理の自動生成 • sqlファイルからrowのstruct、特定のクエリの自動生成 ◦ https://github.com/schemalex/schemalex でsqlをパース • マスターデータはメモリ上にキャッシュ ◦ 自動生成されるselectなどの処理の裏でメモリから取ってくる
DBへのクエリ処理の自動生成 • Insert/Update/Refetch ◦ 単純な操作達 • RefetchForUpdate ◦ 自動生成でrowにIsForUpdate() boolを作っている
• ScanRows/ScanRow ◦ rowに値詰め込む処理は自動
DBへのクエリ処理の自動生成 • Primary Key、Uniqueなものはメソッドを用意 ◦ 例)userテーブル: Primary Key id 、Unique
(name, number) ▪ func (t User) FindByID(id int64) (*row.User, error) ▪ func (t User) FindByNameNumber(name string, number int64) (*row.User, error)
DBへのクエリ処理の自動生成 • eachRowsFast ◦ 条件を満たす全rowを順に処理していくためのメソッド ◦ func([]*row.User) errorみたいなメソッドを渡して、 大量のrowを使った処理などをおこなう •
selectWithCursorID ◦ 主に管理画面用にカーソルを使ってページングするためのメソッド ◦ 前後ページのIDを返したり、並び替えをおこなう
DBへのクエリ処理の自動生成 • マスターデータのキャッシュ ◦ Primary Key、Uniqueに対してGoのmapを生成 ◦ FindByIDとかの裏側でmapから取得
DBへのクエリ処理の自動生成 • 自動のScanは全部の値を取ってきてしまう ◦ 通信のサイズ、メモリなどの無駄 ◦ 仕方ないので、もう手で書く ▪ 余分な取得が2,3カラム程度ならもう全部取ってしまうので、多くはない
ファイルをバイナリに詰め込むpackage • ファイル1個にまとまるので配置が楽になる ◦ https://github.com/jessevdk/go-assets ◦ https://github.com/jteeuwen/go-bindata ▪ これは消えたリポジトリから forkされたリポジトリ
詰め込むpackage使いませんでした • ECSでサービスを動かしているため、dockerのimageの中に ファイル配置すれば良い ◦ そんなに1個のファイルになっても嬉しくなさそう • 開発の途中でgo-bindataのリポジトリが消えた
チームでの開発 • サーバーサイドは5人で開発 • レビュー ◦ コードは他の4人すべてのレビューを通らないとマージされない
コードの書きやすさ • 特殊な書き方ができない ◦ コードとしての書き方にほとんど迷わない
コードの読みやすさ • シンプルな文法 ◦ 読みにくいコードはほぼ書けない • gofmt/golint/govet ◦ ロジックにかかわらないところは何も考えなくて良い レビューする人が多くても開発の速度をあまり下げない
楽しかったこと(個人の感想) • Go(とアプリ)のことだけ考えていることができる ◦ フレームワークの{waf}.Contextや使い方やDocsは気にしたくない ◦ ORMの気持ちも考えていたくない ▪ いつ消えるかもいつ気持ちが変わるかもわからない
まとめ • Goは楽しい • 標準パッケージで大体問題ない ◦ もちろん便利なパッケージは使う ◦ バージョンを気にしたり、そのパッケージの特殊な書き方を 覚えないといけない大きなフレームワークには依存しなくてもよい
• チームが大きくても開発の速度が落ちにくい