c游戏服务器框架(游戏服务端架设)

golang有哪些不错的游戏服务器框架

为什么golang的开发效率高?

golang是一编译型的强类型语言,它在开发上的高效率主要来自于后发优势,不用考虑旧有恶心的历史,又有一个较高的工程视角。良好的避免了程序员因为“ { 需不需要独占一行 ”这种革命问题打架,也解决了一部分趁编译时间找产品妹妹搭讪的阶级敌人。

它有自己的包管理机制,工具链成熟,从开发、调试到发布都很简单方便;

有反向接口、defer、coroutine等大量的syntactic sugar;

编译速度快,因为是强类型语言又有gc,只要通过编译,非业务毛病就很少了;

它在语法级别上支持了goroutine,这是大家说到最多的内容,这里重点提一下。首先,coroutine并不稀罕,语言并不能超越硬件、操作系统实现神乎其神的功能。golang可以做到事情,其他语言也可以做到,譬如c++,在boost库里面自己就有的coroutine实现(当然用起来跟其他boost库一样恶心)。golang做的事情,是把这一套东西的使用过程简化了,并且提供了一套channel的通信模式,使得程序员可以忽略诸如死锁等问题。

goroutine的目的是描述并发编程模型。并发与并行不同,它并不需要多核的硬件支持,它不是一种物理运行状态,而是一种程序逻辑流程。它的主要目的不是利用多核提高运行效率,而是提供一种更容易理解、不容易出错的语言来描述问题。

实际上golang默认就是运行在单OS进程上面的,通过指定环境变量GOMAXPROCS才能转身跑在多OS进程上面。有人提到了的pomelo,开源本来是一件很不错的事情,但是基于自己对callback hell的偏见,我一直持有这种态度:敢用nodejs写大规模游戏服务器的人,都是真正的勇士 : ) 。

2、Erlang与Golang的coroutine有啥区别,coroutine是啥?

coroutine本质上是语言开发者自己实现的、处于user space内的线程,无论是erlang、还是golang都是这样。需要解决没有时钟中断;碰着阻塞式i\\o,整个进程都会被操作系统主动挂起;需要自己拥有调度控制能力(放在并行环境下面还是挺麻烦的一件事)等等问题。那为啥要废老大的劲自己做一套线程放user space里面呢?

并发是服务器语言必须要解决的问题;

system space的进程还有线程调度都太慢了、占用的空间也太大了。

把线程放到user space的可以避免了陷入system call进行上下文切换以及高速缓冲更新,线程本身以及切换等操作可以做得非常的轻量。这也就是golang这类语言反复提及的超高并发能力,分分钟给你开上几千个线程不费力。

不同的是,golang的并发调度在i/o等易发阻塞的时候才会发生,一般是内封在库函数内;erlang则更夸张,对每个coroutine维持一个计数器,常用语句都会导致这个计数器进行reduction,一旦到点,立即切换调度函数。

中断介入程度的不同,导致erlang看上去拥有了preemptive scheduling的能力,而golang则是cooperative shceduling的。golang一旦写出纯计算死循环,进程内所有会话必死无疑;要有大计算量少i\\o的函数还得自己主动叫runtime.Sched()来进行调度切换。

3、golang的运行效率怎么样?

我是相当反感所谓的ping\\pong式benchmark,运行效率需要放到具体的工作环境下面考虑。

首先,它再快也是快不过c的,毕竟底下做了那么多工作,又有调度,又有gc什么的。那为什么在那些benchmark里面,golang、nodejs、erlang的响应效率看上去那么优秀呢,响应快,并发强?并发能力强的原因上面已经提到了,响应快是因为大量非阻塞式i\\o操作出现的原因。这一点c也可以做到,并且能力更强,但是得多写不少优质代码。

