探索 Golang 云原生游戏服务器开发,硬核实战之调试 NanoServer 生产级麻将游戏服务器

本文涉及的产品
RDS MySQL DuckDB 分析主实例,集群系列 4核8GB
简介: 探索 Golang 云原生游戏服务器开发,硬核实战之调试 NanoServer 生产级麻将游戏服务器

介绍



这是一个系列


  1. 探索 Golang 云原生游戏服务器开发,5 分钟上手 Nano 游戏服务器框架 | https://juejin.im/post/6870388583019872270 
  2. 探索 Golang 云原生游戏服务器开发,根据官方示例实战Gorilla WebSocket的用法 | https://juejin.im/post/6872641375297339399
  3. 探索 Golang 云原生游戏服务器开发,Nano 内置分布式游戏服务器方案测试用例 | https://juejin.im/post/6877028133116706823
  4. 探索 Golang 云原生游戏服务器开发,Nano 分布式(集群)示例(Distributed Chat) | https://juejin.im/post/6878706308682350605


示例仓库



服务器


编写 Dockerfile.dev


FROM golang:1.14
WORKDIR /workspace
# 阿里云
RUN go env -w GO111MODULE=on
RUN go env -w GOPROXY=https://mirrors.aliyun.com/goproxy/,direct
# debug
RUN go get github.com/go-delve/delve/cmd/dlv
# live reload
RUN go get -u github.com/cosmtrek/air
# copy modules manifests
COPY go.mod go.mod
COPY go.sum go.sum
# cache modules
RUN go mod download


构建本地开发 Image


docker build -f Dockerfile.dev -t scmj-server:dev .


编写 mysql.cnf


[client]
port = 3306
socket = /var/run/mysqld/mysql.sock
default-character-set = utf8mb4
[mysql]
prompt="MySQL [\d]> "
no-auto-rehash
[mysqld]
port = 3306
socket = /var/run/mysqld/mysql.sock
basedir = /usr/local/mysql
datadir = /var/lib/mysql
pid-file = /var/run/mysqld/mysql.pid
user = mysql
bind-address = 0.0.0.0
server-id = 1
init-connect = 'SET NAMES utf8mb4'
character-set-server = utf8mb4
skip-name-resolve
#skip-networking
back_log = 300
max_connections = 497
max_connect_errors = 6000
open_files_limit = 65535
table_open_cache = 128
max_allowed_packet = 500M
binlog_cache_size = 1M
max_heap_table_size = 8M
tmp_table_size = 16M
read_buffer_size = 2M
read_rnd_buffer_size = 8M
sort_buffer_size = 8M
join_buffer_size = 8M
key_buffer_size = 4M
thread_cache_size = 8
query_cache_type = 1
query_cache_size = 8M
query_cache_limit = 2M
ft_min_word_len = 4
log_bin = mysql-bin
binlog_format = mixed
expire_logs_days = 7
log_error = /var/lib/mysql/mysql-error.log
slow_query_log = 1
long_query_time = 1
slow_query_log_file = /var/lib/mysql/mysql-slow.log
general_log = 1
general_log_file = /var/lib/mysql/mysql.log
performance_schema = 0
explicit_defaults_for_timestamp
#lower_case_table_names = 1
skip-external-locking
default_storage_engine = InnoDB
innodb_file_per_table = 1
innodb_open_files = 500
innodb_buffer_pool_size = 64M
innodb_write_io_threads = 4
innodb_read_io_threads = 4
innodb_thread_concurrency = 0
innodb_purge_threads = 1
innodb_flush_log_at_trx_commit = 2
innodb_log_buffer_size = 2M
innodb_log_file_size = 32M
innodb_log_files_in_group = 3
innodb_max_dirty_pages_pct = 90
innodb_lock_wait_timeout = 120
bulk_insert_buffer_size = 8M
myisam_sort_buffer_size = 8M
myisam_max_sort_file_size = 10G
myisam_repair_threads = 1
interactive_timeout = 28800wait_timeout = 28800[mysqldump]
quick
max_allowed_packet = 500M
[myisamchk]
key_buffer_size = 8M
sort_buffer_size = 8M
read_buffer = 4M
write_buffer = 4M


