亚马逊AWS官方博客

Amazon GameLift 高阶使用技巧(五)- 使用 Game Server Wrapper 快速构建游戏服实战指南

Game Server Wrapper 是专为游戏服务器快速接入 Amazon GameLift 设计的轻量化工具,无需深度集成 SDK 即可实现游戏服务与 GameLift 的无缝对接。它完美适配快速原型验证、敏捷开发迭代及早期压力测试场景,并支持快速将现有的项目部署到 GameLift 上,支持以下三种 GameLift Fleet 部署模式:

  1. Anywhere Fleet
    可在亚马逊云科技尚未覆盖的地理区域(如自有IDC或边缘节点)部署游戏服务器,同时继承 GameLift 的核心功能(游戏会话管理、扩缩容等),实现玩家就近接入与延迟优化。
  2. Managed EC2 Fleet
    基于亚马逊云科技全托管 EC2 基础设施,零运维成本部署游戏服务。通过配置驱动弹性扩缩,自动应对玩家流量波动。
  3. Managed Container Fleet
    以容器化方式运行游戏服务器,精细化分配 CPU/内存资源。支持混合调度游戏与非游戏负载,最大化资源利用率。

通过 Anywhere Fleet 部署,客户可以保护原有的历史投资,将原有投资的硬件或其他云资源继续使用,同时仍能利用 GameLift 的核心游戏服务功能。将服务部署在离玩家群体更近的位置,优化玩家的游戏延迟。通过 Managed EC2 Fleet 部署,利用完全托管的基础设施部署您的服务,可以实现零基础设施的管理,通过简单的配置即可实现游戏服的弹性扩缩。通过 Managed Container Fleet 部署,您还可以获得更精细的资源分配能力,精确的为每个游戏服务器分配 CPU 和内存资源。

本文将以一个猜数字游戏为例,通过实战演示如何利用 Game Server Wrapper 在 GameLift 上快速构建游戏服务。您将掌握从本地调试到三种 Fleet 部署的完整流程,为实际项目落地提供参考。

先决条件

部署示例

在接下来的部署步骤中,您将在最开始部署一个在本地运行猜数字的示例游戏,在完成后,将该游戏的战斗服通过 Anywhere Fleet、Managed EC2 Fleet、Managed Container Fleet 这三种不同部署方式交由 GameLift 去做管理。

本文所有操作基于 Amazon Linux 2023 操作系统,并选用 C6a.large 实例规格进行构建部署。

准备工作

运行以下命令下载 Game Server Wrapper 代码并进行编译。

git clone https://github.com/amazon-gamelift/amazon-gamelift-servers-game-server-wrapper.git
cd amazon-gamelift-servers-game-server-wrapper
make

注意:默认情况下,生成的 Wrapper 二进制文件将与打包环境的操作系统及 CPU 架构相关。

运行以下命令下载游戏示例代码并切换到 demo 分支进行编译。

git clone https://github.com/aws-samples/sample-guess-number-game.git
cd sample-guess-number-game
git fetch
git switch demo
make

在游戏示例代码中,主要包括以下内容:

  • client:游戏的客户端代码,用于玩家进行游戏交互
  • lobby-server:大厅服服务,返回固定的战斗服地址给到玩家进行游戏
  • lobby-server-gamelift:大厅服服务,用于匹配玩家并申请游戏会话,基于 GameLift 申请游戏会话
  • battle-server:战斗服服务,用于玩家连接后进行游戏对战

设置当前账户和区域。

export ACCOUNT_ID=$(aws sts get-caller-identity --output text --query Account)
export AWS_REGION=<your-region>

注意:将 <your-region> 替换为实际区域,确保选择的区域支持 Managed Container Fleet 及 Anywhere Fleet 的部署。

本地运行

在部署到 GameLift 前,您可以先在本地运行示例游戏,分别执行以下步骤:

  1. 运行客户端服务:cd sample-guess-number-game/out/client/ && ./client
  2. 运行大厅服服务:cd sample-guess-number-game/out/lobby-server && ./lobby-server
  3. 运行战斗服服务:cd sample-guess-number-game/out/battle-server/ && ./battle-server

在浏览器中打开 http://<your-ec2-ip>:8000  进行访问,确保 EC2 实例的安全组已放行 8000,8080 及 8081 端口。

