漫谈分布式游戏服务器
2021-06-24 20:55:08 【

游戏服务器为什么要设计成分布式?很简单的原因,为了支持服务器有更多的玩家同时在线。这里的同时在线,是要求玩家能一起交互,而不是简单的在平行世界独立游戏。

如果游戏是单进程架构,受限于cpu和内存的限制,一个进程是不可能支持太多人同时在线的,总会达到一个瓶颈无法突破。PCU(Peak concurrent users),术语代表最高同时在线玩家人数。PCU的上限,跟游戏本身类型,程序架构,机器性能强相关。

谈架构,先聊聊游戏业务特点。

1 、难点在于时间复杂度是以N ^ 2 进行增长的,以平方的级别增长的。具体业务展示为,如移动, 一个人移动要通知其他人,N个人移动就是N * (N - 1), 以平方级别增长的。如世界聊天等。所以很多游戏采取分服分线的策略。当然还有风险问题,现在的用户成本居高不下,一千人的服务器的成本都就上万了,出点技术问题,一个服流失点人都能亏几千,几万,人数攀上去风险太高。

2 热点问题。具体业务展示为,攻城战,帮会战等。策划的业务需求,人多热闹,特别了设定场景人能重叠,就更甚了。跟12306火车订票的问题有点像,只是数量级不在一个级别而已。不过有个问题就是客户端承受不了,手机同屏100不到就不行了,网页flash同屏也就200来人卡得飞起,客户端倒是能达上千。然而游戏服务器做上千同屏问题不大。

3 、高响应速度,基本需要在50ms以下的响应速度。因为加上网络延迟就能到100ms, 玩过lol或者王者荣耀,当延迟超过100ms会有卡顿感,过了200ms,很多都没法玩的了。很多别的领域甚至能到达秒级别响应就好,但游戏不行。不过游戏的业务里并不是全部都要求高响应的,高响应的主要在场景同步上,主要在移动,战斗上面,玩家响应速度会有最直观的感受,但对于一些公会申请之类的,那些的响应需要更偏向传统领域,1秒也是能接受的,但最好还是都在500ms一下。当然不同游戏类型的响应速度的要求不一样。当年做传奇,移动间隔是550ms,所以其实不超过200ms也是可以的,到500ms,就是一步一卡了。当然或许就是使用物品什么的会有一些稍稍的卡顿感。

4 、数据一致性要求高。这块是接近电商,金融的需求。物品因为某些原因,如bug, 突然多的,玩家会去刷,破坏游戏平衡,少了会导致用户流失。包括在数据丢失的时候,也得数据一致。毕竟有可能就是刚好冲了值,结果数据一丢,冲的钱没有了。

5 、数据安全这块,倒是不太重。允许丢失数据,正如社交能丢失聊天记录。但不能太长,最多也就是5分钟,因为太长玩家会有白玩的感觉。当然最好就是不丢,但在灾难面前,丢5分钟数据真的是小事,以前在9377的时候,有丢了1,2个月数据的事件。前段时间,还有腾讯云还把别人公司的数据全丢了,关键是数据一致性。

6 、写数据比读数据多。在所有的业务当中,移动是占据98%比重,移动一次得记录下坐标。所以,写比读多。

7 、数据量比较小,一个服的数据,运行一个月导出来,可能就是几百M顶天了,不过这个更多是因为单服人数的关系。最后一个服平均就是100来人。

8 、游戏服务器的是有状态的,重启玩家会掉线,有Bug需要极速修复,而且不允许轻易重启。因为写比读多,而且还是多太多,所以一般都得做缓存,重启会导致缓存丢失。不像一些领域可以数据都存数据库,让服务器无状态,随时重启。

9 、跨服,合服需求

其他的需求就跟别的领域差不多

1 、开发效率,协作效率,上手难度

2 、线上查Bug,容错能力

3 、宕机处理,容灾

现在开始聊聊解决方案

1 、计算时间复杂度这个问题,其实一般采取同屏广播,集中分发就可以解决。甚至不处理都可以,因为更多时候是客户端限制,用户量没到那个位置。当然哪怕是到一定量的用户量(起码单服上万)才需要考虑这种问题。当然根本解决这个问题的方法是做集群,就是同时几台机器承载同一张地图的场景运算就行了(当然这里也有一些坑跟问题,方案最多上限估计在100万,因为带宽先炸了)。但是最关键还是一个,成本问题。互联网创业有个基础是边际成本为0,或者是在用户量大接近0。然而这种方式是边际成本会越来越高。所以基本上采取分服分线的策略

2 、热点问题,业务需求,没法解决。

