没开发过游戏的人会以为游戏服务器是很神秘的东西。但事实上它并不比web服务器复杂,无非是给客户端提供网络请求服务,本质上它只是基于长链接的socket服务器。固然在逻辑复杂性、消息量、实时性方面有更高的要求。html
若是说web服务器的本质是http服务器,那么游戏服务器的本质就是socket服务器。 它利用socket通信来实现服务器与客户端之间的交互。事实上有很多游戏是直接基于原生socket来开发的。 相对于简单的socket服务器,它承受着更加烦重的任务:前端
不少web应用不会基于原生的http服务器搭建,通常都会基于某类应用服务器(如tomcat)搭建,并且还会利用一些开发框架来简化web开发。 一样,通常游戏服务器的开发都会在socket服务器上封装出一套框架或相似的应用服务器。为何使用原生的socket接口开发不够好呢?html5
一个好的框架能够大大简化游戏服务器的工做。除了游戏自身的逻辑外,大部分的工做均可以用框架来解决。服务端的抽象,可伸缩性,可扩展性这些问题均可以经过框架来解决。 游戏服务器框架也承担了应用服务器的功能。能够把框架当作容器,只要把符合容器标准的代码扔进去,容器就运行起来了。它天然具有了抽象能力、可伸缩性和监控、管理等能力。java
在开源社区里充斥了数不清的web服务器框架,游戏客户端的框架和库也有一大堆,但惟独游戏服务器框架少之又少,零星有一些类库,但完整的解决方案几乎没有。咱们只好从商用的解决方案中拿出一些框架进行类比:node
RedDwarf是惟一一个能找到的完整的开源游戏服务器框架,由sun出品。惋惜在它合并到Oracle之后已经中止开发了。 在设计上,RedDwarf是个分布式架构,它在分布式数据存储和任务管理上投入了太多精力,并且作的过于理想化,如动态任务迁移功能的实现很是复杂,但实际应用中根本用不到。而在可伸缩性和性能的设计上不太理想。所以RedDwarf夭折了。android
SmartfoxServer是由意大利的一家游戏公司gotoAndPlay()推出的商用游戏服务器。 它是基于java开发的,与web应用服务器如Tomcat看上去很相似。Smartfox支持各类客户端,且有一些成功案例。它在服务端封装和监控管理方面实现得很完善。 但在可伸缩性上并非太理想,尽管Smartfox也支持Cluster模式,但它的扩展方式是基于jvm内存复制的。也没有实现传统MMORPG基于场景分区的解决方案。 Smartfox有免费版本,但彻底不开源。并且它的免费版本(达不到高并发用户要求)很大程度是为了吸引开发者最终购买它的收费版本。不限在线人数的收费版本价格达到3500美刀。ios
Bigworld是澳大利亚Bigworld公司开发的全套3d MMORPG游戏解决方案,解决方案包含了客户端和服务端。Bigworld功能很是强大,在动态负载均衡和容错性作了不少工做。可扩展性很是强大。 它的缺点是过于重量级,对硬件要求高,且价格很是昂贵。Bigworld是专门为3d MMORPG游戏定制,但并不适用于中小型游戏的开发。web
Pomelo是网易于2012年11月推出的开源游戏服务器。它是基于node.js开发的高性能、可伸缩、轻量级游戏服务器框架。 它的主要优点有如下几点:算法
Pomelo目前的主要缺点是推出时间尚短,一些功能还在完善中,支持的客户端类型还有限,目前已支持HTML五、ios、android、untiy3d等4类客户端,将来还会支持更多的客户端类型。json
无论是web应用仍是游戏服务器,可伸缩性始终是最重要的指标,也是最棘手的问题,它涉及到系统运行架构的搭建,各类优化策略。 只有把可伸缩性设计好了,游戏的规模、同时在线人数、响应时间等参数才能获得保证。
相比web应用几乎无限扩展的架构(前提是架构设计得好),游戏服务器的可伸缩性相比就着差远了。那么是哪些因素致使游戏没法达到web应用的扩展能力呢? 说明:本文提到的web应用不包括相似于聊天这样的高实时web应用,高实时web可认为是一种逻辑较简单的游戏。
web应用都是基于request/response的短链接模式。占用的资源要比一直hold长链接的游戏服务器要少不少。Web应用能使用短链接模式的缘由以下:
而游戏应用只能使用长链接,缘由以下:
在高并发长链接服务的解决方案中,目前除了传统的C语言(过于重量级)实现,用的最多的是erlang与node.js。二者的性能指标差很少,而node.js在易用性方面毫无疑问胜出太多。
最近微博上看到时go的能撑起100万的并发链接,node.js也能达到一样的数据, Node.js w/1M concurrent connections!有node.js的长链接数据,它占用了16G内存,但CPU还远没跑满。
普通的web应用在交互上没有相邻性的概念,全部用户之间的交互都是平等,交互频率也不受地域限制。 而游戏则否则,游戏交互跟玩家所在地图(场景)上的位置关系很是大,如两个玩家在相邻的地方能够互相PK或组队打怪。这种相邻的交互频率很是高,对实时性的要求也很是高,这就必需要求相邻玩家在分布在同一个进程里。 因而就有了按场景分区的策略,如图所示:
一个进程里能够有一个场景,也能够有多个场景。这种实现带来了如下问题:
游戏中广播的代价是很是大的。玩家的输入与输出是不对等的,玩家本身简单地动一下,就须要将这个消息实时推送给全部看到这个玩家的其余玩家。 假如场景里面人较少,广播发送的消息数还很少,但若是人数达到很密集的程度,则广播的频度将呈平方级增加。如图所示:
假如场景中1000个玩家,每人发1条消息,若是须要其它玩家都看到的话,消息的推送量将高达1,000,000条,这足以把任何服务器撑爆。
解决这个问题的方案:
这样广播逻辑与具体的进程逻辑就不会相互影响了,并且因为只有后端的场景服务器是有状态的,前端负责广播的服务器仍是无状态的,所以前端服务器能够无限扩展。
实时游戏的服务端通常都须要一个定时tick来执行定时任务,为了游戏的实时性,通常要求这个tick时间在100ms以内。这些任务包括如下逻辑:
因为实时100ms的限制,这个实时tick的执行时间必需要远少于100ms,所以单进程内不少数据都会受到限制。
通过以上这些分析。咱们能够获得如今的运行架构,以下图:
运行架构说明:
这个运行架构符合了刚才提到的几个伸缩性原则:
前面提到4个游戏服务器框架,只有bigworld和pomelo符合这样的架构,固然bigworld实现的还要更复杂。 如今的问题是,这个运行架构是个分布式架构,并且并不简单,那就带来如下问题:
Node.js的特色与游戏服务器极其符合。列举以下:
Pomelo是基于node.js搭建的游戏服务器框架,它在灵活性、扩展能力,轻量级调试方面具备无可比拟的优点。咱们先简单回答第三章最末的几个问题:
在本系列文章后面将会陆续讨论pomelo是怎么实现以上如此方便的特性, 以及这些设计带来的启发。
本文分析了游戏服务器框架的市场现状,一个高可伸缩游戏服务器架构的设计原则及运行架构。Node.js与pomelo在解决高并发和分布式架构中起到的做用。下文咱们将深刻分析pomelo在解决复杂的游戏服务器运行架构中提供了哪些便利。