找回密码
立即注册
搜索
发回帖 发新帖

6568

积分

0

好友

831

主题
发表于 昨天 22:27 | 查看: 6| 回复: 0

今天在知乎上刷到一个挺有意思的问题:“为什么游戏公司的 server 不愿意微服务化?”

这其实是个很典型的认知反差:微服务在互联网后端几乎成了标配,可一到游戏领域,尤其是像王者荣耀这种 MOBA 游戏,怎么就被冷落了呢?

背景:一次面试引发的疑问

有位开发者分享了自己去一家游戏公司面试的经历。

那家游戏公司规模不小,已经上市了。他问面试官:公司有没有做微服务架构的打算?

对方一听,表情挺惊讶的:“微服务?没听说过,你能解释一下吗?”

于是他简单说了几点:方便测试、方便维护、方便升级、服务之间松耦合、支持多语言开发、自动扩容等等。

没想到对方的回应更直接:游戏 server 不太需要微服务,因为游戏要求 realtime,微服务会影响性能,按模块拆分开发就可以了。

这个回答让他有点不确定了。微服务不是行业趋势吗?大公司尤其应该用才对啊。游戏 server 的服务看起来也不难拆分吧?

王者荣耀巅峰赛结算界面截图

回答一:MOBA 游戏的核心不是 CRUD,是实时通信

先看第一位答主的分析。

拿 MOBA 类游戏举例,比如王者荣耀、LOL。客户端里确实有很多常规系统:账号、符文、英雄、皮肤、好友、好友消息。这些业务如果流量够大,用微服务架构去做完全没问题。

但问题在于——这些都不是游戏的核心。

MOBA 的真正核心是什么?Multiplayer Online Battle Arena,多人在线战术竞技。它的特点是:10 个人之间各种游戏事件的高速多向通讯,streaming、broadcast、multicast、pubsub 各种通讯模式都要用上。

所以游戏的核心,是小规模群体之间的高速网络通信。也就是面试官说的 realtime。

多 10ms 延迟,玩家就要开骂了。

那微服务在这里会带来什么问题?

第一,微服务为了把业务完美拆解,把原来同一个进程里的模块拆分成不同的服务,必然会显著增加额外的网络开销。更别说什么 service mesh,各种 gateway、proxy、sidecar,简直就是担心延迟不够高。

第二,微服务基本只有 request/response 模式。做不了 streaming 吗?其实微服务通常要求应用无状态才能水平扩展,而 streaming 本身就是一种状态。

第三,为了提高通讯性能,一场英雄联盟游戏很可能会由同一台服务器负责这 10 个玩家之间的全部通讯。这样数据可以在本地交换,性能最大化。但这对客户端或服务端统一网关的要求是必须支持 sticky routing——客户端断线重连后,必须重连到之前那台服务器。而微服务的无状态、水平扩展要求,本身就是反 sticky routing 的。

第四,从服务端集群的角度看,同一时刻有无数场王者荣耀比赛在进行。每一场都可以看作一个沙盒,每个沙盒都处在不同的状态:塔被推了几个、你死了几次、对面几个超神了、20 分钟到了没。这些都是长时间存在的状态,直到游戏结束才能清理。

所以游戏服务器天然就是有状态的,内存里长时间保存着对局状态。有状态,就别想用微服务。除非把这些状态移到 Redis 里去?每次信息流传输到一半还得做一次 remote request,一来一回延迟又上去了。

想象一下对方在 A 你的水晶,每一次普攻都是一个 event 被 streaming 到服务端沙盒中。沙盒里有一个流处理器,每收到一个“水晶被 A”的 event 都要立刻计算水晶爆了没。这个计算要求极快,不可能把水晶生命值存在远端。

像这类游戏,对网络、内存、CPU 的优化需求都很高。整个游戏过程中几乎不存在什么 RPC call,真的需要远端数据,也应该在游戏开局时 prefetch 预先加载好。

