游戏服务器发展历史
一、太古元年
类似一个小的网站服务器,服务器只负责存储:
1、玩家账号的上传和下载(账号的道具数据,等级数据)
2、将同屏幕其它玩家的行为数据转发。
二、乱世之初
服务器有了逻辑模块,会对玩家的io进行一定的检查,做出合法的逻辑处理
客户端通过某种形式验证登陆以后,就和服务器通过TCP直接相连了。这种服务器的承载能力不高,但那时在游戏逻辑上也务求简化,把负载减少到极致,例如:
1、玩家看不到怪物的血量,或者只能看到正在打的怪物的血量。
2、地图有格子的概念,每个格子只能有一个单位,极大限制了同屏人数
性能瓶颈的原因主要是将 逻辑处理 和 数据传输 的功能集中到一个服务器上,为了解决这个问题又出现了新的模型。
三、近代曙光
很明显,将逻辑处理和连接传输功能分开到不同的服务器上,如下图:
此时依然只有一台逻辑服务器,拓展出了很多连接服务器,因为连接服务(数据记录的存储)不要求很高的同步性,所以可以做成这样的分布式系统构架,这个时代的服务器的速度大大的加快了。
四、当前盛世
人类总是不满足现况的,在mmo端游中,为了进一步提高服务器速度,人们开始细分逻辑服务器,主要的分法为以下两类:
1、将游戏的逻辑功能细分
2、将总的游戏场景分为不同地图,每个地图有自己的服务器
两种方法的思路均是相同的,把单个逻辑服务器的压力分散到多个服务器上,并行分担,需要解决的主要难题也类似:
1、不同逻辑服务器终究是要同步的,怎么同步?
2、各个服务器间的连接和通讯。
五、三分天下
一、BigWorld 服务器构架
它利用了上述的第二种分割方法,将场景分为小块,会根据当前场景的玩家人数,动态分配服务器资源,不同的小块场景分配在不同的服务器上。
优点:理论上单服务器承载百万级的玩家在线,大大的解决了服务器效率问题。
缺点:鉴于前述的服务器同步问题,服务器通信问题,BigWorld的开发必须严格按照它的框架模式,开发效率极低,游戏内的逻辑变得异常的复杂,开发难度倍增。
二、Skynet
Skynet是一款开源服务器框架,为泛型框架(可分布式,也可单线程),开发语言为以C语言和lua配合,这也就是问什么很多大场都需要会lua脚本语言的C++游戏开发了。
附上github
https://github.com/cloudwu/skynet
下面我把我理解中的Skynet算法描述一下:
Skynet把一个服务器抽象成一个操作系统,假设当前服务器为m核,则服务器可以建立m个进程,通过系统调度算法,将m个进程并行处理成千上万个服务,换句话说,就是对原来 单进程的逻辑服务器的另外一种分割,无关任何逻辑分割,只是将任务分配到不同进程。
优点:因为是同一个操作系统,所以进程间的通信延迟基本可以忽略不计,由于硬件友好性很棒,所以可以很简单的部署到很多物理机上。
缺点:开发平台比较单一,目前完全依附于Lua
三、Go
Go语言是google开发的一门服务器框架,类似于Lua,也是高度榨取多线程并行的速率,其goroutine特性就是高度并行的代表:
在此处举一个例子
//go语言
//一个循环输出0到9的函数
func loop() {
for i := 0; i < 10; i++ {
fmt.Printf("%d ", i)
}
}
func main(){
loop() //a
loop() //b
}//此时输出为0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9,先进行a后进行b
func main(){
go loop() //a
loop() //b
time.sleep(time.Second)//main函数停顿1秒
}//其中go loop() 就是一个goroutine,他会和b并行执行,之所以停顿一秒是为了防止main函数退出太快,当然项目中使用信道的方法而不是停顿方法,详细的请看以下博客:
//http://blog.csdn.net/skh2015java/article/details/60330785
go语言优点:简洁、快速、安全、并行、有趣、开源、内存管理、v数组安全、编译迅速
补充:
Moba型的开房游戏,每个房间相互独立,可以将mmo复杂的模型框架简化:
管理单位为一个服务器的一个进程,一个进程管理一个房间,根据房间数量,动态分配服务器资源。