修改客户端中的大厅服的地址为 EC2 的公网IP并点击 Set Lobby Server Address 按钮进行提交。在开启两个游戏客户端后,即可通过 Start Game 按钮开始游戏。

在本地运行时,大厅服会返回固定的战斗服地址给到客户端用于连接游玩。接下来,将使用不同的方式进行部署,实现使用 GameLift 来进行战斗服的管理。

Anywhere Fleet 部署

运行以下命令创建 Location。

export LOCATION_NAME=custom-location-1
aws gamelift create-location \
    --location-name ${LOCATION_NAME} \
    --region ${AWS_REGION}

注意:LOCATION_NAME 可以按需进行命名,保存命令返回的 LocationArn 用于后续步骤。

运行以下命令创建 Anywhere Fleet。

export FLEET_NAME=anywhere-fleet-1
aws gamelift create-fleet \
  --name ${FLEET_NAME} \
  --compute-type ANYWHERE \
  --locations "Location=${LOCATION_NAME}" \
  --region ${AWS_REGION}

注意:保存命令返回的 FleetArn 和 FleetId 用于后续步骤。

将战斗服放置到 Wrapper 下,在 amazon-gamelift-servers-game-server-wrapper 文件夹中运行以下命令。

mkdir out/linux/amd64/gamelift-servers-anywhere/MyGame
cp ../sample-guess-number-game/out/battle-server/battle-server \
    out/linux/amd64/gamelift-servers-anywhere/MyGame/

修改 out/linux/amd64/gamelift-servers-anywhere/config.yaml 文件如下:

log-config:
  wrapper-log-level: debug

anywhere:
  provider: aws-profile
  profile: default
  location-arn: <your-location-arn>
  fleet-arn: <your-fleet-arn>
  ipv4: <your-ec2-ip>

ports:
  gamePort: 8081

game-server-details:
  executable-file-path: ./MyGame/battle-server
  game-server-args:
    - arg: "--port"
      val: "{{.GamePort}}"
      pos: 0

执行以下命令以运行游戏:

  1. 运行客户端服务:cd sample-guess-number-game/out/client/ && ./client
  2. 运行大厅服服务:cd sample-guess-number-game/out/lobby-server-gamelift && ./lobby-server-gamelift --fleet-id <your-fleet-id> --region ${AWS_REGION} --location ${LOCATION_NAME}
  3. 运行战斗服服务:cd amazon-gamelift-servers-game-server-wrapper/out/linux/amd64/gamelift-servers-anywhere/ && ./amazon-gamelift-servers-game-server-wrapper

使用前面步骤中返回的 FleetId 代替 <your-fleet-id>,根据前面本地运行的介绍方式访问游戏客户端。

在 Anywhere Fleet 的部署方式中,您的战斗服可以运行在任意的服务器上,由 GameLift 帮助您完成游戏会话的管理。

Managed EC2 Fleet

修改 out/linux/amd64/gamelift-servers-managed-ec2/config.yaml 文件如下:

log-config:
  wrapper-log-level: debug
  game-server-logs-dir: ./game-server-logs

ports:
  gamePort: 8081

game-server-details:
  executable-file-path: ./MyGame/battle-server
  game-server-args:
    - arg: "--port"
      val: "{{.GamePort}}"
      pos: 0

在 amazon-gamelift-servers-game-server-wrapper 文件夹中,运行以下命令构建 GameLift Build。

export BUILD_VERSION=gamelift-test-2025-05-13-1
mkdir out/linux/amd64/gamelift-servers-managed-ec2/MyGame
cp ../sample-guess-number-game/out/battle-server/battle-server \
    out/linux/amd64/gamelift-servers-managed-ec2/MyGame/
aws gamelift upload-build \
    --name gamelift-test \
    --build-version ${BUILD_VERSION} \
    --build-root out/linux/amd64/gamelift-servers-managed-ec2 \
    --operating-system AMAZON_LINUX_2023 \
    --server-sdk-version 5.2.1 \
    --region ${AWS_REGION}

注意:当上传 Build 完成后,保存返回的 Build ID 用于后续步骤。

运行以下命令创建 Managed EC2 Fleet。