3 、高响应,一般游戏至少30帧,每帧30ms。但其实服务器真不需要让响应时间到30ms, 一般玩家一个动作就是10几帧,最少都有8帧,在动作结束前响应就行。100ms以下基本ok,除了一些像王者荣耀那种,需要高精度的,可能特殊处理。

4 、数据一致性,其实在比较常规,一般采取事务处理解决

5 、数据安全这块,一般采取宕机写入数据,一般不会丢数据,除非是有硬件损坏,或者系统崩溃。一般不会丢,而且最多也只会丢5分钟数据。

6 、写数据比读数据多。这个其实也比较常规,一般采取缓存解决。

7 、游戏服务器的是有状态的,这个很多时候我们会采取热更新。以前甚至是直接把业务接口设计成插件,进行动态库重新加载的处理。还有快速重启这些策略

8、 跨服,其实数据访问的问题,还有一致性的问题。

9 、开发效率,协作效率,上手难度。服务器框架采取很多都是面向接口+面向对象,以保证协作,以及开发效率

10 、线上查Bug,一般就是日志 + core dump,还有一些监控工具,如top之类的。

11 、宕机一般就是安全关服,做各种数据保存。当然还有数据库宕机这些处理,业务拆分成分布式,进行进行分区容灾。


结果总体看来,数据的问题,线上查错,容灾,热更这些才是重点问题。而事实上在以前,会有网络问题,因为epoll跟iocp还没有出现,大家还用的select, 著名的c10k问题,所以架构上都会有网关的设定。还有就是这10年计算机的性能翻了很多倍,著名的摩尔定律了解一下,当年单机做1000人都是问题。现在都是不是问题。现在单线程 + 无阻塞队列,都能达到2000+,如果用上一些高频的机器,甚至可能达到5000人。以前很多的问题都不是问题了。


接着介绍一些架构具体的方案。

单线程 + 无阻塞队列


这个架构的重点在于业务线程不能有阻塞,其他IO异步,一些重计算的,排行榜(堆排序),聊天(ac自动机)等需要特殊算法进行优化,或分布式架构,拆分出来。

当然可能会遇到一些问题

1、 无锁编程(并不是必要,可以简单队列处理)

2 、多线程死锁问题

3、 跨服会比较麻烦,因为架构耦合比较严重,一般建个新服做为跨服,进入跨服数据同步过去,等退出跨服,再把数据反向同步回来

4 、单点问题,一旦不可用,就是整体不可用

特意说一下这个,这个的设计的目的是为了实现服务器无状态,把状态存进去redis里面,主要游戏服务器基本都是有状态的,需要保存一些状态的数据。当然有些类别可以做成无状态,如卡牌。不保存状态,就能实现快速重启,数据,逻辑分离好处多多。但并不是所有业务都能用,redis在单链接大概在2万qps,多链接确实能到10万qps。对于大部分业务是可以的,很多都是低频业务,但对于一些高频的,同屏100人用这个扛不住的。


分布式架构


这个架构的重点在于服务器拆分,一般按着业务,数据一致性进行拆分。

当然也会遇到一些问题

1 分布式数据一致性问题(最麻烦的问题,虽然说有通用方案,就是做分布式事务,采用最终一致性进行妥协,但很多公司的做法是不理,因为麻烦,通过把数据冗余尽量把分割的功能合在一起,策略采取先扣除,出问题,客服人工补)

2 调用链问题,因为功能割裂,有些时候问题查找麻烦(日志跟踪麻烦,因为功能割裂,日志分布在不同的服务器上)

3 运维的工作量剧增,或许需要开发一些额外的工具

4 单点问题不可用(网络不可用,机器不可用)

5 一些特殊的业务得做冗余设计,做缓存系统

其实可以明显对比,分布式架构要做要解决的问题会相堆比较多,所以有足够的人力才去做,所以这也是个考量的要素之一。

当然不同游戏类型,架构会稍微不一样,简单介绍一下


mmorpg 前面说过服务器拆分是依据数据一致性的,在mmorpg中,场景的数据是比较重要的,不像回合制,场景物体与人物,数据同步量比较大,做数据一致性比较麻烦,一般会把场景角色管理合为一体,如在场景捡一个物品,进入背包,人物血量同步,技能同步等。

漫谈游戏服务器架构

棋牌游戏,压力会在于各种子游戏跟机器人上面,所以会采取按游戏拆分,每场游戏再进行数据同步,有业务的特殊性,网关规避攻击,规避监管。

架构设计,其实更多是为了解决问题,像一些流行的微服务,其实主要为了是解决在大量人力同时做一个项目,在沟通成本急剧上涨情况下,进行合理拆分,减少沟通成本。


】【打印关闭】 【返回顶部
上一篇游戏服务器DDOS攻击的危害及防御.. 下一篇云计算和游戏业务推动 微软市值首..