设为首页 收藏本站
查看: 794|回复: 0

[经验分享] GoWorld – 用Golang写一个分布式可扩展、可热更的游戏服务器

[复制链接]

尚未签到

发表于 2018-9-20 07:44:29 | 显示全部楼层 |阅读模式
  GoWorld代码:https://github.com/xiaonanln/goworld
  Golang具有运行效率高、内存安全等优良特性,因此是非常适合用来进行服务器开发。使用Golang开发游戏服务器有如下的优点:

  • 运行效率远高于各种脚本语言,大幅度提升服务器承载能力
  • 内存安全,不会像C++服务器那样出现内存错误导致服务器down机
  • Goroutine能够很好地利用多核计算能力,提升承载能力
  • Golang本身非常简单好用,大家都喜欢
  然而使用Golang编写游戏服务器也面临一定的困难,主要是两个方面:

  • Golang是静态编译语言,难以为提供方便的语法糖从而简化开发工作
  • Golang无法支持语言层面的热更新,可能因为频繁关服带来玩家流失
  GoWorld是一个使用Golang实现的可扩展的分布式游戏服务器引擎,并致力于解决以上的这些问题。首先,GoWorld提供对象(Entity)框架来为服务端逻辑开发提供便利。Entity可以在多个场景(Space)之间进行跳转,并且提供AOI支持,因此GoWorld可以很好的支持各种MMORPG游戏服务器所需要的功能。另外一方面,GoWorld通过进程替换来实现游戏逻辑的热更新。在热更新过程中,玩家的客户端连接和各种游戏状态会被保持,并在热更新结束之后恢复正常游戏。
进程结构
  GoWorld架构图
  一个GoWorld系统包括一个dispatcher进程、一个或者多个game进程以及一个或者多个gate进程。dispatcher负责game之间以及gate和game之间的消息转发,并对一些基础功能提供支持。Game进程负责Entity对象的管理和所有游戏逻辑的运行,Gate进程负责管理客户端连接,并将客户端请求通过dispatcher转发到game进程。Gate还需要负责对客户端数据进行压缩和加解密(尚未实现)。GoWorld可以通过增加更多的game进程或者gate进程来增加服务器的负载能力。虽然dispatcher进程是GoWorld服务器中的单点,但是初步的测试和推算表明一个多核高性能的主机上运行dispatcher可以支持100万以上的同时在线。
热更新
  GoWorld使用Hot-Swappaing的方式实现游戏逻辑的热更新。在Game进程收到SIGUSR1信号的时候,就会把当前所有Entity以及其他相关状态保存到一个文件中,并结束进程。此时可以使用最新的可执行镜像重启game进程,并从保存的文件中恢复所有的Entity和游戏状态,并恢复执行。在热更新的过程中,玩家客户端的连接不会中断,玩家角色的状态也会保持不变,只是会感受到一点卡顿,并在热更新结束后恢复。
Entity架构
Entity RPC
  在GoWorld中,我们使用一个Entity来代表游戏场景中的玩家、怪物、NPC之类的对象。GoWorld还支持从客户端到服务端的RPC通信,以及服务端Entity之间的RPC通信。
  GoWorld在RPC数据的封包和解析上使用了MessagePack格式,并会在将来支持Google Protobuf。
场景
  场景(Space)是GoWorld中一个非常重要的概念。每个Entity都属于一个场景。同一个场景的Entity之间可以直接调用相互的函数,而跨场景的Entity之间需要使用RPC来进行通信。Entity可以通过迁移(Migrate)函数来跳转到别的场景中,跳转场景后Entity的所有属性数据都将保持不变。
AOI
  GoWorld提供了一套简化的AOI机制。同场景的Entity之间会根据距离维护一个邻居列表。GoWorld使用十字列表维护场景里的所有Entity,从而根据Entity的位置变化实时更新所有Entity的AOI信息。
属性同步
  GoWorld为Entity提供了属性机制。属性分为服务端属性、客户端属性和全局属性。服务端属性只有在服务端可以访问,客户端属性可以在客户端和服务端同时访问。每次服务端对其进行修改的时候,属性的变化会立刻被同步到客户端,从而保持客户端数据的实时更新。全局属性是对所有Entity都可见的数据,包括其他玩家。全局属性在发生变化的时候会被广播到AOI范围内的所有玩家,从而使得玩家可以实时获取AOI范围内其他Entity的属性变化。
Entity自动存盘
  GoWorld支持Entity的自动存盘。持久化(persistent)的Entity会按一定的时间间隔进行存盘。GoWorld还提供了对已存盘Entity的载入功能。目前GoWorld支持MongoDB和Redis两种不同的底层数据库。
客户端连接和通信
  每个server都会创建一个监听端口用于接收来自客户端的连接。客户端和服务端之间也采用一个RPC的通信方式。客户端可以对玩家和玩家AOI里的其他Entity发起RPC调用。
  GoWorld支持对客户端通信进行压缩。加密功能还有待添加。。。
适用场合
  GoWorld游戏服务器引擎的开发目标是能够很好地支持常见的MMORPG类游戏。在这类游戏里,玩家往往控制一个角色,并可以在不同的场景之间进行切换,并且通过和周围的其他对象(包括NPC、怪物、其他玩家等)进行交互进行游戏内容。GoWorld所提供的场景-对象机制能够很好地支持这些功能。对于其他类似卡牌、棋牌类游戏,也可以使用GoWorld提供的对象机制进行逻辑开发。
安装和运行
下载GoWorld游戏服务器
  请前往github下载GoWorld:https://github.com/xiaonanln/goworld/
  或者使用go get工具:
  go get github.com/xiaonanln/goworld
  下载GoWorld依赖的库
go get -u github.com/xiaonanln/go-xnsyncutil/xnsyncutilgo get -u github.com/xiaonanln/goTimergo get -u github.com/xiaonanln/typeconvgo get -u golang.org/x/net/contextgo get -u github.com/Sirupsen/logrusgo get -u github.com/garyburd/redigo/redisgo get -u github.com/google/btreego get -u github.com/pkg/errorsgo get -u gopkg.in/eapache/queue.v1go get -u gopkg.in/ini.v1go get -u gopkg.in/mgo.v2go get -u gopkg.in/vmihailenco/msgpack.v2go get -u gopkg.in/natefinch/lumberjack.v2
运行GoWorld测试服务端和客户端
  1. 启动MongoDB或者Redis作为数据库
  2. 拷贝goworld.ini.sample为goworld.ini,并进行配置
  编译并运行中心分发器(dispatcher)
  make dispatcher
  components/dispatcher/dispatcher
  4. 编译并运行网关服务器(gate)
  make gate
  components/gate/gate -gid 1
  5. 编译并运行测试逻辑服务器(test_game)
  make test_game
  examples/test_game/test_game -gid 1
6. 编译并运行测试游戏客户端(test_client)
make test_client examples/test_client/test_client -N 500
还在开发阶段,更多内容有待补充,敬请关注 ……
  QQ讨论群:662182346


运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-597942-1-1.html 上篇帖子: 【GoLang】golang context channel 详解 下篇帖子: 依据 smtp协议的简单golang 的发邮件实现
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表