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

为什么王者荣耀不用微服务架构?

时间:2023-03-13 17:27:28 科技观察

今天在知乎上看到这个问题:“为什么游戏公司的服务器不愿意做微服务?1.背景介绍我最近面试了一家游戏公司(满大的,上市的),我问他,是否公司对微服务架构有什么规划和考虑?他很惊讶的说,我从来没有听说过微服务,你能解释一下吗?我大概说了,易测试,易维护,易升级,服务之间松耦合,多-语言开发,自动扩展...等等。然后他说游戏服务器不需要微服务,因为它需要RealTime,微服务会影响性能。还是模块开发好。我也不确定,但是微服务不是趋势吗?尤其是大公司,游戏服务器服务应该很容易拆分吧?接下来我们来看看两个高赞的回答2.hongjic93是这样回答的:MOBA游戏/王者荣耀/LOL,看看王者荣耀客户端就知道了瑞,想象一下。账号系统、符文系统、英雄系统、皮肤系统、好友系统、好友之间的消息,这些都是常规操作,如果流量够大,当然可以用微服务架构来做。但这不是这款游戏的核心。核心是MOBA:多人在线对战竞技场。有什么特点?10人之间各种游戏事件的高速多方位通讯,Streaming/Broadcast/Multicast/Pubsub多种通讯方式。所以游戏的核心在于小规模群体之间的高速网络交流。也就是对方所说的Realtime。如果多了10ms的延迟,玩家就会被骂。同一进程中的原始模块被拆分成不同的服务,这显着增加了额外的网络开销。别说ServiceMesh,各种Gateways,Proxy,Sidecar,就是担心延迟太低。②微服务基本上只有Request/Response模式。不能做流媒体?微服务通常要求应用程序是无状态的,以实现水平扩展。流媒体本身会添加状态。③我可以想象,为了提高通信的性能,一款英雄联盟游戏很可能会使用同一个服务器来负责这10个玩家之间的通信,这样就可以在本地交换数据,将性能最大化.要求客户端或服务端统一网关必须支持StickyRouting。假设客户端连接断开,下一个必须重新连接到与之前相同的服务器。微服务的无状态,水瓶扩展需求本身就是反粘路由,因为粘路由本身就是状态。④对于服务器集群,有无数个王者荣耀游戏同时进行,每个游戏都可以看作是一个沙盒,每个沙盒都处于不同的状态:推了多少塔,推了你杀了几次,对面还有几个超神。已经20分钟了吗?这些是长期存在的状态,直到游戏结束,服务器才能清理一局游戏的状态。所以虽然没有必要将这些状态写入到持久化存储中,但它们必然会长期存在于内存中。都是状态。反正有状态就别想用微服务了。除非你说把这些状态都移到Redis中,否则服务器会在信息流到一半的时候进行RemoteRequest,来来去去延迟会增加。反正也不好。(比如假设对方在你的水晶A中,A的每一次操作都是一个Event,流式传输到服务器的沙箱中,沙箱中有一个流处理器,你每次收到一个Event,你的水晶是A,它会计算你的水晶有没有爆炸。这个计算需要非常快,而且你不可能把你水晶的生命值数据存储在远端。)这类游戏对网络要求很高、内存和CPU优化。整个游戏过程中,几乎没有RPC调用。如果真的需要RemoteData,也应该是Rrefetch,在游戏刚开始的时候加载。微服务不是灵丹妙药,只是为了方便拆解原有的CRUD应用。一是没有触及高级交互方式,二是没有触及分布式系统真正的难点:状态,其实并没有大家想象的那么好用。之所以感觉微服务改变了互联网,是因为90%的互联网应用都只是简单的小规模增删改查。如果对方没有听说过微服务也没关系,因为它本身并不是一个高深的概念。相反,对方听了你就知道微服务不适合做游戏,说明对方理解能力强,对游戏系统设计理解足够深。3.Brice是这样回答的,他玩过棋牌游戏(最简单的一种游戏),他可以尝试说几点:①微服务本身就是一种新的接口组织方式,以应对复杂性的业务逻辑。游戏本身的逻辑其实并没有那么复杂。比如大厅,有一些基本的功能,比如修改账号,登录。游戏本身就是游戏本身的逻辑。②游戏逻辑服务器(如游戏等棋牌)本身因为网络响应性能要求(玩家对每次操作反馈时间的敏感度远高于业务系统)是有状态的,所以游戏服务器是有状态的。状态存在于内存中,偶尔接受Redis、MySQL等是绝对不能接受的。关系型行数据库只是用于定时异步持久化数据,只有游戏服务器才可以将数据持久化到Redis中。③游戏服务器一般需要主动推送,第一代微服务网关无法满足需求。TCP没有网关,可以使用SpringCloudGateway的WebSocket(但是从防攻击的角度来说,端游使用TCP肯定比WebSockets有意义)。④服务间通信RPC首先,Ribbon、Feign等不适合,因为它们都是基于HTTP的,HTTP存在消息乱序问题。例如,如果玩家打了两次牌,那么HTTP中的顺序可能不一致。游戏服务器集群一般使用长连接互连。也许你需要使用Dubbo?(据说是长连接)⑤游戏逻辑服务器(比如游戏服务器),一般不能用SpringMVC来做,因为线程模型完全不同。多线程模型游戏性能差,非常复杂。一般用单个进程/线程驱动固定数量的房间(这就是为什么服务器必须有状态,不能直接读写MySQL)。一般直接使用Netty。⑥自动扩容在游戏端称为开服,已经有固定的流程、工具和限流方式。⑦游戏中很多操作没有服务降级断路器。如果失败,则直接向用户报错。⑧大厅服务器登录注册等确实可以作为微服务使用,但实际上它们不是微服务,只是几个接口自动横向扩展的方案。发现注册服务用处不大,开服是板上钉钉的事,还有一系列操作手段配合,关服千万不能随便关。⑨游戏处理的流量真的不多。10000的在线棋牌游戏已经可以赚很多钱了,100000是特别厉害的产品。⑩一些独立的服务器,比如充值,需要做微服务吗?只能说这种服务端需要微服务来处理,项目组才能梦寐以求。虽然上面说了很多点,其实可以考虑用SpringCloud来改造,因为游戏集群也是有注册中心的,需要服务发现和启动顺序,但是SpringCloud并不是为游戏设计的。比如至少要全面支持Webflux(没仔细研究),如果需要单线程长连接最好支持ProtobufRPC框架(集成服务发现相关功能和接口)。网关支持TCP或者至少封装或者暴露一些Netty的Decoder编码器(或者允许注入)等等。作者:hongjic93、brice编辑:陶佳龙来源:zhihu.com/question/359630395/answer/954452799