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.8k
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
180
linter for your team rule
mizkei
3
2.3k
Other Decks in Programming
See All in Programming
外部システム連携先が10を超えるシステムでのアーキテクチャ設計・実装事例
kiwasaki
1
240
[PyCon Korea 2024 Keynote] 커뮤니티와 파이썬, 그리고 우리
beomi
0
120
Universal Linksの実装方法と陥りがちな罠
kaitokudou
1
240
Quine, Polyglot, 良いコード
qnighy
4
550
Identifying User Idenity
moro
6
8.7k
macOS でできる リアルタイム動画像処理
biacco42
8
2.2k
Kotlin2でdataクラスの copyメソッドを禁止する/Data class copy function to have the same visibility as constructor
eichisanden
1
160
Why Spring Matters to Jakarta EE - and Vice Versa
ivargrimstad
0
1.2k
弊社の「意識チョット低いアーキテクチャ」10選
texmeijin
5
24k
Kaigi on Rails 2024 - Rails APIモードのためのシンプルで効果的なCSRF対策 / kaigionrails-2024-csrf
corocn
5
3.6k
CSC509 Lecture 08
javiergs
PRO
0
110
GitHub Actionsのキャッシュと手を挙げることの大切さとそれに必要なこと
satoshi256kbyte
5
410
Featured
See All Featured
How to Think Like a Performance Engineer
csswizardry
20
1.1k
A better future with KSS
kneath
238
17k
Mobile First: as difficult as doing things right
swwweet
222
8.9k
Building Better People: How to give real-time feedback that sticks.
wjessup
363
19k
Designing the Hi-DPI Web
ddemaree
280
34k
Music & Morning Musume
bryan
46
6.1k
The Language of Interfaces
destraynor
154
24k
Optimising Largest Contentful Paint
csswizardry
33
2.9k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
92
16k
Fashionably flexible responsive web design (full day workshop)
malarkey
404
65k
Navigating Team Friction
lara
183
14k
Keith and Marios Guide to Fast Websites
keithpitt
408
22k
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は楽しい • 標準パッケージで大体問題ない ◦ もちろん便利なパッケージは使う ◦ バージョンを気にしたり、そのパッケージの特殊な書き方を 覚えないといけない大きなフレームワークには依存しなくてもよい
• チームが大きくても開発の速度が落ちにくい