编写 docker-compose.mysql.yaml


version: "3.7"
services:
  db:
    image: mysql:5.7
    volumes:
      - db_data:/var/lib/mysql
      - ./mysql.cnf:/etc/mysql/my.cnf
    networks:
      - db_network
    ports:
      - "3306:3306"
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: 123456
      MYSQL_DATABASE: scmj
      MYSQL_USER: scmj
      MYSQL_PASSWORD: scmj
      TZ: Asia/Shanghai
  adminer:
    depends_on:
      - db
    image: adminer
    restart: always
    networks:
      - db_network
    ports:
      - 8086:8080
networks:
  db_network:
    driver: "bridge"
volumes:
    db_data: {}


一键启动 MySql 和 Adminer


docker-compose -f docker-compose.mysql.yaml up -d


登录 Adminer 管理界面


我们进入 http://localhost:8086,使用如下配置登录:


  • 系统:MySQL
  • 服务器:db
  • 用户名:root
  • 密码:123456
  • 数据库:scmj微信图片_20220610142044.png

微信图片_20220610142056.png

加入 launch.json


方便 VSCode 调试


{
  "version": "0.2.0",
  "configurations": [
      {
          "name": "nanoserver",
          "type": "go",
          "request": "launch",
          "mode": "remote",
          "remotePath":"/workspace/app",
          "port": 2345,
          "program": "${workspaceFolder}",
          "env": {
              "GO111MODULE":"on"
          },
          "args": [],
          "trace": "log",
          "showLog": true
      }
  ]
}


加入 .air.toml


# Config file for [Air](https://github.com/cosmtrek/air) in TOML format
# Working directory
# . or absolute path, please note that the directories following must be under root.
root = "."
tmp_dir = "tmp"
[build]
# Just plain old shell command. You could use `make` as well.
cmd = "go build -o ./tmp/main ."
# Binary file yields from `cmd`.
bin = "tmp/main"
# Customize binary.
full_bin = "APP_ENV=dev APP_USER=air ./tmp/main"
# Watch these filename extensions.
include_ext = ["go", "tpl", "tmpl", "html"]
# Ignore these filename extensions or directories.
exclude_dir = ["assets", "tmp", "vendor", "frontend/node_modules"]
# Watch these directories if you specified.
include_dir = []
# Exclude files.
exclude_file = []
# This log file places in your tmp_dir.
log = "air.log"
# It's not necessary to trigger build each time file changes if it's too frequent.
delay = 1000 # ms
# Stop running old binary when build errors occur.
stop_on_error = true
# Send Interrupt signal before killing process (windows does not support this feature)
send_interrupt = false
# Delay after sending Interrupt signal
kill_delay = 500 # ms
[log]
# Show log time
time = false
[color]
# Customize each part's color. If no color found, use the raw app log.
main = "magenta"
watcher = "cyan"
build = "yellow"
runner = "green"
[misc]
# Delete tmp directory on exit
clean_on_exit = true


编写 docker-compose.dev.yaml


version: "3.4"
services:
  scmj:
    image: scmj-server:dev
    command: >
      bash -c "cp ./go.mod ./go.sum app/
      && cd app/
      && ls -la
      && air -c .air.toml -d"
    volumes:
    - ./:/workspace/app
    networks:
      - db_network
    ports:
      - 12307:12307
      - 33251:33251
  scmj-debug:
    image: scmj-server:dev
    command: >
      bash -c "cp ./go.mod ./go.sum app/
      && cd app/
      && ls -la
      && dlv debug main.go --headless --log -l 0.0.0.0:2345 --api-version=2"
    volumes:
    - ./:/workspace/app
    networks:
      - db_network
    ports:
      - 12307:12307
      - 33251:33251
      - 2345:2345
    security_opt:
      - "seccomp:unconfined"
