了解Edgegap的工作原理

了解Edgegap的工作原理

WebAssembly(WASM)能否取代 Docker 用于游戏服务器?

已发布

已发布

已发布

WebAssembly(WASM)能否取代 Docker 用于游戏服务器?

关键洞察

关键洞察

关键洞察

  • 二进制大小差距确实存在:完整的 Godot 4 游戏引擎编译后仅有 35MB 的 WebAssembly 二进制文件,大约比一个裸的 Node.js Docker 镜像小 10 倍,至少在纸面上,这使得 WASM 的效率优势很有说服力。

  • WASI 阻断了关键路径:WebAssembly 系统接口目前限制访问 TCP/UDP 套接字和文件系统,而多人游戏服务器正依赖这两者,因此服务器端支持目前更像是一个需要关注的限制,而不是已经解决的问题。

  • 线程和 WebSockets 让问题进一步复杂化:有限的原生线程迫使应用层采用变通方案,而将游戏流量通过 WebSockets 路由会带来握手开销和 CPU 成本,这些都是基于 UDP 的架构完全可以避免的。

  • 单人网页游戏是自然契合的场景:客户端 WASM 绕开了所有服务器限制,而像 Godot 这样的引擎本身就默认导出到 WebAssembly,不过这只适用于单人网页游戏,不适用于多人后端。

2026年5月,开发者Ivan Bogomolov在其个人博客上发表了一篇简短的博文,指出了一件引人注目的事情:一个完整的3D Godot 4游戏引擎,包含了GL Compatibility渲染器、Jolt物理引擎、GDScript运行时和一个叙事解释器,导出到WebAssembly后仅仅只有35MB。

作为对比:

  • 默认的Node.js Docker镜像大小为421MB。

  • Facebook主页加载的资源有44MB。

  • 而这个游戏引擎的大小比这两者都要小。

他的博文提出了一个顺理成章的后续问题:如果一个完整的游戏引擎编译后的大小仅为精简版Docker镜像的一小部分,那么WebAssembly是否也可以用作游戏服务器的容器呢?

简短的答案是:目前还不行。原因如下。

什么是WebAssembly?

WebAssembly(WASM)是一种旨在以接近原生速度在浏览器中运行的二进制指令格式。它被构建为一个编译目标:你用其他语言(如Rust、C或C++)编写代码,将其编译为WASM,生成的结果就可以在任何支持WASM运行时的环境中运行。无需安装,无需针对特定操作系统构建,在任何地方都能保持一致的行为。

这种可移植性正是其吸引力所在。一个能够同时在Chrome、Firefox、服务器或边缘节点上运行的单一二进制文件,听起来完全符合容器化部署工作流的需求。但在实践中,“在任何地方运行”与“运行游戏服务器”之间的差距被证明是巨大的。

体积优势:完整游戏引擎仅35MB

这些数据值得细细品味。一个完整的3D游戏引擎只有35MB,而一个精简版Python基础镜像在未添加任何依赖项前就有144MB,最新的Node.js镜像更是高达421MB。作为对比,Facebook主页加载的资源有44MB。游戏引擎比所有这些都要小。

体积上的差异出于实际的运营原因至关重要。更小的二进制文件意味着更快的游戏服务器冷启动(即镜像下载到服务器主机并启动游戏实例所需的时间)。对于自行运行编排系统的游戏工作室而言,镜像分发产生的出网流量成本也是需要稍加考虑的因素,不过在托管平台上,这部分成本通常由服务商承担,而不是直接向工作室计费。

对于构建了自身内部编排系统的工作室(例如使用Agones的工作室),冷启动时间和镜像仓库容量是需要进行专门工程投入才能解决的制约因素。而在托管平台上,这些问题在设计之初就已被解决:例如Edgegap平台从冷启动开始的服务器部署时间中位数仅为2秒(根据其平台数据,从头配置并计算至容器就绪),并包含10GB的容器镜像仓库。对出网流量如何影响其特定基础设施成本感到好奇的工作室,可以通过Edgegap的定价机制,使用我们的游戏服务器托管计算器来了解其对自身架构的影响。

