当前位置: 首页 > news >正文

游戏服务端配置“热更”及“秒启动”终极方案(golang/ygluu/卢益贵)

游戏服务端配置“热更”及“秒启动”终极方案

ygluu  卢益贵

关键词:游戏微服务架构、游戏服务端热更、模块化解耦、golang

目录

一、前言

二、异步线程加载/重载方案

三、配置表碎片化方案

四、指针间接引用

五、重载通知

六、示例代码

七、相关连接


一、前言

众所周知,游戏服务端配置信息热更有几大问题(非lua架构):

1、因配置对象的指针被场景对象引用而导致热更复杂度提高

2、信息量大的配置表热更导致游戏卡顿、玩家闪断

3、一般重载后的配置信息仅影响重载后新创建的对应场景对象,不能影响已存在的场景对象

4、在高度解耦的模块化开发模式下导致热更复杂度提高

本示例代码将使用常用通用的方法来演示在“高度解耦、模块化、模板化”的开发模式下对上述问题的解决方案,并提出游戏服务器秒启动的辅助方案。同时给出了两种方案的完整示例代码下载连接(见后)。

二、异步线程加载/重载方案

异步加载可以完美解决主线程重载大配置文件时可能引起游戏卡顿的现象。见下载连接1

图1

三、配置表碎片化方案

由多行电子表格或者xml格式自动导出一行对应一个ini文件的ini格式,重载时可大大减少重载时间。另外此项方案可应用于游戏秒启动,游戏启动时仅加载必要配置,场景等玩家相关的配置,在玩家登录进入场景以后创建场景对象时再在主线程里同步加载碎片化的配置,碎片化的配置加载时所需时间极短,玩家几乎没有太明显的卡断感知。见下载连接2

当然秒启动还有一个重要方案:主从机方案,即采用主从机方式,在主机崩溃释放所占用端口号后,从机立即夺得相同端口的控制权,从机角色瞬间转变为主机角色

图2

四、指针间接引用

配置对象Cfg引用配置项Item(真正记载配置信息的地方),场景对象Map引用配置对象Cfg,每次Map使用配置信息时间接访问Cfg.Item。配置加载模块执行重载后,在主线程的回调中重置Cfg对象的Item字段,这样既不不影响主线程复杂的场景应用逻辑,又能让已存在的场景对象Map更新到最新的配置信息

图3

五、重载通知

针对部分需要复制配置信息的场景对象,通过主线程同步执行重载回调函数OnReload,这样每个场景对象实例Map1~N都能及时更新到最新的配置信息。

图4

六、示例代码

(一)示例代码下载连接及运行效果

1、示例代码(golang)下载链接:

线程异步加载方案示例代码(1):

游戏服务端配置“热更”终极方案icon-default.png?t=N7T8https://download.csdn.net/download/GuestCode/88977874配置表碎片化加载方案示例代码(2):

游戏服务端配置“热更”及“秒启动”终极方案icon-default.png?t=N7T8https://download.csdn.net/download/GuestCode/88979391

2、示例代码运行效果

重载后会通知所有场景实例更新最新的配置信息。

图5 线程异步加载效果

图6 配置表碎片化重载效果

(二)示例代码结构及源码文件

1、示例代码模块化目录结构

图7 

2、主线程队列代码(异步加载方案)

主线程队列采用了匿名函数队列

package queue/*******************************************************************************Author: Yigui Lu (卢益贵)Contact WX/QQ: 48092788Blog: https://blog.csdn.net/guestcodeCreation by: 2024-3-16*******************************************************************************/// 主线程队列(匿名函数),仅主线程调用,无需同步
var MainQ = make(chan func())// 主线程事件响应函数列表
var events = make(map[string]func())// 触发主线程事件
func TriggerEvent(name string) {MainQ <- func() {on := events[name]if on != nil {on()}}
}// 设置事件监听(在主线程中执行onEvent)
func ListenEvent(name string, onEvent func()) {events[name] = onEvent
}

3、主线程代码(异步加载方案)

package main/*******************************************************************************Author: Yigui Lu (卢益贵)Contact WX/QQ: 48092788Blog: https://blog.csdn.net/guestcodeCreation by: 2024-3-16*******************************************************************************/import (_ "cfgload/mapcfg"_ "cfgload/mapmgr""cfgload/queue"
)func main() {// 模拟游戏主线程for {// 匿名函数队列proc := <-queue.MainQ// 出列并执行proc()}
}