networks:
  db_network:
    driver: "bridge"


使用 docker-compose 调试


docker-compose -f docker-compose.dev.yaml up scmj-debug


使用 docker-compose 开发


docker-compose -f docker-compose.dev.yaml up scmj


因为 nanoserver 使用了 xorm,它会自动的根据定义的 model 生成数据库表 schema

微信图片_20220610142141.png

XORM 同步数据库

重新查看 Adminer,发现在 scmj 数据库中,xorm 已经为我们生成了表。微信图片_20220610142153.png

相关代码是:


....
func syncSchema() {
    database.StoreEngine("InnoDB").Sync2(
        new(model.Agent),
        new(model.CardConsume),
        new(model.Desk),
        new(model.History),
        new(model.Login),
        new(model.Online),
        new(model.Order),
        new(model.Recharge),
        new(model.Register),
        new(model.ThirdAccount),
        new(model.Trade),
        new(model.User),
        new(model.Uuid),
        new(model.Club),
        new(model.UserClub),
    )
}
...


客户端


这里我们直接使用 nanoserver 作者提供的 apk


安装安卓模拟器


这里我推荐网易的 MuMu模拟器。

微信图片_20220610142215.png

安装 APK


mahjong.apk,已经放到笔者修改过的项目中。这里我们使用多开助手,开4个空来血战。

image.gifimage.gif

客户端登录


我们点击微信登录。

微信图片_20220610142232.png微信图片_20220610142242.png

发现登录失败……


解决客户端登录失败问题


当然这问题,也好解决:


  1. 按作者所说那样,反编译 apk,找到 appConfig.luac,使用二进制编辑器改完服务器地址,然后重新打包。

微信图片_20220610142353.png

  1. 直接使用代理,如 Charles 进行请求地址转发。(本地调试服务器程序完全够了)


Charles 对客户端请求地址转发


使用 Map Remote 映射到你本机调试的地址就完全够了。

微信图片_20220610142411.pngimage.gif

加入 guest 测试渠道 konglaiimage.gif


重新登录进入游戏

微信图片_20220610142440.png

微信图片_20220610142455.png

完美,搞定。


测试并凑一局血战到底


创建房间

微信图片_20220610142514.png

加入房间


微信图片_20220610142528.png


开始游戏


微信图片_20220610142546.png


查看服务器日志微信图片_20220610142557.png