然后,针对游戏服务器这种高实时性的运行环境,GC所造成的跳帧问题确实比较麻烦,前面的大神 @达达 有比较详细的论述和缓解方案,就不累述了 。随着golang的持续开发,相信应该会有非常大的改进。一是屏蔽内存操作是现代语言的大势所趋,它肯定是需要被实现的;二是GC算法已经相当的成熟,效率勉勉强强过得去;三是可以通过incremental的操作来均摊cpu消耗。

用这一点点效率损失换取一个更高的生产能力是不是值得呢?我觉得是值得的,硬件已经很便宜了,人生苦短,让自己的生活更轻松一点吧: )。

4、基于以上的论述,我认为采用go进行小范围的MMORPG开发是可行的。

使用Go 语言开发大型 MMORPG 游戏服务器怎么样

从2013年起,经朋友推荐开始用Golang编写游戏登陆服务器, 配合C++做第三方平台验证. 到编写独立工具导表工具GitHub - davyxu/tabtoy: 跨平台的高性能便捷电子表格导出器. 以及网络库GitHub - davyxu/cellnet: 简单,方便,高效的Go语言的游戏服务器底层. 最终使用这些工具及库编写整个游戏服务器框架, 我的感受是很不错的

细节看来, 有如下的几个点:

语言, 库

Golang语言特性和C很像, 简单, 一张A4纸就能写完所有特性. 你想想看, C++到了领悟阶段, 也只用那几个简单特性, 剩下的都是一大堆解决各种内存问题的技巧. 而Golang一开始就简单, 何必浪费生命去研究那一大堆的奇技淫巧呢?