4、地图配置模块示例代码(异步加载方案)

加载和重载共一份逻辑代码。

package mapcfg/*******************************************************************************Author: Yigui Lu (卢益贵)Contact WX/QQ: 48092788Blog: https://blog.csdn.net/guestcodeCreation by: 2024-3-16*******************************************************************************/// 本配置单元可以作为配置模板加载所有配置import ("cfgload/queue""io/ioutil""log""time"
)const ModuleName = "地图配置模块"// 地图配置项,一个对应一个
type Item struct {Name    string // 地图名ResName string // 地址资源名ResData []byte // 资源数据Attrs   []int  // 地图属性
}// 外部类型:地图配置类
type Cfg struct {Item      *Item    // 真正的配置对象是ItemLoadCount int      // 加载次数,演示用onReloads []func() // 触发重载回调,部分场景需求用
}func (c *Cfg) AddOnReload(onReload func()) {c.onReloads = append(c.onReloads, onReload)
}// 配置表
type cfgs = map[string]*Cfg// 配置表(全局变量/外部接口,仅主线程调用无需同步)
var Cfgs cfgs// 配置异步加载协程
var loadcount int// 异步加载/重载通用函数,无需两者区分而额外编写代码
func loadFunc(ch chan bool) {for {// 等待加载通知<-ch// 以下在加载线程中执行 -->isReload := Cfgs != nilloadcount++if isReload {log.Println("地图配置模块(加载线程) => 正在重载......", loadcount)} else {log.Println("地图配置模块(加载线程) => 正在加载......")}var items []*Itemfor {// 模拟配置文件加载过程item := &Item{Name:    "南天门",ResName: "res001.map",}item.ResData, _ = ioutil.ReadFile(item.ResName)items = append(items, item)break // 仅加载一行}// <-- 以上在加载线程中执行// 匿名函数将在主线程执行,达到线程同步目的onModuleLoadedInMain := func() {if Cfgs == nil {// 首次加载Cfgs = make(cfgs)}for _, item := range items {cfg := Cfgs[item.Name]if cfg == nil {// 新增配置cfg = &Cfg{}cfg.Item = itemcfg.LoadCount = 1Cfgs[item.Name] = cfg} else {// 替换旧的配置cfg.Item = itemcfg.LoadCount++// 在主线程调用重载通知回调(只有部分场景需求才需要通知)for _, onReload := range cfg.onReloads {onReload()}}}}if isReload {log.Println("地图配置模块(加载线程) => 重载完毕", loadcount)} else {log.Println("地图配置模块(加载线程) => 加载完毕")}// 给主消息队列压栈// 主线程会调用onModuleLoadedInMain执行,达到线程同步目的queue.MainQ <- onModuleLoadedInMain//  首次加载,触发事件告诉主线程模块加载完毕if !isReload {queue.TriggerEvent(ModuleName)}}
}func reloadTrigger(ch chan bool) {// 模拟5秒钟触发一次重载请求for {ch <- truetime.Sleep(time.Second * 5)}
}func init() {ch := make(chan bool)go loadFunc(ch)go reloadTrigger(ch)
}

5、地图管理模块示例代码(异步加载方案)

package mapmgr/*******************************************************************************Author: Yigui Lu (卢益贵)Contact WX/QQ: 48092788Blog: https://blog.csdn.net/guestcodeCreation by: 2024-3-16*******************************************************************************/import ("cfgload/mapcfg""cfgload/queue""fmt""log"
)type Map struct {cfg   *mapcfg.CfgAttrs []int
}// 间接引用转为直接引用:Map.CfgItem
func (m *Map) CfgItem() *mapcfg.Item {return m.cfg.Item
}// 直接引用配置对象字段示例
func (m *Map) Name() string {return m.cfg.Item.Name
}// 复制配置信息示例(模拟部分需求场景,无需求则可以省略)
func (m *Map) onReloadCopyInfo() {const txt = "地图管理模块(主线程) => 复制配置信息,地图名称:%s,加载次数:%d"log.Println(fmt.Sprintf(txt, m.Name(), m.cfg.LoadCount))// csdn资源未修复此项bugm.Attrs = nilfor _, attr := range m.CfgItem().Attrs {m.Attrs = append(m.Attrs, attr)}
}var Maps = make(map[string]*Map)func createMap() {log.Println("地图管理模块(主线程) => 正在创建地图......")for _, cfg := range mapcfg.Cfgs {mp := &Map{cfg: cfg,}// 无复制配置信息需求时可以省略此步骤cfg.AddOnReload(mp.onReloadCopyInfo)// 为避免代码冗余,首次加载自己调用onReloadCopyInfo复制配置信息mp.onReloadCopyInfo()}log.Println("地图管理模块(主线程) => 创建地图完毕")
}func init() {// 待地图配置首次加载完毕后创建地图queue.ListenEvent(mapcfg.ModuleName, createMap)
}

七、相关连接

对比脚本型和编译型游戏服务器的热更新方案 - codedump的网络日志icon-default.png?t=N7T8https://www.codedump.info/post/20191206-gameserver-hot-refresh/

聊聊Golang游戏服务器的热更 | wudaijun's blogicon-default.png?t=N7T8https://wudaijun.com/2022/08/golang-gameserver-hotfix/

一种基于so的C/C++服务热更新方案_mob604756fea1c5的技术博客_51CTO博客icon-default.png?t=N7T8https://blog.51cto.com/u_15127648/4542189

游戏开发(九) 之 纯 lua 版 热更新 方案_纯lua的热更新方案-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/zyxjx1314/article/details/106045843

lua游戏服务器热更新_lua热更函数但不修改变量-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/peter_teng/article/details/52751231

游戏开发中的热更新:一_热更新从服务器上下载的是什么文件-CSDN博客icon-default.png?t=N7T8https://blog.csdn.net/weixin_40695640/article/details/129463767

相关文章:

游戏服务端配置“热更”及“秒启动”终极方案(golang/ygluu/卢益贵)

游戏服务端配置“热更”及“秒启动”终极方案 ygluu 卢益贵 关键词&#xff1a;游戏微服务架构、游戏服务端热更、模块化解耦、golang 目录 一、前言 二、异步线程加载/重载方案 三、配置表碎片化方案 四、指针间接引用 五、重载通知 六、示例代码 七、相关连接 一、…...

鸿蒙开发的入门

鸿蒙开发的入门 注册并实名认证华为开发者账户 华为官网 注册 有账户可以直接登录 并进行实名认证 下载并安装开发工具 鸿蒙开发使用的语言 java js c/c 仓颉 手机app java 硬件 c/c 应用开发工具的下载地址 Windows(64-bit) 下载地址 程序的运行过程 解析config.j…...

为什么要减少Http的请求以及如何减少Http请求

为什么要减少Http的请求 减少 HTTP 请求的数量是优化网页性能的一个重要策略&#xff0c;原因有以下几点&#xff1a; 1.延迟&#xff1a;每个 HTTP 请求都会有一定的网络延迟。即使数据量很小&#xff0c;请求和响应的往返时间也可能相当长&#xff0c;特别是在网络条件不好…...

Linux性能测试工具整理

性能测试工具&#xff1a;Unixbench lmbench stream iozone fio netperf spec2000 spec2006 一、unixbench unixbench主要是用于系统基础性能测试&#xff0c;unixbench也包含一些非常简单的2D和3D图形测试 UnixBench一个基于系统的基准测试工具&#xff0c;不单纯是CPU 内存 …...

前端路由history路由和hash路由的区别?原理?

前端路由是指在单页应用程序&#xff08;SPA&#xff09;中通过改变 URL 路径来实现页面切换和导航的机制。在前端开发中&#xff0c;有两种主要的前端路由实现方式&#xff1a;基于 History API 的路由&#xff08;history-based routing&#xff09;和基于哈希&#xff08;Ha…...

AcWing 727. 菱形——像拼图一样做题

题目描述] 分析&#xff1a; 利用程序根据输入的整数&#xff0c;画出由字符*构成的该整数阶的实心菱形。给出一个示例&#xff1a; n 7 n7 n7。 * * * * * * * * * * * * * * * * * * * * * * * * * 我们将采取拆解问题&#xff0c;通过四个部分的…...

深入理解生成型大型语言模型:自监督预训练、细调与对齐过程及其应用

分析概述 本文主要介绍了生成型大型语言模型&#xff08;LLM&#xff09;的预训练过程&#xff0c;特别是通过下一个令牌&#xff08;token&#xff09;预测的自监督学习方法&#xff0c;以及后续的细调&#xff08;finetuning&#xff09;和对齐&#xff08;alignment&#x…...

个人简历主页搭建系列-03:Hexo+Github Pages 介绍,框架配置

今天的更新内容主要是了解为什么选择这个网站搭建方案&#xff0c;以及一些前置软件的安装。 Why Hexo? 首先我们了解一下几种简单的网站框架搭建方案&#xff0c;看看对于搭建简历网站的需求哪个更合适。 在 BuiltWith&#xff08;网站技术分析工具&#xff09;上我们可以…...

【堆、位运算、数学】算法例题

目录 十九、堆 121. 数组中的第K个最大元素 ② 122. IPO ③ 123. 查找和最小的K对数字 ② 124. 数据流的中位数 ③ 二十、位运算 125. 二进制求和 ① 126. 颠倒二进制位 ① 127. 位1的个数 ① 128. 只出现一次的数字 ① 129. 只出现一次的数字 II ② 130. 数字范围…...

IDEA 多个git仓库项目放一个窗口

1、多个项目先通过新建module或者CtrlAltShiftS 添加module引入 2、重点是右下角有时候git 分支视图只有一个module的Repositories。这时候需要去设置把多个git仓库添加到同一个窗口才能方便提交代码。 3、如果Directory Mappings已经有相关项目配置&#xff0c;但是灰色的&…...

全球变暖(蓝桥杯,acwing每日一题)

题目描述&#xff1a; 你有一张某海域 NN 像素的照片&#xff0c;”.”表示海洋、”#”表示陆地&#xff0c;如下所示&#xff1a; ....... .##.... .##.... ....##. ..####. ...###. .......其中”上下左右”四个方向上连在一起的一片陆地组成一座岛屿&#xff0c;例如上图就…...

多数据源 - dynamic-datasource | 集成 Quartz 及 ShardingJDBC

文章目录 集成 Quartz引入 quartz-starter配置数据源参数创建任务配置 Quartz 实际使用的数据源方式一: 自定义 SchedulerFactoryBeanCustomizer方式二: 使用@QuartzDataSource来指明quartz数据源集成 ShardingJDBC项目引入 shardingsphere 依赖分别配置shardingjdbc和多数据…...

四连杆机构运动学仿真 | 【Matlab源码+理论公式文本】| 曲柄滑块 | 曲柄摇杆 | 机械连杆

【程序简介】&#x1f4bb;&#x1f50d; 本程序通过matlab实现了四连杆机构的运动学仿真编程&#xff0c;动态展现了四连杆机构的运动动画&#xff0c;同时给出了角位移、角速度和角加速度的时程曲线&#xff0c;除了程序本身&#xff0c;还提供了机构运动学公式推导文档&…...

Lightroom Classic 2024 for mac 中文激活:强大的图像后期处理软件

对于追求极致画面效果的摄影师来说&#xff0c;Lightroom Classic 2024无疑是Mac平台上的一款必备软件。它凭借其强大的功能和出色的性能&#xff0c;赢得了众多摄影师的青睐。 软件下载&#xff1a;Lightroom Classic 2024 for mac 中文激活版下载 在Lightroom Classic 2024中…...

程序员下班以后做什么副业合适?

我就是一个最普通的网络安全工程师&#xff0c;出道快10年了&#xff0c;不出意外地遭遇到瓶颈期&#xff0c;但是凭技术在各大平台挖漏洞副业&#xff0c;硬是妥妥扛过来了。 因为对于程序员来讲&#xff0c;这是个试错成本很低、事半功倍的选择。编程技能是一种强大生产力&a…...

HSE化工应急安全生产管理平台:衢州某巨大型化工企业的成功应用

在化工行业中&#xff0c;安全生产一直是至关重要的议题。为了提高生产安全性、降低成本并提升企业形象&#xff0c;衢州某巨大型化工企业引入了HSE化工应急安全生产管理平台&#xff0c;取得了显著的改善和获益。 该平台的核心功能包括风险管理和应急预案制定。通过对化工生产…...

塑料工厂5G智能制造数字孪生可视化平台,推进塑料行业数字化转型

塑料工厂5G智能制造数字孪生可视化平台&#xff0c;推进塑料行业数字化转型。塑料制造行业作为重要的工业领域&#xff0c;亟需借助这一平台实现产业升级与转型&#xff0c;以适应市场的变化和提高生产效率。传统的塑料制造过程往往存在生产效率低下、资源浪费、环境污染等问题…...

HTML万字学习总结

html文本标签特殊符号图片音频与视频超链接表单列表表格语义标签(布局) html文本标签 标签简介<html></html>根目录<head></head>规定文档相关的配置信息&#xff08;元数据<body></body>元素表示文档的内容<meta></meta>表示…...

Linux网络编程: 以太网帧Frame/ARP/RARP详解

一、TCP/IP五层模型 物理层&#xff08;Physical Layer&#xff09;&#xff1a;物理层是最底层&#xff0c;负责传输比特流&#xff08;bitstream&#xff09;以及物理介质的传输方式。它定义了如何在物理媒介上传输原始的比特流&#xff0c;例如通过电缆、光纤或无线传输等。…...

【SpringCloud微服务实战09】Elasticsearch 搜索引擎

一、Elasticsearch 安装 1、Docker安装ES #创建一个网络 docker network create es-net#拉取ES镜像(这里使用7.17.18版本) docker pull elasticsearch:7.17.18#新建一个目录存放es数据 mkdir es cd es#docker运行 单机启动es docker run -d \--name es \-e "ES_JAVA_O…...

三维GIS开发cesium智慧地铁教程(5)Cesium相机控制

一、环境搭建 <script src"../cesium1.99/Build/Cesium/Cesium.js"></script> <link rel"stylesheet" href"../cesium1.99/Build/Cesium/Widgets/widgets.css"> 关键配置点&#xff1a; 路径验证&#xff1a;确保相对路径.…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议&#xff08;EPSFD 2025&#xff09;将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会&#xff0c;EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

【位运算】消失的两个数字(hard)

消失的两个数字&#xff08;hard&#xff09; 题⽬描述&#xff1a;解法&#xff08;位运算&#xff09;&#xff1a;Java 算法代码&#xff1a;更简便代码 题⽬链接&#xff1a;⾯试题 17.19. 消失的两个数字 题⽬描述&#xff1a; 给定⼀个数组&#xff0c;包含从 1 到 N 所有…...

【网络安全产品大调研系列】2. 体验漏洞扫描

前言 2023 年漏洞扫描服务市场规模预计为 3.06&#xff08;十亿美元&#xff09;。漏洞扫描服务市场行业预计将从 2024 年的 3.48&#xff08;十亿美元&#xff09;增长到 2032 年的 9.54&#xff08;十亿美元&#xff09;。预测期内漏洞扫描服务市场 CAGR&#xff08;增长率&…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力

引言&#xff1a; 在人工智能快速发展的浪潮中&#xff0c;快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型&#xff08;LLM&#xff09;。该模型代表着该领域的重大突破&#xff0c;通过独特方式融合思考与非思考…...

Android第十三次面试总结(四大 组件基础)

Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成&#xff0c;用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机&#xff1a; ​onCreate()​​ ​调用时机​&#xff1a;Activity 首次创建时调用。​…...

Java毕业设计:WML信息查询与后端信息发布系统开发

JAVAWML信息查询与后端信息发布系统实现 一、系统概述 本系统基于Java和WML(无线标记语言)技术开发&#xff0c;实现了移动设备上的信息查询与后端信息发布功能。系统采用B/S架构&#xff0c;服务器端使用Java Servlet处理请求&#xff0c;数据库采用MySQL存储信息&#xff0…...

CRMEB 中 PHP 短信扩展开发:涵盖一号通、阿里云、腾讯云、创蓝

目前已有一号通短信、阿里云短信、腾讯云短信扩展 扩展入口文件 文件目录 crmeb\services\sms\Sms.php 默认驱动类型为&#xff1a;一号通 namespace crmeb\services\sms;use crmeb\basic\BaseManager; use crmeb\services\AccessTokenServeService; use crmeb\services\sms\…...

免费数学几何作图web平台

光锐软件免费数学工具&#xff0c;maths,数学制图&#xff0c;数学作图&#xff0c;几何作图&#xff0c;几何&#xff0c;AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...

实战三:开发网页端界面完成黑白视频转为彩色视频

​一、需求描述 设计一个简单的视频上色应用&#xff0c;用户可以通过网页界面上传黑白视频&#xff0c;系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观&#xff0c;不需要了解技术细节。 效果图 ​二、实现思路 总体思路&#xff1a; 用户通过Gradio界面上…...