APP下载

内存房间管理在多人游戏中的研究与设计

2018-11-09隋玉亮

网络安全技术与应用 2018年11期
关键词:列表大厅队列

◆邵 岚 隋玉亮 李 真

内存房间管理在多人游戏中的研究与设计

◆邵 岚 隋玉亮 李 真

(CLO 北京 100000)

多人玩法允许多个人在同一个房间中互动游戏。本文主要描述了内存房间的业务逻辑和功能,多个房间在内存中的实现方式和效率优势,研究了内存房间列表、超时事件列表和异步任务队列的原理及设计实现。

内存管理;多人游戏;超时处理

0 引言

目前,我公司开发的游戏玩法均以单人玩法为主,无论是目前线上的游戏,还是后续开发的新游戏,尽管在游戏题材、游戏类型、游戏风格、动画效果(3D)、屏幕显示(双屏)等方面进行了诸多创新,但是在游戏模式上,仍然都是单人参与的游戏,玩家之间的操作独立互不影响,无法看到彼此的游戏状态,无法分享中奖的喜悦,无法体验和朋友共同游戏的乐趣。

如今的游戏行业,从早期的棋牌室、QQ游戏大厅[1],到红极一时的MUD网页游戏,再到现在蓬勃发展的各类手机游戏,则是多人玩法的天下。这些游戏玩法中,除了需要完成本身游戏逻辑的实现,还额外需要解决多人游戏玩法特有的问题,如系统架构的设计[2]、虚拟游戏房间的分配与管理、内存及数据库协同、游戏数据一致性与实时性、大并发量情况下如何解决系统的性能瓶颈[3]等。诸如此类的技术难点,需要在多人玩法中逐个实现。

本文研究并实现了一套支持多人游戏玩法的架构设计,首次使用内存(而非传统的单纯依赖数据库)对游戏数据进行管理,通过映射、双向链表、异步队列等技术手段实现对虚拟游戏房间的分配、管理、数据同步、事件响应、回收、转发等功能。本文的研究成果填补了我公司缺乏多人游戏玩法的空白,为今后的多人游戏策划开发提供了技术借鉴与支持。

1 项目整体架构

该项目系统由客户端、游戏服务器、通知服务器、大厅服务器、数据库等组成,是在原有的单人玩法系统中增加多人玩法,本文研发实现的房间管理功能位于游戏服务中,各模块间的关系如图1所示。

图1 项目整体架构图

游戏终端和游戏服务器原有功能及连接不变,增加大厅服务器和通知服务器。游戏服务器使用FastCGI向通知服务器发送消息,通知服务器通过Corba把消息推送给大厅服务器,大厅服务器与游戏终端之间使用tsl加密的WebSocket互相通信。游戏服务器之间新增了转发连接。

1.1 游戏终端

完成游戏的GUI展现和处理逻辑,负责调用游戏服务器的通信接口,根据收到的报文类型,把部分(或全部)报文转发给大厅服务器,并接收大厅服务的广播信息。

1.2 游戏服务器

游戏服务器负责完成游戏逻辑控制,保存游戏数据。在每个游戏服务器上新增了内存房间管理模块,主要负责以下功能:虚拟房间的创建、管理、删除;房间数据的同步与更新;对房间内各玩家进行监控,处理超时事件;将不属于本服务负责的游戏请求转发给其他游戏服务;服务异常之后的房间接管等。

1.3 通知服务器

在原有系统中增加通知服务器。通知服务器负责接收各个大厅服务器的注册消息,以及各个游戏服务器发来的通知请求,并将消息推送给指定的大厅服务器。经过重新设计后,通知服务器不再负责任何游戏逻辑及处理超时事件等,仅负责消息的推送,进一步和游戏服务器解耦,使得模块定位更加清晰准确。

1.4 大厅服务器

在原有系统中增加大厅服务器。大厅服务器接收各游戏客户端的注册,并向通知服务器注册,收到通知服务器的通知信息后,解析消息内容中目的地址字段,将通知信息通知到对应的游戏客户端。同时大厅服务器接收注册过的客户端发来的转发消息,解析消息内容中目的地址字段,将消息广播给对应的游戏客户端。大厅服务器只负责信息转发,不处理任何游戏逻辑。