Golang的坑只有2个:1. interface{}和nil配合使用, 2. for循环时, 将循环变量引入闭包(Golang, Lua, C#闭包变量捕获差异) 完全不影响正常使用, 复合语言概念, 只是看官方后面怎么有效的避免

用Golang就忘记继承那套东西, 用组合+接口

用Golang服务器如何保证解决游戏服务器存盘一致性问题? stop the world是肯定的, 但是Golang可以从语言层并发序列化玩家数据, 再通过后台存盘

channel是goroutine虽然是Golang的语言特性. 但是在编写服务器时, 其实只有底层用的比较多.

Golang的第三方库简直多如牛毛, 好的也很多

不要说模板了, C#的也不好用, 官方在纠结也不要加, 使用中, 没模板确实有点不方便. 用interface{}/反射做泛型对于Golang这种强类型语言来说,还是有点打脸

运行期

Golang和C++比性能的话, 这是C++的优势, Golang因为没虚拟机, 只有薄薄的一层调度层. 因此性能是非常高的, 用一点性能牺牲换开发效率, 妥妥的

1.6版后的GC优化的已经很好了, 如果你不是高性能,高并发Web应用, 非要找出一堆的优化技巧的话. 只用Golang写点游戏服务器, 那点GC损耗可以忽略不计

和其他现代语言一样, 崩溃捕捉是标配功能, 我用Golang的服务器线上跑, 基本没碰到过崩溃情况

热更新: 官方已经有plugin系统的提交, 跨平台的. 估计很快就可以告别手动cgo做so热更新

开发, 调试, 部署, 优化

LiteIDE是我首选的Golang的IDE, 虽然有童鞋说B格不高. 但这估计实在是找不到缺点说了, 别跟我说Visual Studio, 那是宇宙级的...

曾经听说有人不看好Golang, 我问为啥: 说这么新的语言, 不好招人,后面打听到他是个策划... 好吧

真实情况是这样的: Golang对于有点编程基础的新人来说, 1周左右可以开始贡献代码. 老司机2~3天.

开发效率还是不错的, 一般大的游戏功能, 2*2人一周3~4个整完. 这换C++时代, 大概也就1~2个还写不完. 对接服务器sdk的话, 大概1天接个10多个没问题

Golang自带性能调优工具, 从内存, CPU, 阻塞点等几个方面直接出图进行分析, 非常直观, 可以参考我博客几年前的分析: 使用Golang进行性能分析(Profiling)

Golang支持交叉编译, 跨平台部署, 什么概念? linux是吧? 不问你什么版本, 直接windows上编译输出一个elf, 甩到服务器上开跑.不超过1分钟时间..

游戏服务器与普通服务器有什么区别

首先,游戏服务器与普通服务器相比较来说,游戏服务器需要能够保存更多的用户的状态。用户的等级等属性不用说,一般的IM服务也会有,还有一些时刻变化的数据,比如某个玩家的生命值,发技能前后的法力值等等,这些值区别于一般的属性值如名字,ID这些,这些数据会经常性的变化,还会参与到逻辑的计算中,比如你一个多少等级的玩家吃了什么东西之后战力值变化为多少,打在一个多少属性的玩家身上会不会被他闪避,会不会产生暴击…诸如此类的信息,在游戏服务器中都会一一保存。

其次,游戏服务器中每一个用户都是独立存在的,每一个用户的数据、请求等都是独立的,用户彼此间的数据并没有任何交互。这也是游戏服务器与普通服务器之间最大的区别。至于客户端之间会有交互这一点,举最简单的例子,一个人在一个场景里面说了一句话,那么“同一个屏幕”的玩家也需要能够看到他说的这句话。此时游戏服务器就需要判断,多远的距离以内的玩家,会认定为是\"同屏幕\"的玩家,需要向这些玩家广播这个玩家说的这句话。

这个广播就比较麻烦了。首先,需要计算哪些玩家属于\"同屏幕\",就是我们在第一点提到的玩家身上某些经常变化的属性需要做的运算,在这里需要根据玩家的坐标,找出来跟在同屏幕的玩家,用到的是AOI的概念。另外,找到了这些需要接收这个消息的玩家之后,将消息转发给它们又是一个IO密集的操作,假如场景中有10个人,那么一句话就需要同时广播给另外9个人,假如有100人,1000人呢,数据量就更大了,而且时间的延迟也不能太长,这对于游戏服务器的性能就要求很高了。所以同样的一个硬件配置的服务器,可能跑Nginx可以同时处理上万的链接,但是对于一个游戏服务器就只有1,2千了,就是因为游戏服务器是一个CPU密集而且IO密集的服务器类型。而且不仅需要这样的游戏服务器不仅要求性能比较高,还需要服务器具有极高的稳定性,总不能隔一会就宕机了,那大家还怎么玩。

此外,游戏服务器需要更好的数据承载能力和处理能力。而普通服务器则在各个方面都比较均衡。在寻找游戏服务器租用商的时候,一定要选择那种CPU性能非常出色的。

最后一点,游戏行业一直以来是网络攻击的重灾区,很多游戏刚上线没多久就频繁遭到攻击,导致玩家大量流失口碑下降,最后可能导致直接关服。所以游戏服务器一定要带高防流量包。

总结:那些热门的开源游戏服务器框架,还不看你就out了

作为一名业内资深的游戏开发人员,经常会遇到实习的新同事在工作中会问到这样的问题:

工作中到底有哪些开源游戏服务器框架,该去值得学习呢?

囊括到node.js 、java、C#、golang 、c++、python 等技术栈有各种各样的游戏框架。

本文给大家总结了一些github上star和fork比较常用的且有一定数量的较为完整的框架做了一个说明,大家可以往下看。

地址:

基于此引擎开发的游戏众多,很多棋牌小企业在用,例如简悦的 陌陌争霸 、 食物战争 等等很多产品...

地址:

一花科技等棋牌在用

地址:

代表作全民无双

地址:

已经被电魂网络收购

地址:

经过产品验证并且教程比较完善

地址:

zooba appstroe排行很高的moba、吃鸡类游戏

但是,像c++类的框架对新手要求较高。

亦或者node.js类框架性能确实差一些,毕竟它是针对io密集型。

阿博自己的话使用的是pitaya这套框架。毕竟支持分布式使用的技术比较新,也经过各种验证。 其他的就先不做评价,留着给大家发表一下意见。

毕竟,只要适合自己的才是最好的。

是的不......

不同服务器之间的数据同步(skynet 和 c++)

最近公司开发了一个捕鱼游戏,现在想要把这个项目嵌入到公司已有的游戏中,成为其子游戏,开发捕鱼的服务器框架是基于 skynet 的框架(独立一套系统)。而已有的游戏服务器框架是c++自研框架(也是独立的一套系统),所以需要解决一个问题:就是两个系统中数据共享的问题,因为用户都是现有游戏中的。捕鱼并没有用户,用户从主游戏中进入到捕鱼势必要把 ta 的金币、钻石、道具等数据带到捕鱼服务器,最终用户退出捕鱼游戏,要把用户现在的金币和其他数据移动回去,这里就涉及到数据共享和维护数据唯一性的问题了。

最初的方案是选择 http 请求通知的方式进行通信。但是考虑到极端情况: 如高并发,如果一秒钟发起 2W 次请求那么以 http 的处理方式就是要 每秒建立tcp链接和断开链接 * 2W次,文件描述符占用、和不能便捷集成到两个系统业务层中、以及网络异常处理需要依赖到DB保存数据待后续恢复、以及后续的集群部署需要再做考虑,等等这些缺点都是无法忍受的。

后面考虑用 redis 的 Pub/Sub 来实现高效的 MQ 并且在请求发起的时候如果超时,如果数据是必须被对方接收的话,还可以直接把数据写入缓存,让对端自行获取。遂和其他 xxMQ 进行对比,最后不管从易用性、通用性、高可用等等方面上都是 redis 胜出,当然 redis 的 Pub/Sub 也是有缺点的,但是使用到上述的这个应用场景来说,都是可以忽略的。

数据一致性保证机制

如果发起端请求对端超时 会将请求的数据写入到缓存,其格式如下:

保存到 redis 中的类型:set

key: 捕鱼缩写(f) + \"_\" + 用户uid

value: \"请求的命令 \"+\" @ \" + [ k + \"|\" + value [ k + \"|\" + value ...] ]

实例 key = f_10001 value = req_mv_gold@gold=10000|session=1

含义为:捕鱼发起的请求(f) 用户uid(10001) 命令(req_mv_gold)和携带数据用 \"@\" 分割,数据中字段与字段用 \"|\" 进行分割。数据解析,按对应命令协议定义结构进行解析。

1.用户登录了捕鱼,进入捕鱼游戏,用户向斗地主发起请求 req_mv_gold 数据中 gold 字段值为 0,斗地主就把用户的金币先保存到临时变量,然后置空用户的金币,再把用户金币通过 rsp_mv_gold 发送给捕鱼,如果 rsp_mv_gold 没有收到响应,斗地主要把钱加回给用户,意味这一次转移金币失败

2.假如用户已经成功完成了上面的步骤,此时用户在斗地主中的金币值为 0,在捕鱼中的金币值为用户实际金币值。

3.等用户退出捕鱼游戏就再次向斗地主发起第一个步骤的请求,如果成功,则完成了金币转移,如果失败(可能斗地主服务器中,这个用户下线了,可能斗地主奔溃了,可能网络阻塞或者掉线),捕鱼会把这次的请求写入到 redis 中,也就是上面的这个例子。

4.用户再次登录斗地主时,斗地主服务器需要去redis中查看是否有 捕鱼缩写(f) + \" \" + 用户uid 的这个健的存在,如果存在了,就要读取该键全部的成员

如:SMEMBERS f_10001,(理论上来说,每种请求最多一条记录)并且删除掉 redis中的 捕鱼缩写(f)+\" \"+uid 的健 如:DEL f_10001。并且按具体内容恢复数据。

这个机制适用于全部需要确保对端收到的命令。如果对端是捕鱼,那么 set 的键是 斗地主缩写(d) + \"_\" + uid,表示斗地主发起的请求失败了,捕鱼会按上面的流程自行处理。

未经允许不得转载:便宜VPS网 » c游戏服务器框架(游戏服务端架设)