aws gamelift create-fleet \
    --name 'gamelift-managed-ec2-fleet' \
    --description 'gamelift-managed-ec2-fleet' \
    --build-id <your-build-id> \
    --ec2-instance-type c6a.large \
    --ec2-inbound-permissions 'FromPort=37000,ToPort=37020,IpRange=0.0.0.0/0,Protocol=UDP' \
                              'FromPort=37000,ToPort=37020,IpRange=0.0.0.0/0,Protocol=TCP' \
    --compute-type EC2 \
    --region ${AWS_REGION} \
    --runtime-configuration '{
        "ServerProcesses": [
            {
                "LaunchPath": "/local/game/amazon-gamelift-servers-game-server-wrapper",
                "ConcurrentExecutions": 1,
                "Parameters": "--port 37000"
            },
            {
                "LaunchPath": "/local/game/amazon-gamelift-servers-game-server-wrapper",
                "ConcurrentExecutions": 1,
                "Parameters": "--port 37001"
            }
        ]
    }'

注意:使用上一步返回的 Build ID 代替 <your-build-id>,保存创建后响应的 FleetId 用于后续步骤。

执行以下命令以运行游戏:

  1. 运行客户端服务:cd sample-guess-number-game/out/client/ && ./client
  2. 运行大厅服服务:cd sample-guess-number-game/out/lobby-server-gamelift && ./lobby-server-gamelift --fleet-id <your-fleet-id> --region ${AWS_REGION} --location ${AWS_REGION}

使用前面步骤中返回的 FleetId 代替 <your-fleet-id>,根据前面本地运行的介绍方式访问游戏客户端。

在 Managed EC2 Fleet 部署方式中,您不再需要管理任何的战斗服相关服务器,GameLift 帮助您完成服务器及游戏会话的管理。

Managed Container Fleet

修改 out/linux/amd64/gamelift-servers-managed-containers/config.yaml 文件如下:

log-config:
  wrapper-log-level: debug
  game-server-logs-dir: ./game-server-logs

ports:
  gamePort: 8081

game-server-details:
  executable-file-path: ./MyGame/battle-server  

在 amazon-gamelift-servers-game-server-wrapper 文件夹中,运行以下打包镜像。

mkdir out/linux/amd64/gamelift-servers-managed-containers/MyGame
cp ../sample-guess-number-game/out/battle-server/battle-server \
    out/linux/amd64/gamelift-servers-managed-containers/MyGame/
docker build --platform=linux/amd64 \
    -t gamelift-sdk-wrapper-sample:latest \
    out/linux/amd64/gamelift-servers-managed-containers \
    --progress=plain
