介绍Quilkin:为游戏服务器通信而构建的开源UDP代理

Google Cloud 在 Quilkin 发布时发表的介绍博客文章

原文来自 Google Cloud Blog 上的博客文章 Introducing Quilkin: the open-source game server proxy

传统上,实时多人游戏的专用游戏服务器已经在使用定制的UDP协议,用于游戏内玩家之间的通信和游戏同步。这种通信通常被捆绑在单体游戏服务器和客户端中,将通信协议的技术功能,如定制的网络物理同步、安全、访问控制、遥测和度量,与物理模拟、人工智能计算等极高的计算要求配对。

Quilkin 是与 Embark工作室 合作开发的一个UDP代理,为高性能的实时多人游戏量身定做。它的目的有两个方面:

  1. 将安全、访问控制、遥测和指标等通用功能从单体的专用游戏服务器和客户端中剥离出来。

  2. 以一种可组合和可配置的方式提供这些通用功能,这样它就可以在广泛的多人游戏中重复使用。

这种可重复使用的基础使游戏开发者能够将更多的时间集中在构建多人通信协议的游戏特定方面,而不是这些通用方面。

多人游戏服务器通信的挑战

在快节奏的多人游戏中,一段游戏的完整模拟通常发生在一个单体的专用游戏服务器的内存中,其职责涵盖了从网络物理学和人工智能模拟到从客户端回到服务器的通信等一切。

由于游戏的整个状态是常驻内存的,每个客户端直接连接到玩家正在玩的专用游戏服务器上,这带来了几个挑战:

  • 每个专用游戏服务器都是单点故障。如果它发生故障,那么整个游戏会话(有时是多个会话)都会失败。这使得它成为恶意攻击者的目标。

  • 连接到游戏服务器的IP和端口是公开的,并暴露给游戏客户端,使其很容易被发现并成为目标。

  • 游戏服务器模拟和网络通信的多个方面被紧密地耦合在同一个过程中,使得重用和模块化更加困难,并扩大了性能问题的风险。

我们看看过去几年的网页和移动技术,这些挑战中的一些开始看起来非常熟悉。值得庆幸的是,帮助推动专用服务器工作负载转向更多的冗余和分布式协调的解决方案之一是利用流量代理!

通过在低延迟网络(如 what is available on Google Cloud )中的专用游戏服务器前使用多人UDP流量代理,我们可以解决这些关键挑战,具体如下:

  • 更高的可靠性。代理提供了冗余的通信入口。UDP数据包可以被发送到任何数量的代理,并被路由到专用游戏服务器。虽然专用游戏服务器通常仍然是单点故障,但代理提高了通信层的冗余度和潜在的故障转移。

  • 更好的安全性。专用游戏服务器的IP和端口不再是公开的。游戏客户可能只看到代理池的一个子集,限制了潜在的攻击面。

  • 更大的可扩展性。我们开始打破单一进程,因为我们可以将通信协议、指标、通信安全和访问控制的各个方面移到代理中。这就把非游戏的具体计算从游戏服务器的处理循环中移除。

因此,整个系统现在更有弹性,因为代理可以独立扩展,不仅是为了性能原因,也是为了在出现恶意行为时分发负载。

引入Quilkin:游戏服务器的UDP代理

Embark StudiosGoogle Cloud 携手同行一起建立了Quilkin,以提供一个标准的、开源的解决方案。 Embark工作室位于斯德哥尔摩,是一个由经验丰富的行业老手组成的(相对)新工作室。 鉴于其团队在大型实时多人游戏方面的经验,他们是创建Quilkin的完美合作伙伴。

Quilkin是一个开源的、非透明的UDP代理,专门设计用于大规模多人专用游戏服务器的部署,以确保安全、访问控制、遥测数据、指标等。

Quilkin被设计为在游戏客户端后面以及在专用游戏服务器前面使用,并提供以下主要优势:

  • 混淆视线。对UDP数据进行非透明的代理,使游戏架构的内部状态对不良攻击者不那么明显。

  • 开箱即用的度量。用于UDP数据包的流量和通信。

  • 可见性。一套可组合的处理过滤器,可应用于路由、访问控制、限速等方面。

  • 灵活性。能够作为独立的二进制文件使用,不需要改变客户端/服务器;也可以作为Rust 类库使用,这取决于你希望为你的系统和你希望建立的自定义处理过滤器进行多深的整合。

  • 兼容性。如有需要,可以通过 Rust FFI 与现有的 C/C++ 代码库集成。

  • 就绪。多种集成模式,允许您选择对您的架构和现有平台有意义的集成级别。

到目前为止,这类能力只提供给有资源建立自己的专有技术的大型游戏工作室。