1.5 数据库

为多人游戏提供数据支持,包括玩家信息,游戏状态,投注数据,房间信息,组队信息等。

2 房间管理业务逻辑和功能

在多人玩法中玩家进入游戏房间后有两种游戏场景:一种是房间内各玩家的投注互不干预但是可以互相观看游戏结果,另一种是房间内所有玩家处在同一画面相互配合赢得游戏奖励。如果玩家在游戏房间中长时间不操作,游戏服务器会根据不同游戏场景将玩家踢出房间或者自动帮玩家完成游戏。同一房间内任何一个玩家游戏状态或者房间状态发生变化时都会产生通知信息,并由系统推送给房间内每个玩家,实现游戏画面信息同步展示。

与房间管理相关的玩家业务操作主要有:玩家投注,加入房间,退出房间,超时。如图2所示。

玩家发起投注请求时,会在房间列表中找到对应的玩家房间,以原子性的方式完成本玩家的一次投注过程,更新房间内玩家的投注信息。

玩家进入房间时,系统自动将该玩家匹配到当前人数最多且未满员的游戏房间,并在此游戏房间数据中增加本玩家信息和超时事件,如果没有满足条件的房间,则为玩家新建一个房间并加入房间列表,同时在超时列表中加入一个针对本房间的超时计时器。

图2 房间业务处理图

玩家退出房间时,会在房间列表中找到对应的玩家房间,将玩家信息从房间里删除。如果玩家退出后,房间内还有其他玩家,则在房间列表中保留本房间;如果玩家退出后,房间内没有玩家了,则将本房间从房间列表中删除,同时从超时列表中删除本房间计时器。

在房间中的玩家,如果长时间不操作,会触发超时事件。系统每隔1秒钟会轮询一次超时列表,发现对应房间的计时器超时,则将房间中的超时事件加入任务队列执行。触发超时事件后,根据游戏场景不同将玩家踢出房间或者帮玩家完成游戏。

在以上业务操作中,如果玩家信息或者房间状态发生变化需要同步到房间内的所有玩家,则会生成同步信息,由推送系统推送到房间内各玩家客户端。

3 房间管理技术原理及设计

内存房间管理将房间数据保存在内存中,主要设计并实现了以下内存数据结构及管理机制:房间列表,超时列表,异步任务队列,房间数据转发与异常恢复。

3.1 房间列表技术原理及设计方式

为了快速的查找及增删元素,房间列表采用map结构,对于每种游戏玩法,以房间编号作为key,以房间对象作为value形成map;为了使系统支持同时管理多个种类的游戏,本文进一步以游戏编号作为key,以上述map结构作为value,组成了新的map结构,即一个两层结构的map嵌套,如图3所示。

图3 房间双层map图

另外,本文设计了三个房间相关的互斥锁,分别为map锁、房间数据锁、引用计数锁。map锁在增删房间、查找房间以及获取房间对象个数时使用,完成相应操作后,先释放map锁,再返回得到的房间对象。在后续对房间对象进行业务操作时,调用房间数据锁,保证房间数据的一致性,因为已经释放了map锁,因此不会阻塞其他线程的查找等操作。引用计数锁使用的场景为:当成功创建或者找到房间时引用计数加1,当清除数据资源时引用计数减一。总体来说,通过在不同场景调用三个功能不同的互斥锁,可以在保持数据一致性的前提下,最大限度的提高访问效率,减少等待时间。

3.2 超时列表技术原理及设计方式

假设一个房间有n个玩家,每个玩家都会存在超时情况,房间本身也存在超时情况。这样,一个房间中就会存在n+1个超时事件。如果每个超时事件对应一个超时计时器,一个房间需要n+1个超时计时器,过多的超时计时器会增加管理难度并引起业务处理的混乱。

为了解决以上问题,采用两级列表的方式处理超时,第一级列表是每个房间的所有超时事件以双向链表的方式按照超时时间排序挂入本房间数据结构下;第二级列表是只将房间超时链表最近一个超时事件放入全局超时列表中,从而保证了每个房间在全局超时列表中只存在一个超时计时器,如图4所示。