这种效率优势使得WASM值得作为一种服务器技术被认真对待。但问题在于,二进制文件体积仅仅是游戏服务器所需考量的一个维度。

服务器问题始于WASI

要在浏览器之外运行,WebAssembly需要一个与底层操作系统交互的接口。

这个接口就是WASI:WebAssembly系统接口(WebAssembly System Interface)。正是WASI让WASM二进制文件在服务器运行时而非浏览器沙箱中运行时,能够访问文件、环境变量和标准I/O。

问题在于WASI目前所施加的限制。取决于运行时和语言组合,TCP和UDP套接字(socket)要么不可用,要么受到严格限制。文件系统访问模型是基于权能(capability-based)且受到严格沙箱隔离的。对于Web API或无服务器函数(Serverless Function),这些约束是可应对的。但对于游戏服务器而言,它们则是致命的阻碍。

多人游戏服务器依赖套接字运行。它们需要原始UDP来实现快速、低开销的数据包传输。它们还需要文件系统访问权限来处理配置、日志记录和状态持久化。

截至2026年,现阶段的WASI无法在游戏服务器所需的层面上为这两者提供可靠的支持。正如Bogomolov在他的博文中直言不讳地指出:“wasip1仍处于预览阶段,标准运行时中没有套接字。”

语言支持情况更让问题雪上加霜:目前只有Rust和C/C++是实用的WASM编译目标。Go的wasip1支持仍处于预览阶段。Zig则尚未就绪。仅这一限制就决定了绝大多数工作室甚至根本无法尝试构建WASM服务器版本。

没有线程的“多线程”

游戏服务器并不是单线程程序。物理模拟、网络I/O、游戏状态同步和玩家输入处理通常并发运行。游戏引擎在设计之初就是基于这一假设的。

WebAssembly的线程支持非常有限。现有机制需要在应用层采用变通方案,利用中断和协作式调度来近似实现并发执行。其结果并不等同于真正的操作系统线程。它引入了协调开销,增加了代码复杂性,并在高负载下使调试变得更加困难。

即便一家工作室解决了WASI的套接字限制,在游戏服务器能够在大规模下正常运行之前,他们仍必须解决线程问题。这些都不是细微的集成工作,而是当前WASM规范中存在的根本性架构缺陷。

即便解决了上述所有问题:WebSocket之墙

假设一个团队投入了大量工程精力绕过了WASI的套接字限制,并构建出了能在高压下稳定运行的线程模型。

前方仍然横亘着一道高墙:WebSocket。

WASM服务器运行时默认通过WebSocket进行通信。WebSocket基于TCP运行,在每条消息之上都增加了一个持久连接层,附带自身的握手开销、成帧机制以及安全协商。对于浏览器而言,这完全可以接受。但对于游戏流量来说,这极其昂贵。

游戏选择UDP而非TCP是有原因的。UDP轻量且快速,没有握手,没有保证送达的开销,也没有队头阻塞问题。迟到的数据包会被直接丢弃,这远比停滞连接以等待重传要好得多。从延迟补偿到回滚机制,整个游戏网络代码技术体系都是围绕UDP的特性构建的。

改用WebSocket来路由游戏流量,会抹杀WASM较小二进制体积原本应带来的大部分性能优势。服务器最终要么将CPU周期浪费在WebSocket开销上,要么在大规模并发时遇到DNS解析问题,或者产生让这种部署方式在经济上难以成立的出网流量成本。

插件兼容性:(隐性的)移植代价

除了基础设施层面的限制外,还存在一项工作室很少预先考虑的实际开发成本。大多数资源商店资源包、引擎插件和第三方SDK都无法自动编译为WebAssembly。它们的目标平台是原生系统:Windows、Linux、macOS。