docker tag gamelift-sdk-wrapper-sample:latest \
    ${ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/gamelift-sdk-wrapper-sample:latest

运行以下命令,将打包好的镜像上传到 ECR。

aws ecr create-repository \
    --repository-name gamelift-sdk-wrapper-sample \
    --region ${AWS_REGION}
aws ecr get-login-password \
    --region ${AWS_REGION} | docker login \
    --username AWS \
    --password-stdin ${ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com
docker push ${ACCOUNT_ID}.dkr.ecr.${AWS_REGION}.amazonaws.com/gamelift-sdk-wrapper-sample:latest

运行以下命令,创建 Container Group。

export CONTAINER_GROUP_NAME=gamelift-sdk-wrapper-sample
CONTAINER_DEF='{
  "ContainerName": "GameServer",
  "ImageUri": "'${ACCOUNT_ID}'.dkr.ecr.'${AWS_REGION}'.amazonaws.com/gamelift-sdk-wrapper-sample:latest",
  "PortConfiguration": {
    "ContainerPortRanges": [
      {
        "FromPort": 8081,
        "ToPort": 8081,
        "Protocol": "TCP"
      }
    ]
  },
  "ServerSdkVersion": "5.2.1"
}'
aws gamelift create-container-group-definition \
    --region ${AWS_REGION} \
    --name ${CONTAINER_GROUP_NAME} \
    --operating-system AMAZON_LINUX_2023 \
    --total-memory-limit-mebibytes 1024 \
    --total-vcpu-limit 1 \
    --game-server-container-definition "$CONTAINER_DEF"

运行以下命令,创建 Managed Container Fleet 所需要的 Role。

ASSUME_ROLE_POLICY='{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "gamelift.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}'
aws iam create-role \
    --role-name GameLiftContainerFleet \
    --assume-role-policy-document "$ASSUME_ROLE_POLICY"
aws iam attach-role-policy \
    --role-name GameLiftContainerFleet \
    --policy-arn arn:aws:iam::aws:policy/GameLiftContainerFleetPolicy

运行以下命令,创建 Managed Container Fleet。

aws gamelift create-container-fleet \
    --region ${AWS_REGION} \
    --description "container fleet" \
    --instance-type c6a.large \
    --fleet-role-arn "arn:aws:iam::${ACCOUNT_ID}:role/GameLiftContainerFleet" \
    --game-server-container-group-definition-name ${CONTAINER_GROUP_NAME} \
    --instance-connection-port-range "{\"FromPort\": 4192, \"ToPort\": 4194}" \
    --instance-inbound-permissions "[{\"FromPort\": 4192, \"ToPort\": 4194, \"IpRange\": \"0.0.0.0/0\", \"Protocol\": \"TCP\"}]"

注意:保存创建后响应的 FleetId 用于后续步骤。

执行以下命令以运行游戏:

  1. 运行客户端服务:cd sample-guess-number-game/out/client/ && ./client
  2. 运行大厅服服务:cd sample-guess-number-game/out/lobby-server-gamelift && ./lobby-server-gamelift --fleet-id <your-fleet-id> --region ${AWS_REGION} --location ${AWS_REGION}

使用前面步骤中返回的 FleetId 代替 <your-fleet-id>,根据前面本地运行的介绍方式访问游戏客户端。

在 Managed Container Fleet 的部署方式中,GameLift 帮助您完成服务器及游戏会话管理的同时,您还可以精确分配每台服务器所需要的 CPU 和内存资源。

清理环境

为避免资源的浪费,在完成示例部署后,可按以下脚本进行资源的清理。

运行以下命令清理 Anywhere Fleet 中所创建的 Location 及 Fleet。

aws gamelift delete-fleet --fleet-id <your-fleet-id> --region ${AWS_REGION}
aws gamelift delete-location --location-name ${LOCATION_NAME} --region ${AWS_REGION}

运行以下命令清理 Managed EC2 Fleet 中所创建的 Build 及 Fleet。

aws gamelift delete-fleet --fleet-id <your-fleet-id> --region ${AWS_REGION}
aws gamelift delete-build --build-id <your-build-id> --region ${AWS_REGION}

运行以下命令清理 Managed Container Fleet 中所创建的 ECR、Container Group、Role 及 Fleet。

aws gamelift delete-container-fleet --fleet-id <your-fleet-id> --region ${AWS_REGION}
aws iam detach-role-policy --role-name GameLiftContainerFleet \
    --policy-arn arn:aws:iam::aws:policy/GameLiftContainerFleetPolicy
aws iam delete-role --role-name GameLiftContainerFleet
aws gamelift delete-container-group-definition --name ${CONTAINER_GROUP_NAME} --region ${AWS_REGION}
aws ecr delete-repository \
    --repository-name gamelift-sdk-wrapper-sample \
    --region ${AWS_REGION} \
    --force

总结

在这篇文章中,您通过使用 Game Server Wrapper,实现了快速在 GameLift 上运行游戏服,实现了基于 Anywhere Fleet、Managed EC2 Fleet、Managed Container Fleet 三种不同的部署方式将本地运行的游戏部署到 GameLift 中。整个过程只需要改造战斗服寻址的逻辑,无需改动核心业务代码即可实现云端托管。

在实现了在 Fleet 上部署游戏后,未来更可以借助 GameLift 的 Alias 能力,快速实现版本的热切换。结合 FlexMatch 智能匹配与 Queues 全球调度能力,更可构建跨区域、低延迟的玩家对战体系。

系列博客

Amazon GameLift 高阶使用技巧(一)- FlexMatch 多模式匹配的实现

Amazon GameLift 高阶使用技巧(二)- 使用 GameLift Container Fleet 运行 UE5 Dedicated Server

Amazon GameLift 高阶使用技巧(三)- 使用 Amazon GameLift Servers+ Amazon GameLift Streams 托管游戏服,并构建云游戏串流

Amazon GameLift 高阶使用技巧(四)- 玩转专用服务器: Photon Fusion 与 GameLift Servers 集成指南

参考资料

amazon-gamelift-servers-game-server-wrapper

本篇作者

黄际东

亚马逊云科技解决方案架构师,有过银行、旅游、直播、教育等行业的十多年项目经验。曾独立主导实现从零到千万用户级别的教育类应用,也参与研发过月活跃用户过千万的全球知名直播平台。在互联网领域拥有多年的研发及运维经验,是一个喜欢编程的解决方案架构师。

孟祥智

亚马逊云科技解决方案架构师