相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
6月前
|
人工智能 JavaScript API
零基础构建MCP服务器:TypeScript/Python双语言实战指南
作为一名深耕技术领域多年的博主摘星,我深刻感受到了MCP(Model Context Protocol)协议在AI生态系统中的革命性意义。MCP作为Anthropic推出的开放标准,正在重新定义AI应用与外部系统的交互方式,它不仅解决了传统API集成的复杂性问题,更为开发者提供了一个统一、安全、高效的连接框架。在过去几个月的实践中,我发现许多开发者对MCP的概念理解透彻,但在实际动手构建MCP服务器时却遇到了各种技术壁垒。从环境配置的细节问题到SDK API的深度理解,从第一个Hello World程序的调试到生产环境的部署优化,每一个环节都可能成为初学者的绊脚石。因此,我决定撰写这篇全面的实
1473 67
零基础构建MCP服务器:TypeScript/Python双语言实战指南
|
3月前
|
Cloud Native Serverless API
微服务架构实战指南:从单体应用到云原生的蜕变之路
🌟蒋星熠Jaxonic,代码为舟的星际旅人。深耕微服务架构,擅以DDD拆分服务、构建高可用通信与治理体系。分享从单体到云原生的实战经验,探索技术演进的无限可能。
微服务架构实战指南:从单体应用到云原生的蜕变之路
|
3月前
|
弹性计算 人工智能 前端开发
在阿里云ECS上部署n8n自动化工作流:U2实例实战
本文介绍如何在阿里云ECS的u2i/u2a实例上部署开源工作流自动化平台n8n,利用Docker快速搭建并配置定时任务,实现如每日抓取MuleRun新AI Agent并推送通知等自动化流程。内容涵盖环境准备、安全组设置、实战案例与优化建议,助力高效构建低维护成本的自动化系统。
851 5
|
6月前
|
JSON 前端开发 Go
Go语言实战:创建一个简单的 HTTP 服务器
本篇是《Go语言101实战》系列之一,讲解如何使用Go构建基础HTTP服务器。涵盖Go语言并发优势、HTTP服务搭建、路由处理、日志记录及测试方法,助你掌握高性能Web服务开发核心技能。
|
8月前
|
人工智能 安全 Shell
Jupyter MCP服务器部署实战:AI模型与Python环境无缝集成教程
Jupyter MCP服务器基于模型上下文协议(MCP),实现大型语言模型与Jupyter环境的无缝集成。它通过标准化接口,让AI模型安全访问和操作Jupyter核心组件,如内核、文件系统和终端。本文深入解析其技术架构、功能特性及部署方法。MCP服务器解决了传统AI模型缺乏实时上下文感知的问题,支持代码执行、变量状态获取、文件管理等功能,提升编程效率。同时,严格的权限控制确保了安全性。作为智能化交互工具,Jupyter MCP为动态计算环境与AI模型之间搭建了高效桥梁。
580 2
Jupyter MCP服务器部署实战:AI模型与Python环境无缝集成教程
|
9月前
|
Go API 定位技术
MCP 实战:用 Go 语言开发一个查询 IP 信息的 MCP 服务器
随着 MCP 的快速普及和广泛应用,MCP 服务器也层出不穷。大多数开发者使用的 MCP 服务器开发库是官方提供的 typescript-sdk,而作为 Go 开发者,我们也可以借助优秀的第三方库去开发 MCP 服务器,例如 ThinkInAIXYZ/go-mcp。 本文将详细介绍如何在 Go 语言中使用 go-mcp 库来开发一个查询 IP 信息的 MCP 服务器。
550 2
|
9月前
|
弹性计算 Linux 网络安全
阿里云服务器迁移中心SMC实战指南:跨平台业务迁移教程参考
现在越来越多的个人和企业用户选择将其他云平台或者服务商的业务迁移到阿里云,但是如何快速且安全完成迁移是很多用户比较关注的问题,我们可以选择使用阿里云提供的服务器迁移中心(Server Migration Center,简称SMC),这个产品是阿里云提供给您的迁移平台,专注于提供能力普惠、体验一致、效率至上的迁移服务,满足您在阿里云的迁移需求。本文为大家展示使用阿里云服务器迁移中心SMC将其他云平台业务迁移至阿里云的教程,以供参考。
|
9月前
|
弹性计算 资源调度 搜索推荐
阿里云ECS中长期成本节省计划解析:从原理到实战,助力企业降本提效
阿里云ECS节省计划的推出为企业用户提供了一种全新的成本优化方案。通过一次性购买的方式享受长期按量付费的折扣权益,客户不仅可以大幅降低ECS资源的使用成本还可以享受更高的灵活性和便捷性。本文将从多个维度深入剖析阿里云ECS节省计划,包括其核心优势、详尽的购买使用指引、与传统付费模式的全面对比,以及一客户成功案例,以供大家了解和参考。
|
11月前
|
Cloud Native 安全 Serverless
云原生应用实战:基于阿里云Serverless的API服务开发与部署
随着云计算的发展,Serverless架构日益流行。阿里云函数计算(Function Compute)作为Serverless服务,让开发者无需管理服务器即可运行代码,按需付费,简化开发运维流程。本文从零开始,介绍如何使用阿里云函数计算开发简单的API服务,并探讨其核心优势与最佳实践。通过Python示例,演示创建、部署及优化API的过程,涵盖环境准备、代码实现、性能优化和安全管理等内容,帮助读者快速上手Serverless开发。

热门文章

最新文章

推荐镜像

更多