雲原生專案實踐DevOps(GitOps)+K8S+BPF+SRE,從0到1使用Golang開發生產級麻將遊戲伺服器—第2篇
阿新 • • 發佈:2021-02-04
![](https://img2020.cnblogs.com/blog/436453/202102/436453-20210204084801104-2107763893.png)
## 搭建遊戲伺服器腳手架 & 快速上手開發
### 系列文章
1. [雲原生專案實踐DevOps(GitOps)+K8S+BPF+SRE,從0到1使用Golang開發生產級麻將遊戲伺服器—第1篇](https://mp.weixin.qq.com/s/Jyq_A1vehrnMwv6AdOtQ1w)
### 介紹
這將是一個完整的,完全踐行 `DevOps/GitOps` 與 `Kubernetes` 上雲流程的 Golang 遊戲伺服器開發的系列教程。
這個系列教程是對開源專案 `Nanoserver` 的完整拆解,旨在幫助大家快速上手 Golang(遊戲)伺服器後端開發。通過實踐去理解 Golang 開發的精髓 —— `Share memory by communication(通過通訊共享記憶體)`。
同時這個專案可能還會涉及到 `Linux` 效能調優(BPF相關的工具)和系統保障(SRE)的相關的工作。
### 腳手架專案
* 腳手架是基於 `nanoserver` 抽出來的,旨在幫助大家快速理解這個 `Mahjong Server` 是如何搭出來的。
* 我們先`單體架構`理解整體業務 -> 然後再 `分散式 Nano Server` + `微服務` 改造(Step-by-Step)。
* Demo:[go-mahjong-server](https://github.com/Hacker-Linner/go-mahjong-server)
## 基礎回顧
### Go Modules
**我的本地環境:**
```sh
go version
# go version go1.14.14 darwin/amd64
```
**`go mod help`**
`Go mod` 提供對 `modules` 操作的訪問。
請注意,所有 `go` 命令都內建了對 `modules` 的支援,
不只是`'go mod'`。例如,日常的依賴關係新增(adding),刪除(removing),升級(upgrading)和降級(downgrading)應該使用 `'go get'` 完成。
有關 `module` 功能的概述,請參見 `'go help modules'`。
用法:
```sh
go mod [arguments]
```
* `download` 將模組下載到本地快取
* `edit` 通過工具或指令碼編輯 go.mod
* `graph` 列印模組依賴圖
* `init` 在當前目錄中初始化新模組
* `tidy` 新增缺少的內容並刪除未使用的模組
* `vendor` 製作第三方依賴包(vendored)的依賴副本
* `verify` 驗證依賴項具有預期的內容
* `why` 解釋為什麼需要軟體包(packages)或模組(modules)
使用 `“go help mod <命令>”` 可獲取有關命令的更多資訊。
![](https://img2020.cnblogs.com/blog/436453/202102/436453-20210204084832353-1060376699.png)
## 腳手架基本結構
```sh
├── configs # 配置檔案
│ ├── config.toml
├── db # 資料庫(xorm)相關
│ ├── model
│ │ ├── struct.go # database schema
│ ├── const.go
│ ├── logger.go
│ ├── model.go
├── internal
│ ├── game # 遊戲伺服器(Nano server)
│ │ ├── crypto.go
│ │ ├── game.go
│ │ ├── manager.go
│ ├── web # web 伺服器(提供 API)
│ │ ├── web.go
├── pkg # 專案基礎包
│ ├── algoutil # 常用工具函式
│ │ ├── algoutil.go
│ ├── crypto # md5 rsa sha1 x509 base64 相關工具
│ │ ├── crypto.go
│ ├── errutil # 遊戲伺服器中錯誤碼和錯誤資訊統一管理
│ │ ├── code.go
│ │ ├── errutil.go
│ ├── whitelist # 白名單驗證工具函式
│ │ ├── white_list.go
├── protocol # 協議(放所有遊戲)
│ ├── web.go
├── main.go # 入口
```
## Mahjong Server 基礎啟動流程
**Everything start with `main.go`**
### 載入配置檔案
**`configs/config.toml`**
* `core` 核心基礎配置
* `webserver` web 伺服器配置
* `game-server` 遊戲伺服器配置
* `database` 資料庫配置
* `whitelist` 白名單配置
* `update` 客戶端更新配置
### 啟動 Game Server
**`game.Startup()`**
1. 根據配置`config.toml`,列印相關啟動資訊:
* 當前遊戲伺服器版本
* 是否強制更新
* 當前心跳時間間隔
2. 業務功能配置(如:`房卡設定`)
3. 註冊遊戲業務邏輯(Nano Components)
* 玩家申請加入俱樂部
* 建立一張桌子
* 根據桌號返回牌桌資料
* 設定桌號對應的牌桌資料
* 檢查登入玩家關閉應用之前是否正在遊戲
* 網路斷開後, 重新連線網路
* 網路斷開後, 如果ReConnect後發現當前正在房間中, 則重新進入, 桌號是之前的桌號
* 應用退出後重新進入房間
* 理牌結束
* 定缺
* 有玩家請求解散房間
* 玩家語音訊息
* 處理踢出玩家和重置玩家訊息(來自http)
* ……
4. 註冊遊戲資料包加密管道
* `pipeline`(`Inbound` & `Outbound`)
5. 根據設定,啟動遊戲伺服器(Nano server)
* `WithPipeline`
* `WithHeartbeatInterval`
* `WithLogger`
* `WithSerializer`
* `WithComponents`
* ……
### 啟動 Web Server
**`web.Startup()`**
1. 資料庫設定(`XORM`)
* `DSN` 資料庫連線字串
* `ShowSQL` 是否顯示生產的 Sql 語句
* `MaxIdleConn` 最大空閒連線
* `MaxOpenConn` 最大開啟連線 < MaxIdleConn
* `syncSchema` xorm 同步 model 到資料庫表結構
* `async write channel` 資料非同步插入管道,持久化資料
* `async update channel` 資料非同步更新管道,持久化資料
* 定時 `ping` 資料庫, 保持連線池連線
2. 啟用白名單(風控相關功能)
3. API 服務註冊(業務相關介面)
* 登入
* 註冊人數
* 活躍人數
* 同時線上人、桌數
* 留存
* 房卡消耗
* 重置玩家未完成房間狀態
* 設定房卡消耗
* 訊息廣播
* 踢人
* 線上資訊
* 玩家充值
* 玩家資訊查詢
* ……
4. 是否啟用 `http.ListenAndServeTLS`
5. Graceful Shutdown(優雅退出,程式關閉前可做一下清理工作)
* `syscall.SIGINT`
* `syscall.SIGQUIT`
* `syscall.SIGKILL`
同時,在 `kubernetes` 中執行微服務時。我們需要處理 `kubernetes` 發出的終止訊號。這樣做的正確方法是:
1. 監聽 `SIGINT`, `SIGTERM`
2. 收到訊號後,將服務置於不健康模式(`/health` 路由應返回狀態碼 `4xx`,`5xx`)
3. 在關閉之前新增寬限期,以允許 `kubernetes` 將您的應用程式從負載均衡器中移除
4. 關閉伺服器和所有開啟的連線
5. Shutdown
### 腦圖
![](https://img2020.cnblogs.com/blog/436453/202102/436453-20210204084852837-138364759.png)
## 快速上手開發
### Docker Compose 本地一鍵啟動 MySql
上篇已有詳細介紹,這裡就不贅述了哈。
[雲原生專案實踐DevOps(GitOps)+K8S+BPF+SRE,從0到1使用Golang開發生產級麻將遊戲伺服器—第1篇](https://mp.weixin.qq.com/s/Jyq_A1vehrnMwv6AdOtQ1w)
```sh
docker-compose -f docker-compose.mysql.5.7.yaml up # -d
docker-compose -f docker-compose.mysql.5.7.yaml down
```
### 使用 Air 進行本地開發
☁️ Live reload for Go apps
```sh
go get -u github.com/cosmtrek/air
```
開發(專案根目錄):
```sh
air
```
![](https://img2020.cnblogs.com/blog/436453/202102/436453-20210204084912879-970283832.png)
### 使用 VSCode-Go 外掛除錯程式
[VSCode-Go Debugging](https://github.com/golang/vscode-go/blob/master/docs/debugging.md)
**安裝 `Delve`**
1. 開啟 `命令面板`(Windows/Linux: Ctrl+Shift+P; OSX: Shift+Command+P),
選擇 `Go: Install/Update Tools,` 然後選擇 `dlv`
**開始除錯**
1. 開啟你想要除錯的 `package main` 原始檔(`source file`)或測試檔案(`test file`)
2. 使用以下任何一種方式進行除錯:
* 開啟 `命令面板`, 選擇 `Debug: Start Debugging`,然後選擇 `Go`。
* 開啟除錯視窗(Windows/Linux: Ctrl+Shift+D; OSX: Shift+Command+D),然後點選 `Run and Debugs`,然後選擇 `Go`。
* 從主選單選擇 **Run > Start Debugging**
![](https://img2020.cnblogs.com/blog/436453/202102/436453-20210204084928093-1521923726.png)
```
我是為少
微信:uuhells123
公眾號:黑客下午茶
加我微信(互相學習交流),關注公眾號(獲取更多學習資料~