当前位置: 首页 > 科技观察

为什么像王者荣耀这样的游戏服务器不愿意使用微服务?

时间:2023-03-12 09:57:56 科技观察

最近在知乎上看到一个问题:“为什么游戏公司的服务器不愿意微服务?”背景介绍:笔者最近采访了一家游戏公司。最近面试了一个游戏公司(很多大的,上市的),我问他,公司对微服务架构有什么规划和考虑吗?他很惊讶,说,我没听说过微服务,你能解释一下吗?我大致说了易测试、易维护、易升级、服务间松耦合、多语言开发、自动扩展……等等。然后他说游戏服务器不需要微服务,因为需要实时,需要微服务。服务会影响性能。我不确定按模块开发是否更好,但是微服务不是趋势吗?尤其是大公司,游戏服务器的服务应该很容易拆分吧?hongjic93是这样回答的:比如moba游戏/王者荣耀/LOL,就看王者荣耀的客户端,想象一下。账号系统、符文系统、英雄系统、皮肤系统、好友系统、好友之间的消息等都是常规操作。如果流量够大,当然可以用微服务架构来做。但这不是这款游戏的核心,核心是MOBA:多人在线对战竞技场。有什么特点?10人之间各种游戏事件的高速多方位通信流/广播/组播/pubsub等多种通信方式所以游戏的核心在于小规模群体之间的高速网络通信。对方说的是实时的。如果多了10ms的延迟,玩家就会被骂。1.微服务为了完美拆解业务,将同一个进程中原有的模块拆分成不同的服务,显着增加了额外的网络开销。更不用说servicemesh,各种gateway,proxy,sidecars,就是担心延迟太低。2、微服务基本上只有请求/响应模式。不能做流媒体?微服务通常要求应用程序是无状态的,以便水平扩展。Streaming本身就是在state3中加入的。我可以想象,为了提高通信的性能,一款英雄联盟游戏很可能会使用同一个服务器来负责这10个玩家之间的通信,这样就可以进行数据交换本地。最大化。对客户端或服务端统一网关的要求是必须支持粘性路由。假设客户端连接断开,下一个必须重新连接到与之前相同的服务器。微服务的无状态,水瓶扩展需求本身就是反粘路由,因为粘路由本身就是状态。4.对于服务器集群来说,有无数个王者荣耀游戏同时进行,每个游戏都可以看做是一个沙盒,每个沙盒都处于不同的状态:推了多少塔,你我有被杀了几次,对面还有几个超神。已经20分钟了吗?这些是长期存在的状态,直到游戏结束,服务器才能清理一局游戏的状态。所以虽然没有必要将这些状态写入到持久化存储中,但它们必然会长期存在于内存中。都是状态。反正有状态就别想用微服务了。除非你说把这些状态都搬到redis上去,那服务器在信息流到一半的时候会去远程请求,一来一去延迟就变大了。反正也不好。(比如假设对方在A你的水晶中,A的每一次操作都是一个事件,流式传输到服务器的沙箱中,沙箱中有一个流处理器,每次收到一个事件你的水晶是A,它会计算你的水晶是否爆炸了。这个计算需要非常快,而且你不可能远程存储你水晶的生命值数据)这类游戏对网络,内存要求很高,和CPU优??化。游戏过程中,几乎没有RPC调用。如果确实需要远程数据,应该预取。在游戏开始时加载微服务并不是灵丹妙药。方便拆解原有的CRUD应用。仅此而已,一是没有触及高级交互方式,二是没有触及分布式系统真正的难点:状态,其实并没有大家想象的那么好用。之所以感觉微服务改变了互联网,是因为90%的互联网应用都只是简单的小规模增删改查。如果对方没有听说过微服务也没关系,因为它本身并不是一个高深的概念。相反,对方听了你就知道微服务不适合做游戏,说明对方理解能力强,对游戏系统设计理解足够深。Brice是这样回答的:我玩过棋牌游戏(最简单的一种游戏),可以尝试说几点:1.微服务本身就是为了处理业务逻辑的复杂性,需要一种新的方式组织接口。游戏本身的逻辑其实并没有那么复杂。比如大厅,有一些基本的功能,比如修改账号,登录。游戏本身就是游戏本身的逻辑。2、游戏逻辑服务器(如棋牌类游戏)本身有网络响应性能要求(玩家对每次操作的反馈时间的敏感度远高于业务系统),所以游戏服务器是有状态的,以及状态存在于内存中。偶尔接受redis、mysql等是绝对不能接受的。关系行数据库仅用于定期异步持久化数据。只有游戏服务器才能将数据持久化到redis中。3、游戏服务器一般需要主动推送,第一代微服务网关无法满足需求。tcp没有gateway,可能用springcloudgateway的websocket(但是从防攻击的角度来说,端游绝对要用TCP,比websockets更合理)。4、服务间通信RPC首先不适合ribbon、feign等,因为它们都是基于http的,使用Http时存在消息乱序的问题。比如一个玩家出牌两次,在http中可能顺序不一致。游戏服务器集群一般使用长连接互连。也许你需要使用dubbo?(据说是长连接)5.游戏逻辑服务器(比如游戏服务器)一般不能用springmvc来做,因为线程模型完全不一样。多线程模型游戏性能差,非常复杂。一般用单个进程/线程驱动固定数量的房间(这就是为什么服务器必须有状态,不能直接读写mysql)。一般直接netty6。自动扩容在游戏端叫服务器开服,很长时间以来都有固定的流程、工具和限流方法。7.游戏中很多操作没有服务降级熔断器。8、大堂服务器登录注册确实可以作为微服务使用,但实际上不是微服务,只是几个接口自动横向扩展的方案。发现注册服务用处不大,开服是板上钉钉的事,还有一系列操作手段配合,关服千万不能随便关。9.游戏处理的流量真的不多。10000个在线棋牌游戏已经可以赚很多钱,10W是一个特别强大的产品。10、充值等一些独立服务器是否需要做微服务?只能说这种服务端需要微服务来处理,项目组才能梦寐以求。虽然上面说了很多点,其实可以考虑用springcloud来改造,因为游戏集群也有注册中心,需要服务发现和启动顺序,但是springcloud并不是为游戏设计的。比如至少要完全支持webflux(我没仔细研究过),如果需要单线程长连接,最好支持protobufrpc框架(集成服务发现相关功能和接口),网关支持tcp或者至少封装或者暴露一些nettydecoder编码器(或者允许注入)等等。