我们认为,为游戏行业的每个人提供公平的竞争环境是一项重要而值得的努力。这就是为什么我们与谷歌云合作,共同发起这个项目。

在Embark,我们相信开源是游戏行业的未来,开放的、跨公司的合作是未来的方向,这样所有的工作室,无论大小,都能达到相同的技术能力水平。

—— Luna Duclos, Embark工作室技术负责人

谷歌云很高兴地宣布Quilkin成为我们的游戏开源解决方案组合中的最新项目。 Quilkin补充了我们现有的开放源码解决方案(OSS),包括用于游戏服务器的Agones,用于匹配的 Open Match,以及用于持久化的Open Saves。 这些解决方案被设计为一起工作,成为一个开放和集成的游戏生态系统。 我们很自豪地将Embark Studios与Ubisoft、Unity和2K Games一起作为我们最新的游戏开源合作者。 谷歌云将继续与我们在行业和社区的合作伙伴密切合作,提供全球规模的解决方案,以支持世界上最大的游戏。

—— 谷歌游戏云首席架构师 Rob Martin

开始使用Quilkin

虽然Quilkin可以支持上述更高级的部署方案,但开始使用Quilkin的最简单方法是将其作为sidecar部署到现有的专用游戏服务器上。这最初可能会限制一些好处,但这是获取UDP通信指标和遥测数据的简单途径,入门门槛很低,并能随着时间的推移进行扩展。

虽然Quilkin以二进制文件和容器镜像的形式发布,并且不与任何特定的托管平台绑定,但我们将使用 AgonesGoogle Cloud Game Servers 作为本例中的游戏服务器托管平台。

首先,我们将创建 ConfigMap 来存储 Quilkin 静态配置的yaml,它将接受26001端口的连接,然后将其路由到 Xonotic(一个开源的多人FPS游戏)专用游戏服务器的26000端口:

apiVersion: v1
kind: ConfigMap
metadata:
  name: quilkin-config
data:
  quilkin.yaml: |  # quilkin configuration
    version: v1alpha1
    proxy:
      port: 26001
    static:
      endpoints:
        - address: 127.0.0.1:26000

其次,我们将以 Agones 为 Xonotic 专用游戏服务器提供的容器为例,在 Agones Fleet 的游戏服务器中,像这样在每个专用游戏服务器旁边运行Quilkin作为Sidecar:

apiVersion: "agones.dev/v1"
kind: Fleet
metadata:
  name: xonotic-sidecar
spec:
  replicas: 2
  template:
    spec:
      container: xonotic
      ports:
        - name: default
          containerPort: 26001
          container: quilkin
      health:
        initialDelaySeconds: 30
        periodSeconds: 60
      template:
        spec:
          containers:
            - name: xonotic
              image: gcr.io/agones-images/xonotic-example:0.8
            - name: quilkin  # quilkin sidecar
              image: us-docker.pkg.dev/quilkin/release/quilkin:0.1.0
              volumeMounts:
                - name: config
                  mountPath: "/etc/quilkin"
              livenessProbe:
                httpGet:
                  path: /live
                  port: 9091
                initialDelaySeconds: 3
                periodSeconds: 2
          volumes:
            - name: config
              configMap:
                name: quilkin-config

一旦应用,当我们查询集群中正在运行的GameServers时,一切看起来都和没有Quilkin时一样。我们的系统中没有任何其他东西需要知道流量被拦截,我们可以自由地利用Quilkin的功能,而无需调整客户端或服务器代码。

$ kubectl get gameservers
NAME                          STATE   ADDRESS         PORT   NODE           AGE
xonotic-sidecar-gdpgn-2pfkc   Ready   34.95.106.201   7929   gke-0f7d8adc   25m
xonotic-sidecar-gdpgn-c8bds   Ready   34.95.106.201   7028   gke-0f7d8adc   25m

如果这引起了你的兴趣,请一定要看一下演练,在那里我们经历了同样的场景,然后扩展到压缩从游戏客户端到服务器的UDP数据包,而不需要改变任何程序。

然而,这只是表面现象:Quilkin还有更多的功能,包括兼容xDS的管理API,各种现有的过滤器来处理和路由UDP数据包等等。

Quilkin的下一步

Quilkin仍处于早期阶段,此次发布的是 0.1.0 alpha版本,但我们对已经奠定的基础非常满意。

路线图中有各种功能,从增强的指标和遥测,到新的过滤器和过滤器类型,等等。

如果你想尝试这个版本,你可以从我们的发布页面抓取二进制文件或容器镜像,通过我们的快速启动,并审查与你的专用游戏服务器的不同集成选项。

Embark工作室也发布了他们自己的公告博文,深入探讨他们对自己的生产游戏后台基础设施的计划,以及Quilkin在其中的作用。