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
1
6.9k
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
190
linter for your team rule
mizkei
3
2.4k
Other Decks in Programming
See All in Programming
Kanzawa.rbのLT大会を支える技術の裏側を変更する Ruby on Rails + Litestream 編
muryoimpl
0
120
Lookerは可視化だけじゃない。UIコンポーネントもあるんだ!
ymd65536
1
140
非ブラウザランタイムとWeb標準 / Non-Browser Runtimes and Web Standards
petamoriken
0
450
Fibonacci Function Gallery - Part 2
philipschwarz
PRO
0
230
月刊 競技プログラミングをお仕事に役立てるには
terryu16
1
1.3k
自動で //nolint を挿入する取り組み / Gopher's Gathering
utgwkk
1
170
SwiftUIで単方向アーキテクチャを導入して得られた成果
takuyaosawa
0
140
Azure AI Foundryのご紹介
qt_luigi
1
260
Moscow Python Meetup №97. Константин Крестников (Техлид команды GigaChain (SberDevices)). GigaChain: Новые инструменты для разработки агентов на примере агента техподдержки
moscowdjango
PRO
0
100
Immutable ActiveRecord
megane42
0
120
【PHP】破壊的バージョンアップと戦った話〜決断と説得
satoshi256kbyte
0
100
ErdMap: Thinking about a map for Rails applications
makicamel
1
1.1k
Featured
See All Featured
How STYLIGHT went responsive
nonsquared
96
5.3k
The Straight Up "How To Draw Better" Workshop
denniskardys
232
140k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
33
2k
Practical Orchestrator
shlominoach
186
10k
RailsConf 2023
tenderlove
29
980
Fireside Chat
paigeccino
34
3.2k
Building Your Own Lightsaber
phodgson
104
6.2k
What’s in a name? Adding method to the madness
productmarketing
PRO
22
3.3k
Reflections from 52 weeks, 52 projects
jeffersonlam
348
20k
The Cult of Friendly URLs
andyhume
78
6.2k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
8
1.3k
It's Worth the Effort
3n
184
28k
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は楽しい • 標準パッケージで大体問題ない ◦ もちろん便利なパッケージは使う ◦ バージョンを気にしたり、そのパッケージの特殊な書き方を 覚えないといけない大きなフレームワークには依存しなくてもよい
• チームが大きくても開発の速度が落ちにくい