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
7.1k
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
NIKKEI Tech Talk#38
cipepser
0
400
ドメイン駆動設計のエッセンス
masuda220
PRO
15
7.5k
フロントエンド開発のためのブラウザ組み込みAI入門
masashi
7
3.7k
「10分以内に機能を消せる状態」 の実現のためにやっていること
togishima
1
110
チームのテスト力を総合的に鍛えてシフトレフトを推進する/Shifting Left with Software Testing Improvements
goyoki
4
2k
CSC509 Lecture 07
javiergs
PRO
0
260
Eloquentを使ってどこまでコードの治安を保てるのか?を新人が考察してみた
itokoh0405
0
3k
AI時代に必須!状況言語化スキル / ai-context-verbalization
minodriven
2
340
The Past, Present, and Future of Enterprise Java
ivargrimstad
0
290
三者三様 宣言的UI
kkagurazaka
0
360
予防に勝る防御なし(2025年版) - 堅牢なコードを導く様々な設計のヒント / Growing Reliable Code PHP Conference Fukuoka 2025
twada
PRO
28
8.6k
GitHub Copilotを使いこなせ!/mastering_github_copilot!
kotakageyama
2
780
Featured
See All Featured
[RailsConf 2023 Opening Keynote] The Magic of Rails
eileencodes
31
9.7k
4 Signs Your Business is Dying
shpigford
186
22k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
132
19k
Build your cross-platform service in a week with App Engine
jlugia
234
18k
Producing Creativity
orderedlist
PRO
348
40k
Six Lessons from altMBA
skipperchong
29
4.1k
Principles of Awesome APIs and How to Build Them.
keavy
127
17k
How GitHub (no longer) Works
holman
315
140k
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
No one is an island. Learnings from fostering a developers community.
thoeni
21
3.5k
Why You Should Never Use an ORM
jnunemaker
PRO
60
9.6k
How to Think Like a Performance Engineer
csswizardry
28
2.3k
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は楽しい • 標準パッケージで大体問題ない ◦ もちろん便利なパッケージは使う ◦ バージョンを気にしたり、そのパッケージの特殊な書き方を 覚えないといけない大きなフレームワークには依存しなくてもよい
• チームが大きくても開発の速度が落ちにくい