云原生项目实践DevOps(GitOps)+K8S+BPF+SRE,从0到1使用Golang开发生产级麻将游戏服务器—第2篇
搭建游戏服务器脚手架 & 快速上手开发
系列文章
介绍
这将是一个完整的,完全践行 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
基础回顾
Go Modules
我的本地环境:
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'
。
用法:
go mod <command> [arguments]
-
download
将模块下载到本地缓存 -
edit
通过工具或脚本编辑 go.mod -
graph
打印模块依赖图 -
init
在当前目录中初始化新模块 -
tidy
添加缺少的内容并删除未使用的模块 -
vendor
制作第三方依赖包(vendored)的依赖副本 -
verify
验证依赖项具有预期的内容 -
why
解释为什么需要软件包(packages)或模块(modules)
使用 “go help mod <命令>”
可获取有关命令的更多信息。
脚手架基本结构
├── 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()
- 根据配置
config.toml
,打印相关启动信息:- 当前游戏服务器版本
- 是否强制更新
- 当前心跳时间间隔
- 业务功能配置(如:
房卡设置
) - 注册游戏业务逻辑(Nano Components)
- 玩家申请加入俱乐部
- 创建一张桌子
- 根据桌号返回牌桌数据
- 设置桌号对应的牌桌数据
- 检查登录玩家关闭应用之前是否正在游戏
- 网络断开后, 重新连接网络
- 网络断开后, 如果ReConnect后发现当前正在房间中, 则重新进入, 桌号是之前的桌号
- 应用退出后重新进入房间
- 理牌结束
- 定缺
- 有玩家请求解散房间
- 玩家语音消息
- 处理踢出玩家和重置玩家消息(来自http)
- ……
- 注册游戏数据包加密管道
-
pipeline
(Inbound
&Outbound
)
-
- 根据设置,启动游戏服务器(Nano server)
WithPipeline
WithHeartbeatInterval
WithLogger
WithSerializer
WithComponents
- ……
启动 Web Server
web.Startup()
- 数据库设置(
XORM
)-
DSN
数据库连接字符串 -
ShowSQL
是否显示生产的 Sql 语句 -
MaxIdleConn
最大空闲连接 -
MaxOpenConn
最大打开连接 < MaxIdleConn -
syncSchema
xorm 同步 model 到数据库表结构 -
async write channel
数据异步插入管道,持久化数据 -
async update channel
数据异步更新管道,持久化数据 - 定时
ping
数据库, 保持连接池连接
-
- 启用白名单(风控相关功能)
- API 服务注册(业务相关接口)
- 登录
- 注册人数
- 活跃人数
- 同时在线人、桌数
- 留存
- 房卡消耗
- 重置玩家未完成房间状态
- 设置房卡消耗
- 消息广播
- 踢人
- 在线信息
- 玩家充值
- 玩家信息查询
- ……
- 是否启用
http.ListenAndServeTLS
- Graceful Shutdown(优雅退出,程序关闭前可做一下清理工作)
syscall.SIGINT
syscall.SIGQUIT
syscall.SIGKILL
同时,在 kubernetes
中运行微服务时。我们需要处理 kubernetes
发出的终止信号。这样做的正确方法是:
- 监听
SIGINT
,SIGTERM
- 收到信号后,将服务置于不健康模式(
/health
路由应返回状态码4xx
,5xx
) - 在关闭之前添加宽限期,以允许
kubernetes
将您的应用程序从负载均衡器中移除 - 关闭服务器和所有打开的连接
- Shutdown
脑图
快速上手开发
Docker Compose 本地一键启动 MySql
上篇已有详细介绍,这里就不赘述了哈。
云原生项目实践DevOps(GitOps)+K8S+BPF+SRE,从0到1使用Golang开发生产级麻将游戏服务器—第1篇
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
go get -u github.com/cosmtrek/air
开发(项目根目录):
air
使用 VSCode-Go 插件调试程序
安装 Delve
- 打开
命令面板
(Windows/Linux: Ctrl+Shift+P; OSX: Shift+Command+P),
选择Go: Install/Update Tools,
然后选择dlv
开始调试
- 打开你想要调试的
package main
源文件(source file
)或测试文件(test file
) - 使用以下任何一种方式进行调试:
- 打开
命令面板
, 选择Debug: Start Debugging
,然后选择Go
。 - 打开调试窗口(Windows/Linux: Ctrl+Shift+D; OSX: Shift+Command+D),然后点击
Run and Debugs
,然后选择Go
。 - 从主菜单选择 Run > Start Debugging
- 打开
我是为少
微信:uuhells123
公众号:黑客下午茶
加我微信(互相学习交流),关注公众号(获取更多学习资料~)