关于我们

质量为本、客户为根、勇于拼搏、务实创新

< 返回新闻公共列表

网络服务器和游戏服务器的区别

发布时间:2021-04-18 17:29:41

  用Go语言写游戏服务器也有一个多月了,可以明显感受到两者的不同。 这篇文章我想具体谈谈它的不同。 当然,在了解差异的过程中,让我们来简单地了解一下Go语言本身。


  PS  :这里举一个SLG手游的例子


  1. Go语言的特点


  Go语言与Java等其他语言相比,可以说是非常年轻的语言。 Go语言由Robert  Griesemer、Rob  Pike、Ken  Thompson于2007年在谷歌开发。 2009年正式发表。


  Go语言的设计理念以简洁这两个字为中心,被认为是少的一方居多。 如果熟悉Java的话,比较一下Java的语法命名和Go,就能明显地感受到这种感觉。


  Go的特征可以简单地总结为以下几点。


  1.1静态类型和编译类型


  首先Go是静态型,静态型在编译时知道所有变量的类型,所以在编译阶段可以发现很多问题。 对于动态语言(如JavaScript  ),有些问题在运行时才能被发现。


  Go是一种编译型语言,看到编译型,大家的脑海里可能会想到另一种语言解释型。 虽然从字面上理解了两者的不同,但实际上已经看到了,用简单的例子来类比一下吧。


  编译型的在餐厅吃饭,点菜后,酒店会一直等到所有的菜都做好。


  说明了型号,在餐厅吃饭,点了菜之后,陆陆续续地一边吃一边上来了


  1.2跨平台


  顾名思义,你写的Go源代码可以在所有系统上运行。


  这很容易理解。 例如,Java的口号是“一次写入,运行”。 众所周知,Java是一种编译型语言,但Java在编译时生成字节码。 这个字节码与当前的操作系统无关,也与CPU无关。


  此字节码必须依赖于Java虚拟机运行,虚拟机将阻止用户与操作系统和CPU之间的差异。 对编程的人来说,这个过程其实没有感知到。 在Java中,语言本身的跨平台不表示代码可以跨平台。


  从某种意义上说,Go跨平台意味着Java类型必须安装与当前操作系统相对应的Go版本。 编译的可执行文件因操作系统而异。


  1.3自动垃圾回收


  和JVM一样,Go运行时的内存管理(GC  )由Go语言本身管理,不需要程序员的参与,但可以介入。


  1.4本机并行编程


  什么是原生? 我们知道,要用Java实现并发,需要外部类库支持(Thread  ),Go不需要从外部导入依赖。 支持关键字go的使用即可。 而且在Java中通过共享内存进行通信,所以熟悉Go的人应该看到了“不通过共享内存进行通信,而是应该通过通信共享内存”这样的话。. 5完美的构建工具


  它有自己的内置工具,包括检索、编译、测试、安装、运行和分析等一系列过程。 例如,可以使用Go  get命令下载更新指定的代码包,然后进行编译和安装。 可以使用go  build编译源代码,使用go  run命令运行go的程序,使用go  fmt快速格式化代码,统一代码样式。


  1.6多范式编程


  目前主流的编程范式有指令性编程、函数性编程以及我们最熟悉的面向对象编程。 编写Go的代码时,可以选择使用面向对象的方法,也可以使用函数编程的思想,使它们相互结合并互补。


  例如,Go可以使用接口来描述行为,也可以使用纯函数来避免副作用。 因此,多模态编程是指该语言支持多种编程模式。


  1.7代码风格强烈的统一


  使用Go的内置工具go  fmt,可以将代码快速格式化为官方统一的标准,从而实现代码样式的统一。 甚至golangci-lint也可以检测出你的语法是否与内置的标准语法冲突,把这个检测工具挂在git的钩子上,可以达到强制代码风格统一的目的。


  1.8活跃的社区


  另一个重要特征是国内Go社区非常活跃,对Go在国内的普及起到了很大的作用。


  2 .使用go的好处


  让我先谈谈我对Go语言的看法。 我认为Go在服务器上非常有优势。 如果今后有高并发的应用场景的话,大概率这个服务是由Go写的。 我不知道你是否注意到摩尔定律失效了。 近十年来,硬件的原始处理能力基本没有提高。 显然,一味增加晶体管的数量不是解决问题的最佳方法。


  根据美国航天局日前在官网上发表并迅速删除的文章,谷歌有可能实现量子霸权,一般来说其计算能力超过所有传统计算机。 由于部署更多晶体管的成本也在增加,供应商正在向处理器添加核心以提高性能。


  正如众所周知的Java一样,Java本身支持多线程,但在Java中使用多线程编程代码比较昂贵。 在Java中创建新线程会消耗约1米的内存。 如果需要支持成千上万个线程的运行,则服务很可能正在运行。 不仅是内存消耗,还存在支持多线程的同时执行和死锁等问题。


  在Go中使用协和代替线程。另外,一个线程所消耗的内存比线程少好几倍。 在同一物理设备限制下,最多只能启动数千个线程,而协作可能会启动数百万个线程。 而且不同的Goroutine可以通过信道进行安全的通信。3 .游戏服务器和Web服务器的区别


  据游戏服务器介绍,游戏服务器是一个需要长期运行的程序,该怎么办? 我个人认为,像Web服务器一样需要长期运行,也需要在不特定的不定时满足用户的要求。 两者从宏观上看没有本质区别。 另外,网络服务器对稳定性和性能也有要求,游戏服一般分为尺寸服。 这里举一个小衣服的例子。


  . 1状态


  首先要提到的是状态。 你可能听说过游戏服务器有状态,Web服务器是无状态的概念。 什么意思? Web服务器的大部分数据流直接发送到数据库。 游戏服务器的数据流首先写入内存,然后定期写入数据库(落地)。


  也就是说,游戏服务器本身的数据和数据库中的数据在运行中存在数据不一致的窗口。 如果此时游戏服务器宕机,数据最初到达的内存数据和数据库存的数据将不一致。


  Web服务没有这样的问题。 Web上的所有数据状态都已就位,可以将事务添加到操作中。 不用担心由于操作失败而导入脏数据。 正因为有状态的限制,游戏服务器才会小心使用内存、CPU。 在资源有限的情况下,寻求最大化的载重量,降低服务延迟。 当然,Web服务器为了缩短某个接口的响应时间而进行对应的优化。


  . 2容量扩展


  在Web服务器中,如果无法评估服务面临的压力,或者由于即时热点访问而导致服务不可用,则各服务只需接收请求、处理请求并返回结果,而不将数据存储在服务器的内存中,因此是自动的要将数据保存在内存中,它也在Redis中。 Redis的数据丢失对数据完整性几乎没有影响。


  但是在游戏服务器端很难像Web一样灵活。 首先,数据流不是数据库,而是内存。


  举个简单的例子,如果玩家的主城市受到攻击而起火,并且有自动扩展,那么在落地的窗口内,玩家很可能会再次请求另一个实例。 主城又没有燃烧。 因为数据先存在于内存中。


  再举个例子,玩家氪金买了礼包。 然后游戏结束后,落地窗口内再次上线。 这不仅仅是数据的问题。 玩家是用真金白银买的工具,突然不见了。 一两个没问题。 如果多名玩家有这样的问题,这将是一次严重的在线事故。 修复数据的工作量非常大。因此,一个游戏服务器可用的内存和CPU资源非常有限,不像Web服务器那样需要很大的成本就可以横向扩展。 因此,游戏服务器非常重视代码的性能和稳定性。


  . 3稳定


  如上例所示,如果游戏服务器运行中发生了bug,导致服务无法直接使用,或者通过这个bug刷了大量的工具,将会造成非常严重的在线事故。


  对于Web服务器来说,如果是管理系统等,则有可能存在脏数据。 脏数据对Web来说,也是故障诊断的头疼。 如果没有脏数据,服务暂时无法使用。 另外,使用微服务的体系结构时,重启服务的成本相对较小,只有重启中的服务的业务无法使用。 其余部分可以正常访问。


  对游戏服务器来说,服务器重启影响的是全服的玩家。 玩家停止衣服的时候,连游戏都不能进入,所以会特别影响玩家的体验。 此外,如果在停止服务之前服务的数据掉落而发生问题,则在服务重新启动后,将数据从数据库load传输到内存。 在这种情况下,也会发生数据不一致。


  . 4性能


  根据我的经验,在制作Web服务器时,为了减轻GC的压力,没有进行优化以不怎么占用内存。 当然,由于项目本身的体量很少,如果QPS高,Web服务器也需要重视性能,但游戏服务器需要始终注意这一点。


  但是在Web上,如果访问量大,一个服务就无法承担压力,很多人最先想到的解决方案应该是制作多个实例,最终可以很容易地横向扩展。


  在游戏服务器中,服务器的资源相当宝贵。 例如,绝对不要在不落地的场地落地。 可以在已知条件下计算某个字段的值。 尽量不要在代码中定义。 但是,这具体也取决于权衡运算量和调用的频率。 因为上线后,如果发生数据不一致,需要维护的数据越少,数据的修复就越困难。


  . 5谨严


  在这方面,我认为两者都是备受瞩目的重点。 但是,根据游戏服务器的情况,服务器可能发生异常或抛出panic。 结果被游戏的特殊环境放大。


  例如,如果召回的驻外部队失败,部队就会一直留在外面,无法使用。 这比浏览器中点的按钮没有反应,影响比较小。 微服务架构还允许在修复问题后以较低的成本重新启动相应的服务,并且游戏服务器需要重新修复数据。让我举另一个极端的例子。 点击商店,玩家将准备氪金。 但是,也有可能无法进入店里,无法得到商品清单。 这些都会直接影响游戏的体验和收入。


  对Web来说,服务器的稳定性也很重要。 否则,结果的严重性可能会因业务而异。 如果影响用户体验,会直接影响产品的口碑。


  3.6数据传输格式


  熟悉Web的人都知道,数据传输格式是JSON。 在游戏服务器上是Protobuf,是谷歌开发的数据传输格式,与JSON类似。 Protobuf是二进制文件,二进制数据量比JSON小一些。 另外,如果传输的字段为空,则不进行传输。 如果JSON为null,则以同样的方式传输。


  在任何环境中,举个例子,在Node.js和Java中,Protobuf的性能表现都比JSON好。 在Java中,Protobuf比JSON快了近80%。 如果Java的服务器间通信存在性能瓶颈,则可以考虑使用RPC在服务器之间进行通信。


  但凡事都有两面性。 Protobuf的缺点依然存在:


  文件很少


  社区与JSON的对比


  没有可读性的JSON好


  4总结


  以上总结了这两个月以来两者的不同。 只是进行了粗略的对比,没有具体的细节。 详细的事情以后有时会单独介绍。



/template/Home/Zkeys/PC/Static