目前国内外最新的实时游戏服务器技术术用的什么

hackfreer 的BLOG
用户名:hackfreer
文章数:532
评论数:211
访问量:1269074
注册日期:
阅读量:5863
阅读量:12276
阅读量:410556
阅读量:1098715
51CTO推荐博文
没什么技术性,只是想说明现状
现在想弄钱的入侵者,似乎热衷于入侵网络游戏服务器,盗出游戏服务器程序或是数据库。国内的网络游戏企业,都应该招受过此损失,有暴露出来的,有没暴露出来的。但游戏企业对安全问题理解都十分片面,狭隘!
然,不只是网络游戏企业。近一两年来,入侵者乐此不疲,各种商业数据的偷盗在国内几乎快形成一种”圈内产业”。不论是技术性还是行事组织性都与早年不可同
日而语。需求与供应在这里似乎有着完美结合。再看看各地公安网监部门,媒体似乎每天都有报道关于某地公安抓获某黑客的事件。但却似乎没有一起真正成熟的案
件。抓到的都是小鱼,大鱼都在偷着乐。原因有没发现没报案的,也有网监部门的技术问题。还有就是官僚主义,公安部门发布所谓的“战果”也乐此不疲。
话不说远了,转入正题。
一个好友在国内某网络游戏企业工作,让我帮忙测试他们游戏服务器群的安全性。加上我这段时间闲得无聊,也就答应了。
我先下载了游戏客户端程序,得到到了几个游戏服务器的地址。
游戏帐号在WEB网站上也可以注册,看来游戏中央数据库的调用WEB网站也可以。
仔细的检查了一下WEB网站,大部分是PHP+MYSQL的。代码写得还不错,几乎找不到什么突破口。再看看MYSQL,禁止远程连接。查看了其他游戏服
务器,都是LINUX系统,都只是开了OPENSSH和游戏服务器程序端口。只有WEB网站多个80,而又没什么可利用的地方。
看上去安全做得不错,但这是种幻象!
随 后仔细分析了下游戏客户端程序,我打开Sniffer
Pro以便记录下客户端程序和服务器的所有通信。发现客户端程序有个自动更新功能,我Sniff到是通过FTP去下载更新文件的。但我扫描所有游戏服务器
时没发现这个FTP端口啊(8888)。仔细看了一下,原来这个端口连接延时十分长。所以扫描器没发现这个端口。
意外的从更新过程中,竟然Sniff到一个固定的更新程序的FTP帐户。检查了FTP服务器是ProFTPd,我没直接用这个帐户去溢出ProFtpd。因为这台服务器开了SSH,我直接拿帐户去登陆SSH,获得一个权限极低的shell。
就像一块布,一但撕开一丁点口子,只要稍一加力,整块布都会随之撕开!
在系统中寻觅了半天,终于寻找到一个有权限去写的tmp目录。查看了内核版本,用kernel do_brk()的问题溢出提升权限获得了rootshell,没去装rkt,因为只是帮忙测试.
检查了系统的路由表,发现有一个内网,最后确认是VPN,原来所有游戏服务器之间的连接是通过VPN,防火墙的信任检查,都是通过内网的IP地址。外网访问这些服务器都只能看到22端口和游戏服务程序端口。
在这台已控制的服务器上下载了一个nmap,扫描了其他服务器,发现其中一台开了Samba,查看了一下版本,存在问题。溢出并获得了rootshell。
到现在为止以控制两台服务器,我把两台服务器的shadow文件都弄回来,拿jonh跑了一遍,没什么弱智密码。看来密码还设得挺好的。
逛尤了一会,在开了Samba的服务器上,发现了游戏服务器程序。并随之在game.conf文件中发现了中央数据库的地址和一个数据库帐户。登上去看了一下,数据库太庞大,放弃了dump出来的念头。
好象没有必要去分析游戏服务器程序,找出vul,去exp,来撕开其他服务器
但从其中的一个名为”weihu”的table中,发现一个后台管理帐户和密码,这个密码大小写互换加数字加符号。
我在web网站上找到一个后台入口,并用在数据库得到的帐户登陆成功。发现后台管理系统中有一个上传的功能,而且没检查文件后缀名。存放文件目录也是在web目录之下。上传了一个phpshell,执行命令成功,随后我又获得提升权限为root的shell。
现这台机器上还有个root在上面工作,但正在专注用vi编辑一个文件。没发现我。但我想到一个恶作剧。我给这台web网站服务器装了个能监视tty输入
的sniff,随后又skill了那个root,那个root被踢下去没多久,又登陆上来。但我立马就抓到了他的密码。
我用这个抓到的密码去登陆其他服务器的SSH,并也用root帐户,都登陆成功。
感觉所有服务器的系统都应该是直接拷的盘,因为系统版本和所安装的程序和一些配置大都相同。
至此已经控制游戏服务器群的所有服务器,其中还有一台是SMS网关。
我们的游戏时间结束。只是因为一个小问题,最后导致整个服务器群被控制,其实这在安全问题上,这是必然会发生的。安全无小事!
其实这家企业对安全也有投入,硬件防火墙,支持VPN的。但因为一个程序自动更新的设计上的小失败。导致一切都虚设。
随后我把整个过程告诉了我那朋友,听得他立马向他们主管汇报了问题。
如有其他游戏企业被入侵,雷同文章所说,那纯属巧合,本人概不负责!
了这篇文章
类别:┆阅读(0)┆评论(0)
16:50:13 17:11:49966,690 三月 独立访问用户
语言 & 开发
架构 & 设计
文化 & 方法
您目前处于:
Node.js之网游服务器实践
Node.js之网游服务器实践
日. 估计阅读时间:
不到一分钟
道AI风控、Serverless架构、EB级存储引擎,尽在!
相关厂商内容
相关赞助商
ArchSummit深圳-8日,深圳&华侨城洲际酒店,
角色扮演类游戏根据策划的要求可以实现各种各样的功能,如聊天,打斗,自动刷怪等各种复杂的功能,但是开发者基本可以把这些功能抽象地划分为二大类,即服务端的网络传输与逻辑运算能力,这样游戏服务的开发和实现会稍微简单些。现在,网络的实时传输基本上是采用Socket服务器来实现的,逻辑运算这个就不需要再述了,因此,游戏服务器就可以粗略的归纳为Socket的服务器综合游戏业务逻辑的实现。
与Web应用区别
从上面游戏服务的概念简单介绍中可以得知,实时游戏服务器的开发与传统的Web开发还是具有一些不同点,这些不同点着重体现在以下几个方面:
大部分的Web应用还是短连接的方式去实现,而游戏的实时性需要采用长连接的方式进行。
Web应用的场景一般是读多写少的应用,热点数据基本可以缓存;游戏服务的数据经常发生变动,如移动中的路径,打怪掉血等,缓存基本很快就失效,属于写多读少的应用场景。
广播特性,即Web应用行为上基本只需要用户与服务器交互,其他用户要实现共享他人信息的时候,会采用类似拉的方式如长轮询来实现数据交互,即使在没有数据更新的状态时也需要消耗一定的服务端资源,造成一定的浪费;游戏里面的交互方式需要实时进行,对影响三方的数据,必须采用广播的方法进行消息推送,即推的模式。
目前的Web应用开发一般采用无状态性的方式来实现,因此可以实现较好的可扩展性,很多Web服务会采用绑定会话或集中会话等方式工作,当后面的某台服务器出现宕机时,服务也可以很快的切换;但是游戏服务器和用户之间的连接是有状态的,在断开时需要进行相关的通知和数据持久化,在重连时需要进行状态恢复等手段来维护游戏世界的运行。
除以上几点不同之外,还有负载均衡的策略,服务驱动方式,系统判定,系统安全如外挂作弊等相关问题,文章中不再对他们进行对比说明。一般来讲,根据游戏的规模与需求,通常游戏服务器的实现的模式会使用如下的三种架构方式来实现。
单进程服务架构
图1 单进程服务架构
图1是目前互联网上的很多游戏服务器使用的架构,比如商用的游戏服务器,开源的有Google的 , Mozilla的 等框架。所有的程序在同一个进程里面运行,架构简单,开发人员上手快,开发和调试非常方便又快速,成本较低,后期的维护成本可能随着游戏项目的大小而不同,但是整体应该不会太高。很明显,游戏的世界是在同一个进程里运行,在单个场景都有不少在线用户的时候,如果采用单进程的 Node.js 实现的话,每个用户的操作可能会有一定的延迟,特别是在大量用户同时做大量操作与AI运算时,如服务端寻路和自动杀怪,延迟会更加严重;同时单进程对计算机资源使用有限。因此只适合游戏的原型制作或小型的游戏开发。另外,由于游戏的状态与复杂性,也无法较好的实现游戏的可扩展性,基本只能通过添加游戏服务器的方式来实现,即所谓的开新服,而这些用户之间是无法在同一个世界里通信会话和交互的。尽管Node.js支持原生的TCP服务,使用简单;但是目前大部分网络应用中,尤其是支持HTML5的应用,由于性能较好并且使用简单,成为大部分应用采用的网络库来实现高性能websocket服务。在移动互联网应用中,由于协议较复杂与通信数据等问题,需要一定的裁减。下面示例中,就是最简单的单进程服务的原型:
var socketio = require('socket.io');
var io = socketio.listen(8080);
io.sockets.on('connection',function(socket){
socket.on('disconnect',function(){
//user leave
socket.on('message',function(msg){
if (getLoginStatus(socket)) {
game[data.action].apply(null,[socket,msg]);
game['login'].apply(null,[socket,msg]);
多进程服务架构
图2 多进程服务架构
在上图2中,我们可以看出,每个进程负责采用单一职责,各进程间通过一定的规则(如RPC远程过程调用)来进行通信,游戏中的各场景服务使用一个进程来服务,实现各场景游戏运行的分离。但是在开发过程中,不需要考虑每个场景具体的信息,全部采用统一的代码来实现,开发方便,通过添加适当的参数来实现较易的调试,每个进程分别运行在服务器的多核上,即可以充分使用计算机的资源,也由于职责单一,由于每个进程都专职做自己的事,因此,在压力大的时候,可以很明显的查出问题所在,并可以较好的实现对相应的服务进行调优,可以达到较好的性能和一定的可伸缩性。但是,在各游戏的世界里,无法准确的知道游戏的状态如在线人数之类的,会存在热点数据和服务过载等一些问题,造成部分服务堵死等现象,也无法达到在不停服务的情况下进行服务器扩容与自动切换等问题,同时会给游戏运营带来一定的问题,不能充分的对玩家数据进行分析与挖掘,因此,这种实现方式可以满足中小型的游戏开发。这种架构目前很多的游戏服务器中还在使用,技术发展也较成熟,如传奇服务端架构等。
分布式服务架构
图3 分布式的服务架构
同样,分布式的服务架构与多进程的架构具有很多相同点,如进程服务单一职责,较好的性能调优,同时采用集中式的方式对游戏服务器进行管理,各游戏服务器可以通过自定义的方式即DSL进行游戏业务的路由与分发,通过主备服务器的状态可以很清楚的知道每个服务的状态及运行情况,这样可通过动态添加服务来到达负载均衡,具备较好的性能和可扩展性,能满足大型游戏的开发。当然,采用这样方式,会具有一定的复杂性,同时各服务之间可能是不在同一台服务器上的,因此会带来一定的网络开销,在大量广播的场景中,网络IO压力大,需要通过定时批量或AOI服务等方式来进行广播通信,同时,游戏的通信协议需要经过特别的设计,尽量避免数据序列化上的CPU重复开销,采用胖客户端的方式去分担游戏服务器的序列化与反序列化;另外还有可能引入分布式事务等相关问题,需要在一个集中点进行处理。当然,在游戏设计中,策划开发人员需要尽量避免这种跨场景跨进程的游戏逻辑需求。
在分布式架构实现中,目前商业上较成功的案例是游戏服务框架,国内外很多大型的游戏开发商都在使用。而在开源部分,目前还没有较稳定成熟的方案,我们团队采用Node.js正在开发的Pomelo游戏服务框架正在努力实现这一目标,现已进入最后的文档整理阶段,预计将在十月份进行开源与线上示例演示。
采用 Node.js 来实现网络游戏服务器的开发,除了能利用JavaScript的动态语言的优势特性、强大的开源社区和V8引擎的优越性能外,在网络数据传输的异步化方面具有快速、实时等事件编程模型;特别在HTML5的应用开发中,还具有前后端代码共享、DSL灵活定义等特点。但是也由于JavaScript的动态脚本语言的性质,同时V8在内存使用上的限制等问题。尽管V8引擎对脚本语言通过动态编译进行了静态化,但如果开发工程师在大规模开发时,没有注意到一些代码的细节,比如代码的额外异常检查和类属性的动态变化等方面,导致未经过调优的代码整体上还是无法和C、Java等静态语言相比的,然而在经过调优过后的代码是可以达到静态语言的性能的。在云计算应用中,也得到很多公司的推广与使用,如国外的SmartOS,Vmware以及国内的阿里云等,相信其性能与应用层面都会发展的越来越好;
此外,采用 Node.js 来实现游戏服务框架并开源也是一件非常有价值的事情,在追求高性能与低成本同时,希望能给开发者提供即简单又快速的开发方式,游戏开发者通过使用游戏框架,可以完全把精力放在业务代码的实现,不需要再把精力放在框架的实现。有机会我们将在后面的一系列讨论中介绍采用 Node.js 来开发游戏服务架构遇到的很多性能问题及优化过程。 最后,本文并不是建议大家一定要采用 Node.js 去开发游戏服务器,只是给新老游戏开发者提供一种解决方案,欢迎大家关注和探讨我们团队近期将开源的 Node.js 游戏服务解决框架。
个人介绍:
尧飘海,网易杭州开发工程师,系统分析员,正致力于Node.js的移动游戏引擎开发和性能优化等方面的工作,同时对JVM性能和服务端的应用架构设计也很有兴趣,欢迎交流。个人Github地址:。
感谢对本文的审校。
给InfoQ中文站投稿或者参与内容翻译工作,请邮件至。也欢迎大家通过新浪微博()或者腾讯微博()关注我们,并与我们的编辑和其他读者朋友交流。
Author Contacted
告诉我们您的想法
允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p
当有人回复此评论时请E-mail通知我
Jiang Kerry
Huang Zhiyong
很值得关注
Re: 错别字
Re: 错别字
Huang Zhiyong
Node.js之网游服务器实践
Re: 错别字
Re: 错别字
允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p
当有人回复此评论时请E-mail通知我
允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p
当有人回复此评论时请E-mail通知我
赞助商链接
InfoQ每周精要
订阅InfoQ每周精要,加入拥有25万多名资深开发者的庞大技术社区。
架构 & 设计
文化 & 方法
<及所有内容,版权所有 &#169;
C4Media Inc.
服务器由 提供, 我们最信赖的ISP伙伴。
北京创新网媒广告有限公司
京ICP备号-7
注意:如果要修改您的邮箱,我们将会发送确认邮件到您原来的邮箱。
使用现有的公司名称
修改公司名称为:
公司性质:
使用现有的公司性质
修改公司性质为:
使用现有的公司规模
修改公司规模为:
使用现在的国家
使用现在的省份
Subscribe to our newsletter?
Subscribe to our industry email notices?
我们发现您在使用ad blocker。
我们理解您使用ad blocker的初衷,但为了保证InfoQ能够继续以免费方式为您服务,我们需要您的支持。InfoQ绝不会在未经您许可的情况下将您的数据提供给第三方。我们仅将其用于向读者发送相关广告内容。请您将InfoQ添加至白名单,感谢您的理解与支持。游戏服务器:到底使用UDP还是TCP
在编写网络的时候,到底使用UDP还是TCP的问题迟早都要面对。
一般来说你会听到人们这样说:&除非你正在写一个动作类游戏,否则你就用TCP吧& 或者是 &你能够在MMO游戏中用TCP,因为魔兽世界就用的TCP!&
遗憾的是,这些观点都没有反映这个问题的复杂性。
首先,说明一下,我之前主要是用TCP进行网络编程。我曾为一个流行的在线纸牌游戏编写了好几年,在高峰期我们的每台能够承受个连接(同一台物理机器上有多个进程在跑)都没有问题。在我来看,TCP是一种安全而且常见的选择。
尽管如此,我们最新的项目却是使用UDP协议,而且我们的项目无法通过任何方式在TCP下工作。事实上,项目一开始使用的TCP,但是后来发现我们使用TCP无法达到我们需求的连接数量时,我们只能换成UDP了。
在使用中TCP表现怎么样呢
从原理上,TCP的优势有:
简单直接的长连接
可靠的信息传输
数据包的大小没有限制
任何一个和TCP打过交道的人都知道,要实现一个稳定的TCP网络连接,需要处理各种隐藏的坑,比如断线检测、慢速客户端响应阻塞数据包,对开放连接的各种dos攻击,阻塞和非阻塞IO模型等等。
除了上面列出的这些问题外,一个好的TCP模块确实不好编码实现。
但是,TCP最糟糕的特性是它对阻塞的控制。一般来说,TCP假定丢包是由于网络带宽不够造成的,所以发生这种情况的时候,TCP就会减少发包速度。
在3G或WiFi下,一个数据包丢失了,你希望的是立马重发这个数据包,然而TCP的阻塞机制却完全是采用相反的方式来处理!
而且没有任何办法能够绕过这个机制,因为这是TCP协议构建的基础。这就是为什么在3G或者WiFi环境下,ping值能够上升到1000多毫秒的原因。
为什么不用UDP
UDP相对TCP来说既简单又困难。
举个例子来说,UDP是基于数据包构建,这意味着在某些方面需要你完全颠覆在TCP下的观念。UDP只使用一个socket进行通信,不像TCP需要为每一个客户端建立一个socket连接。这些都是UDP非常不错的地方。
但是,大多数情况下你需要的仅仅是一些连接的概念罢了,一些基本的包序功能,以及所谓的连接可靠性。可惜的是,这些功能UDP都没有办法简单的提供给你,而你使用TCP却都可以免费得到。
这也是人们为什么经常推荐TCP的原因。在用TCP的时候你可以不考虑这些问题,直到你需要同步连接的数量级达到500以上的时候。
所以,是的,UDP没有提供所有的解决方法,但是就像你看到的那样,这也正是UDP好用的地方。在某种意义上来说,TCP对UDP就好比是Hibernate和手写SQL的区别。
使用TCP失败的地方
人们经常给你建议,让你去使用TCP,比如&TCP跟UDP一样快&或者&游戏X用TCP如此成功,所以TCP当然是首选&,然而,他们完全没有理解为什么在那个特定的游戏中TCP是有效的,为什么UDP不按照顺序发送数据包呢?
那么为什么魔兽世界采用TCP呢?首先我们需要解释这个问题。这个问题其实是&为什么魔兽世界有的时候1000毫秒以上的延迟还能够运行?&这是TCP的性质决定的,在发生丢包的时候,会产生巨大的延迟,因为TCP首先会去检测哪些包发生了丢失,然后重发所有丢失的包,直到他们都被接收到。
可靠的UDP也是有延迟的,但是由于它是在UDP的基础之上建立的通信协议,所以可以通过多种方式来减少延迟,不像TCP,所有的东西都要依赖于TCP协议本身而无法被更改。
就这一点来讲,一些人要开始提到Nagle算法了,实际上它是你在实现任意一个对延迟敏感的TCP模型时首先需要禁止使用的。
那么魔兽世界以及其他的一些游戏是怎么处理延迟问题的呢?
方法也很简单,他们能够隐藏掉延迟带来的影响。
在魔兽世界中,玩家和玩家是无法碰撞的:因为这类碰撞是无法通过一些预测来处理的,但是玩家和环境之间的碰撞却是可以通过预测来处理的,所以这里使用TCP是没有问题的。
我们来看一下魔兽世界的战斗就会发现,玩家的攻击指令发送给服务器的操作是放在比如&attack_entity(entity_id)&或者&cast_spell(entity_id, spell_id)&的接口中来做的,换句话说,瞄准操作是独立于进行的。如此一来,一些类似发起攻击动作和释放技能特效就能够在没有收到服务器确认的情况下就直接执行,比如展现冰冻技能的效果就可以在服务器没有返回数据前在客户端就做出来。
客户端直接开始进行计算而不等待服务端确认是一种典型的隐藏延迟的技术。
几年前,我为一个叫&Five Card Jazz&的纸牌游戏编写过客户端。它使用的是http协议,它比直接的TCP协议连接的延迟更加严重。
我们用简单的纸牌绘制和抽牌的动画来掩盖延迟的问题,所以延迟的问题只在非常糟糕的连接下才会被看出来。这种方法也非常的典型:发送请求的同时开始播放牌桌的动画,一直播放翻动最后一张牌直到接收到了服务端传回来的数据为止。魔兽世界的战斗特效就是使用类似的原理。
这也意味着,我们到底是使用TCP还是UDP取决于我们能否隐藏延迟。
TCP在什么时候失效
一个采用TCP的游戏必须能够处理好突发的延迟问题(纸牌客户端就很典型,对突发性的一秒的延迟,玩家也不会产生什么抱怨)或者是拥有缓解延迟问题的好方法。
但是如果你运行的是一个无法使用任何减缓延迟措施的游戏呢?玩家对玩家的动作类游戏通常就属于这个范畴,但是这也不仅仅限于动作类游戏。
举个例子:
我目前正在写一个多人游戏(War Arcana)。
一种常见的操作是,你快速的移动你的角色通过一张充满战争迷雾的世界地图,但是一旦你探索过,迷雾就会被打开。
为了确保游戏的规则,防止玩家作弊,服务器只能显示玩家当前位置附近的信息。这意味着不像魔兽世界,玩家无法在没有得到服务器响应的情况下,做出完整的动作。和Five Card Jazz相比,我们即使允许500毫秒的延迟,也已经非常困难了。
在实现了游戏的原型后,在局域网内一切都进行的非常顺利,但当我们在WiFi环境下测试时,操作会间歇性的卡起来或者延迟高起来。写了一些测试程序之后发现,WiFi环境下偶尔会发生丢包行为,每当发生丢包的时候,服务器的响应速度就从100-150毫秒上升到毫秒。
没有任何办法可以绕过TCP的这个设置来避开这个问题。
我们替换了TCP的代码,用了自定义的可靠的UDP来实现,把大量的丢包产生的延迟降到了仅仅只有50毫秒,甚至比以前TCP不丢包的情况一个来回的延迟还要小。当然,这只可能建立在UDP之上,这样我们才对可靠性拥有完全的掌控力。
困惑:可靠的UDP只是TCP的一种简单的实现?
你有没有听过这种说法:&可靠的UDP就像TCP一样,所以还是用TCP吧&。
问题是这种说法是错误的。可靠的UDP一点也不像TCP,要去实现一个特殊的阻塞控制。事实上,这也是你使用可靠UDP代替TCP的最大的原因,避免TCP的阻塞控制。
另一个重点是可靠的UDP的可靠性是如何保证的。这里有很多种方法去实现。我非常喜欢Quake3网络库代码里的一些想法,它们也激发了我在War Arcana中使用UDP协议。
你也可以使用许多支持可靠通信的UDP库,当然,这样在可靠性方面,相比自己手动实现全部的代码而言,可能会更加通用而失去了一些性能优势。
那么到底是用UDP还是TCP呢?
如果是由客户端间歇性的发起无状态的查询,并且偶尔发生延迟是可以容忍,那么使用HTTP/HTTPS吧。
如果客户端和服务器都可以独立发包,但是偶尔发生延迟可以容忍(比如:在线的纸牌游戏,许多MMO类的游戏),那么使用TCP长连接吧。
如果客户端和服务器都可以独立发包,而且无法忍受延迟(比如:大多数的多人动作类游戏,一些MMO类游戏),那么使用UDP吧。
这些也应该考虑在内:你的MMO客户端也许首先使用HTTP去获取上一次的更新内容,然后使用UDP跟游戏服务器进行连接。
永远不要害怕去使用最佳的工具来解决问题。
顶一下(0) 踩一下(0)
热门标签:}

我要回帖

更多关于 游戏服务器技术 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信