乐趣区

关于运维自动化:新尝试我用-Serverless-部署了一个更稳定的游戏后端

异星工厂(Factorio)是我在 Steam 上游戏工夫最长的游戏,这是一个无关设计自动化流水线、察看流水线运行并一直地进行改良和扩容的游戏,在这样一个沙盒里能够施展你的创造力来建造工厂、解决工厂内的物流需要,一直超过本人,The Factory Must Grow!

异星工厂也反对多人游戏,和敌人们一起联机建工厂就更加乏味了,但因为家用网络的多层 NAT,想要和敌人们在互联网上相互直连是一个比拟麻烦也很不稳固的事件。刚好前一阵云引擎增加了 托管游戏后端 的能力,能够部署基于 UDP 的游戏(或其余类型的服务),于是我就开始尝试在云引擎上运行一个连接起来更稳固的服务器和大家一起玩耍。异星工厂的 多人模式 是一个十分典型的 Lockstep 架构(步进锁定,有时也称为帧同步),所有玩家连贯到房主(可能是一个玩家也可能是一个服务器),通过 UDP 向房主发送本人的动作,房主会收集每个 tick(1/60 秒)中玩家的动作来确认先后顺序,而后播送给其余玩家,最初实现所有玩家的游戏状态齐全同步的成果。

部署到云引擎

因为云引擎提供的是规范的 Linux 运行环境,并不限度运行在其中的过程应用什么技术栈,因而很容易将既有的游戏后端部署下来,云引擎提供了 leanengine.yaml 来自定义构建过程,所以咱们只须要几行脚本就能够从异星工厂的官网下载到游戏的服务器版本:

install:
  - curl -Lo factorio.tar.xz https://www.factorio.com/get-download/1.1.61/headless/linux64
  - tar --strip-components 1 -xf factorio.tar.xz
  - rm factorio.tar.xz
  - use: default
extraPorts:
  - name: factorio
    protocol: udp
    containerPort: 34197

云引擎反对通过 Git 或命令行工具等多种形式部署,这里不再开展介绍,详见 疾速开始部署游戏后端 的文档页面。

leanengine.yaml 中的 extraPorts 局部用于定义游戏服务器监听的端口,在这里是 UDP 34197 端口,云引擎会将其映射至一个公网端口上。

因为云引擎被设计用来反对可横向扩大的游戏后端,所以游戏后端的每个实例都会被调配一个独自的公网地址和端口供客户端连贯(只管异星工厂只能单实例运行),咱们须要通过一个 HTTP API 来获取公网连贯地址(相干文档):

$ curl -H 'X-LC-Id: SJjoXHWuhewHKV4Ojw' \
       'https://shared.cloud.tds1.tapapis.cn/1.1/engine/gateway/route?groupName=factorio&prod=1'

[
  {
    "name": "factorio",
    "protocol": "udp",
    "publicPort": 10280,
    "publicIp": "106.75.48.157"
  }
]

而后就能够在游戏中连贯了:

存档

在游戏跑起来之后咱们还要思考存档的问题,游戏服务器会每隔几分钟将内存中的游戏状态导出写入为一个存档文件(如 first-game.zip),然而云引擎以后还不提供长久的文件存储,实例重启或重新部署后,临时文件零碎上的文件就会失落。

于是我想到了检测存档文件的变动,应用 rclone 将文件同步到对象存储(如 S3)。相应地在每次重启后、游戏开始前再从 S3 上将存档下载回来。

我用一个简略的 Go 程序充当胶水代码,在启动游戏的同时,实现了创立、下载和同步存档的能力,残缺的代码(以及 leanengine.yaml)能够在 GitHub 看到。

存档的名字和对象存储的拜访密钥能够设置在云引擎的环境变量中,而不用硬编码在代码中:

更适宜游戏开发者

其实当初市面上曾经有很多专门托管异星工厂等游戏服务器的云服务了,它们更加简略易用,也更有性价比。但不同于这些服务,云引擎提供的更多的是面向开发者的托管游戏后端的能力,如欠缺和易用的构建、部署、日志和统计等能力。利用这些能力游戏开发者们能够轻松地部署自行开发的游戏服务器上来,在玩家数量减少时还能够利用云引擎提供的横向扩大能力来应答。

就像后面演示的那样,云引擎对尽管对 Node.js、Python、Java、PHP、Go、C/C++、C# 等罕用的技术栈都提供了反对,但并不限度理论应用的技术栈,也不存在供应商锁定(Vendor lock-in)。即便在我的项目的开发前期甚至实现后,也能够通过简略的适配运行在云引擎上,受害于云引擎提供的各种运维能力。

退出移动版