微服务不是银弹。它更多是方便拆解 CRUD 应用,一没触及高级的交互方式,二没触及分布式系统真正的难点:状态。之所以感觉微服务改变了互联网,只不过因为 90% 的互联网应用本身就只是简单小规模的 CRUD。

那位面试官没听说过微服务,完全没问题。这本来就不是什么高深概念。反而对方一听就判断出微服务不适合游戏,说明理解能力很强,对游戏系统设计的认知也足够深。

回答二:从棋牌游戏看游戏服务器的特殊约束

另一位做过棋牌游戏的答主也补充了不少实操层面的细节。

棋牌游戏算是游戏里最简单的一类了,但即便如此,游戏服务器和普通业务后端还是有本质区别。

业务复杂度不在一个量级。 微服务是为了应对业务逻辑的复杂化而生的组织接口方式。但游戏本身的逻辑没那么复杂——大厅就是登录、改账号这些基础功能,游戏内就是游戏本身的逻辑。

游戏逻辑服务器必须有状态。 由于玩家对每个操作的反馈时长敏感度远高于业务系统,游戏服务器都是把状态存在内存里的。偶尔接受 Redis,但绝对不可能直接读写 MySQL。关系型数据库只用于定时异步持久化数据,游戏服务器用 Redis 持久化就够了。

主动推送是刚需。 游戏服务器普遍需要主动向客户端推送消息,第一代微服务网关根本满足不了。TCP 没有合适的网关可用,Spring Cloud Gateway 的 WebSocket 或许能凑合,但从防攻击角度讲,端游用 TCP 远比 WebSocket 合理。

服务间通信不能靠 HTTP。 服务间 RPC 首先排除 Ribbon、Feign 这类基于 HTTP 的方案。HTTP 存在消息乱序问题——比如玩家连续出牌两次,经过 HTTP 传输后次序可能就不一致了。游戏服务器集群一般使用长连接互联,可能需要用 dubbo?听说是长连接。

线程模型完全不同。 游戏逻辑服务器一般不能用 Spring MVC 来做,线程模型就不匹配。多线程模型处理游戏逻辑性能差而且非常复杂,一般都是用单进程/单线程驱动固定数量房间的方式。这也是为什么服务器一定有状态、一定不能直接读写 MySQL。通常直接用 Netty 就完事了。

自动扩容在游戏里叫开服。 早就有固定流程、工具和限流方式了,不需要微服务那套弹性伸缩。

服务降级熔断不适用。 游戏里很多操作不存在降级一说,不行就直接报错给用户。

大厅服务器可以做微服务? 其实也不是真正的微服务,就是几个接口做自动水平扩容的方案。服务注册发现用处不大——开服都是确定的事情,有一系列运营手段配合,关服也绝对不能随便关。

流量规模完全不是问题。 棋牌游戏在线 1 万人已经很赚钱了,10 万在线就是特别厉害的产品了。根本不需要微服务来扛流量。

充服务器需要微服务化? 只能说如果这种服务器都需要微服务处理了,项目组做梦都能笑醒。

当然,也不是说 Spring Cloud 完全不能用于游戏。游戏集群一样有注册中心、需要服务发现、需要编排启动顺序。只是 Spring Cloud 并没有为游戏场景设计——比如至少要完全支持 WebFlux,需要单线程长连接且最好支持 Protobuf 的 RPC 框架(集成服务发现相关能力),网关要支持 TCP 或至少暴露 Netty 的 decoder/encoder 接口。

如果对微服务架构在业务拆分、网关、服务保护这些方向上的完整实践感兴趣,可以系统性地看看 Spring Cloud 微服务架构深度解析与核心技能精讲。它能帮你理清微服务的适用边界,也能更好地理解为什么有些场景不适合微服务化。




上一篇:Firecrawl 接入 Codex:18.4 万 Star 的开源爬虫,让 AI 真正看懂网页
下一篇:风控组件就该这么设计:Redis+Lua 计数 + 注解 AOP 通用方案
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-10-22 08:09 , Processed in 0.070223 second(s), 42 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表