移植它们需要大量的人工工作。与基于Docker的部署相比,WASM游戏开发方面的社区支持较为薄弱。文档匮乏,教程罕见,边界情况往往要等到团队深入项目后才会被发现。

对于高度依赖插件的工作室,或者缺乏深厚系统级编程背景的团队来说,无论理论上的效率提升多么诱人,单单是移植负担就足以让基于WASM的服务器方案变得不切实际。

WASM目前真正的用武之地:单人WebGL游戏

有一个领域让WASM能够完全避开上述所有限制:客户端单人Web游戏。

在浏览器中运行的单人游戏不需要原始UDP套接字。它不需要操作系统级别的多线程。它也不需要与为原生目标构建的插件生态系统进行交互。浏览器提供了一个受控环境,WASM的这些限制对于该用例而言根本无关紧要。

Godot很好地印证了这一点。该引擎在面向Web目标时默认导出为WebAssembly。一款单人Godot游戏只需打包为一个35MB的二进制文件,就能在任何现代浏览器中免安装运行。而对于Linux服务器部署,Godot则会导出为原生二进制文件。这种区别并非偶然:它准确地反映了WASM目前的能力上限所在。

Rust与WebAssembly生态系统也呈现出类似的情况。被最广泛引用的WASM学习资源之一是官方Rust与WebAssembly教程书,它通过构建一个基于浏览器的WASM康威生命游戏(Conway's Game of Life)项目来进行讲解。这是该技术运行良好的典型范例。但它同样是一个单人、依赖浏览器的应用程序,完全没有服务端网络需求。

WASM非常适合单人Web游戏。但多人游戏后端则完全是另一回事。

见解:技术采纳曲线

将WASM作为服务端技术运行的基础设施已经存在,至少以实验形式存在。Cloudflare Workers在边缘运行WASM模块。containerd/runwasi为containerd带来了WASI工作负载支持。KWasm为Kubernetes节点增加了WebAssembly支持,尽管其维护者目前建议不要在生产环境中使用它。相关工具正在被审慎地构建。

这种发展轨迹类似于ARM节点进入云基础设施讨论的过程。在ARM成为云工作负载的默认选择之前,它在成本和密度方面的真正优势已经展现了多年。早期的技术论点非常明确。采纳之所以滞后,是因为生态系统成熟度、工具链支持和组织惯性等原因。但后来,这一局面被彻底打破。

明确地说,WASM在游戏服务器领域是否会遵循相同的轨迹,目前只是一种观点而非既定规律。当前的限制是具体且有据可查的。何时能改变这些限制以及改变的步伐,取决于浏览器厂商、运行时维护者和标准组织的决策。Bogomolov在博文的最后提出了同样一个悬而未决的问题:“为什么WASM的普及停滞了?传输体积的优势早已显而易见。”

这是一个合理的问题。对于游戏服务器而言,答案在于:二进制文件的体积从来都不是唯一的问题。

如今你能做什么

在2026年,WASM还不是一个可行的游戏服务器容器。对于部署专用多人游戏服务器的工作室来说,Docker仍然是务实之选,围绕它的运维工具链成熟、文档完善且受广泛支持。

话虽如此,他的观察所引发的效率问题是真实存在的。服务器二进制文件的大小确实关乎冷启动性能和出网成本,工作室完全可以利用现有工具采取切实可行的措施。对于Unreal Engine,Edgegap发布了一份关于通过服务器分析来分析和优化游戏服务器构建版本的指南。对于Unity,Edgegap的文档中直接涵盖了服务器构建版本优化指南。

WASM未来可能在体积方面带来的收益,今天借助现有的工具就能实现,而无需等待生态系统的成熟。

—

本文取材自Ivan Bogomolov发表在其个人博客上的原创文章。原始内容的所有权利均归各自所有者所有。

书写者

Jakub Motyl,Edgegap 的产品经理

Get your Game Online Easily & in Minutes

立即开始集成!

轻松在线游戏
且在几分钟内

Get your Game Online Easily & in Minutes