图4 超时链表设计图

系统每秒钟轮询一次全局超时链表,将超时事件放入异步任务队列;当异步任务队列的超时事件执行后,会从房间超时链表中取出下一个本房间的超时事件,放入全局超时链表。

3.3 异步任务队列技术原理及设计方式

在多人游戏业务中,即存在实时任务,如投注请求,也存在异步任务,如超时事件,通知事件。这些任务都是针对一个具体的房间执行的,为了保证内存房间数据的一致性,保证实时任务和异步任务的正常执行,防止异步任务的阻塞与丢失,引入了异步任务队列。所有的异步任务全部放入异步任务队列,只有在当前任务执行完成后,才会从异步任务队列取得下一个任务执行,既保证了实时任务的及时处理,也保证了异步任务的处理,完整的实现了多人游戏的业务逻辑。如图5所示。

图5 实时与异步任务执行图

实时任务或异步任务执行时,都会从房间列表查找对应房间,并锁定房间数据,执行完成后才允许其他任务操作本房间数据。引入异步任务队列后,把异步任务缓存到队列中,只允许本房间的一个异步任务对房间数据加锁,不会引起过多的任务同时对同一房间加锁而阻塞,同时还能保证当前任务执行完后,就会执行实时任务。异步任务队列通过sem信号监听当前队列中是否有需要执行的任务,如果有则执行,没有则不做操作。

3.4 房间数据转发与异常恢复

在现有系统架构下,每个游戏客户端可能连接到不同的游戏服务,而这些客户端因为参与多人玩法又被分配到同一个游戏房间,这会导致部署在不同游戏服务的内存房间管理模块互相争抢游戏房间的控制权,造成数据冲突与错误。为了解决这一问题,本文新增了游戏服务之间的转发连接,如图1所示。该转发消息通过iona中间件实现,收到客户端的请求后,先查询数据库,判断该客户端归属的房间服务url是否和本机的相同,如果相同则继续处理业务请求,如果不相同,则需要向目标url发送转发的消息,交由目标服务接管。

如果在上述转发过程中发现目标url的连接不存在,即表明目标服务出现了异常,则需要本服务接管起目标服务负责的所有房间,从数据库读取数据并恢复。待出异常的服务重新上线后,其会尝试从数据库恢复房间数据,继续提供服务。通过异常恢复与房间服务互相接管的设计,保证了即使有部分房间服务发生异常,剩余的房间服务仍可以保持服务不中断。

4 总结

本文在公司现有单人玩法系统的基础上,新增了通知服务器和大厅服务器,扩展成可以支持多人游戏玩法的系统,首次尝试用内存房间管理游戏数据,通过双层map映射、双向链表、任务队列等技术完成开发,完整的实现了多人游戏的业务逻辑,既保证了数据一致性,又减少了对数据库的频繁读取,提高了系统效率。通过本次多人游戏系统的研发,不仅增加了公司技术储备,同时也拓宽了游戏设计的角度与方式。

由于是首次进行多人游戏系统的设计,本项目在开发过程中不可避免的存在若干不足,如解决在消息推送过程中偶发的丢包现象;在长时间、大并发的情况下系统的响应时效与稳定性;如何监控各服务的状态及发生异常后的处理等,均需在今后的研发过程进一步的完善,并不断探索新技术、新方式,以满足未来游戏的需求。

[1]QQ游戏大厅体验报告.https://www.jianshu.com/p/df5 b66077949.

[2]从QQ游戏分布式架构设计看“分而治之”等原则.http://tech.it168.com/a2009/1019/762/000000762733.shtml.

[3]QQ游戏百万人同时在线服务器架构实现.https://blog.csdn.net/akunshouyoudou/article/details/56682869.

猜你喜欢

列表大厅队列
学习运用列表法
扩列吧
队列里的小秘密
基于多队列切换的SDN拥塞控制*
挪威Bodø市政大厅
在队列里
丰田加速驶入自动驾驶队列
跟踪导练(四)4
网上办事大厅解决方案
列表画树状图各有所长