- 游戏开发
- 云原生
【免费下载链接】agones
Dedicated Game Server Hosting and Scaling for Multiplayer Games on Kubernetes
导读
Agones 1.37.0(发布于 2023-12-19)是该项目在"任意计数与列表(Counters and Lists)"能力上投入一年多工作后的首个里程碑版本,为每个 GameServer 挂载可配置的 Counters 与 Lists 提供了 SDK 侧与 Allocation/Autoscaler 侧的完整支持。本文以 1.37.0 发布文档为骨架,结合仓库源码(特性开关定义、GameServer API、Allocation 示例等)逐项拆解 CountsAndLists、FleetAllocationOverflow、PodHostName、ResetMetricsOnDelete、SplitControllerAndExtensions 五个特性的设计意图、配置方法与底层实现,并附上本版本全部增强清单、可用镜像与 Helm 安装方式,帮助你在实际集群中评估、启用并迁移到这些能力。
1. 版本总览:一次"播种"与"收获"并存的发布
1.37.0 是 Agones 的一个双主线版本:
- 新能力首秀:经过一年多迭代的 Counters and Lists 功能首次以Alpha特性(
CountsAndListsfeature gate)随版本发布,为 GameServer 挂载可编程的 int64 计数器与字符串列表,并打通了 SDK、Allocation、Fleet 扩缩容与 Metrics 全链路; - 多项特性晋升:
FleetAllocationOverflow从 Alpha 晋升到Beta;PodHostName、ResetMetricsOnDelete、SplitControllerAndExtensions三个特性晋升到Stable(默认开启)。
按照 Agones 的特性门控(Feature Gate)惯例(参见 features.go 的featureDefaults注释):Alpha 特性默认关闭、Beta 特性默认开启、Stable 特性强制开启且不允许被显式关闭(以免旧版本传入未知 flag 导致解析失败)。因此本版本中实际开箱即用的是后四个特性,而CountsAndLists需要显式通过--feature-gates=CountsAndLists=true或 Helm values 开启。
2. Counters and Lists:可编程的 GameServer 通用追踪能力(Alpha)
2.1 设计动机:从 Player Tracking 到通用 Counters/Lists
Agones 此前在 Alpha 阶段提供过专门化的PlayerTracking能力(players字段,见 gameserver.go 的PlayersSpec与PlayerStatus),但它只能追踪"玩家"一种语义。Counts and Lists 将这一思想泛化:
- Counters:挂在 GameServer 上的 int64 计数器,支持按指定数值增减(
count)并限定最大容量(capacity),天然适合"当前房间人数 / 房间容量""会话中的玩家数"等场景; - Lists:挂在 GameServer 上的字符串数组,支持追加、删除单个值与查询包含关系,适合"玩家 ID 集合""房间成员名单""已领取道具列表"等场景。
从当前仓库源码看,该特性已在后续版本晋升为Beta 并默认开启(见 defaultfeaturegates.yaml 中CountsAndLists: true,以及 gameserver.yaml 中"Now in Beta, and enabled by default"的注释),但在 1.37.0 发布时它还是 Alpha、默认关闭。
2.2 配置模型:在 GameServer Spec/Status 中声明
Counters 与 Lists 的 key 必须在GameServer 创建时声明,其初始值与容量写入 Spec,运行中的实时值由 SDK Server 同步到 Status:
# 摘自 examples/gameserver.yaml spec: counters: # int64 计数器,可增减固定数值;key 必须在创建时声明 rooms: # 任意自定义 key count: 1 # 初始值 capacity: 100 # 最大容量,可选,默认 1000 lists: # 字符串列表,支持追加/删除;key 必须在创建时声明 players: # 空列表示例 capacity: 10 # 容量,默认 1000 rooms: # 允许与 counters 使用相同的 key 名 capacity: 333 values: # 也支持声明初始值 - room1 - room2 - room3对应到 API 层(gameserver.go):Spec.Counters为map[string]CounterStatus、Spec.Lists为map[string]ListStatus;CounterStatus仅含count与capacity两个 int64 字段(第 353-357 行),ListStatus则包含values数组与capacity(第 359 行起)。运行时 GameServer 的 Status 中同步维护一份实时Counters/Lists(第 328-332 行),供 Allocation 查询与 Fleet 扩缩容决策使用。
2.3 SDK 侧:进程内直接读写
游戏服务器进程通过 Agones SDK 直接操作 Counters 与 Lists。本版本新增的 SDK 方法定义于 beta.proto(当前仓库中这些方法位于 Beta 阶段,1.37.0 发布时对应 Alpha SDK 的同一组 RPC):
| 方法 | 作用 | 关键错误语义 |
|---|---|---|
GetCounter(name) | 读取 Counter 当前值 | 不存在返回NOT_FOUND |
UpdateCounter(req) | 更新 Counter 的 count / capacity(支持增量语义countDiff) | 不存在返回NOT_FOUND,名称不可修改 |
GetList(name) | 读取 List 当前内容 | 不存在返回NOT_FOUND |
UpdateList(req) | 按字段掩码更新 List 字段 | 非法字段返回INVALID_ARGUMENT |
AddListValue(name, value) | 向 List 追加值 | 重复值返回ALREADY_EXISTS;已达容量返回OUT_OF_RANGE |
RemoveListValue(name, value) | 从 List 删除值 | 值不存在返回NOT_FOUND |
对应的 Go SDK 实现与测试可参见 sdks/go/alpha.go 与 sdks/go/alpha_test.go;REST 网关的 OpenAPI 描述见 alpha.swagger.json。
2.4 Allocation 集成:按容量过滤、优先级排序与分配动作
Counts/Lists 的价值在 Allocation 中体现得最充分。1.37.0 起GameServerAllocation支持三类新配置(完整示例见 gameserverallocation.yaml):
① 选择器过滤(selector 内嵌 counters/lists):只有当前值/可用容量落在指定区间的 GameServer 才可能被选中:
selectors: - matchLabels: agones.dev/fleet: green-fleet counters: rooms: minCount: 1 # count 最小值,默认 0 maxCount: 5 # count 最大值,默认 max(int64) minAvailable: 1 # 可用容量 (capacity - count) 最小值,默认 0 maxAvailable: 10 # 可用容量最大值,默认 max(int64) lists: players: containsValue: "x6k8z" # 仅匹配列表中含该值的 GameServer,默认 "" 即全部 minAvailable: 1 maxAvailable: 10② 优先级排序(priorities):控制 Packed/Distributed 策略下候选 GameServer 的搜索顺序,例如"可用容量小的优先分配"以实现高密度装箱:
priorities: - type: Counter # 支持 Counter 或 List key: rooms order: Ascending # Ascending 表示可用容量小的排前面③ 分配动作(counters/lists actions):分配命中后自动修改 GameServer 的 Counter/List,例如把新玩家加入房间:
counters: rooms: action: Increment # 仅支持 Increment / Decrement amount: 1 # 增减量,必须为正整数 capacity: 5 # 同时把容量更新为该值,范围 [0, max(int64)] lists: players: addValues: # 分配时追加值,重复值自动忽略 - x7un - 8inz capacity: 40 # 容量上限,范围 [0, 1000] deleteValues: # 分配时删除值,不存在的值自动忽略 - alice - bob从源码看,这些字段在 Allocation gRPC 定义中均有对应(allocation.pb.go 标注了[FeatureFlag:CountsAndLists],Priorities的语义注释说明 Packed 策略下作为"最低利用率基础设施内的决胜排序"、Distributed 策略下作为全局分配顺序),底层排序实现位于 gameserver.go 的CompareCountAndListPriorities系列函数;Allocation 层到 gRPC 请求的转换则在 converter.go 中按FeatureCountsAndLists开关分支处理,且配套了覆盖完整/空字段/部分字段等大量场景的单测(converter_test.go)。
2.5 Fleet 集成:按 Counter/List 决定缩容优先级
Fleet 在 1.37.0 同步获得priorities配置(见 fleet.go 与 fleet.yaml),用于影响缩容时删除哪些 GameServer:Packed策略下作为节点内决胜排序,Distributed策略下决定整个 Fleet 的删除顺序——例如"优先保留房间容量大的实例":
priorities: - type: Counter key: rooms order: Ascending2.6 迁移提醒:Counters/Lists 将取代 PlayerTracking
发布文档明确提示:Counters and Lists 最终会取代 Alpha 阶段的 Player Tracking,后者随后将从 Agones 移除。仍在PlayerTracking上构建功能的用户,应尽早用 Counters/Lists 复刻并验证自身场景(当前仓库中FeaturePlayerTracking仍存在于 features.go 的 Alpha 组中但默认关闭,而FeatureCountsAndLists已进入 Beta 组默认开启,正是该迁移方向的体现)。
3. FleetAllocationOverflow:溢出分配自动打标(晋升 Beta)
3.1 解决什么问题
当对 Fleet 的分配请求数量超过底层GameServerSet期望的副本数(replicas)时,多出来的 GameServer 被称为"溢出(overflow)"实例。FleetAllocationOverflow 允许为这类溢出实例自动附加 Labels / Annotations,方便后续通过 Allocation 选择器、监控或外部系统识别它们。
3.2 配置示例
# 摘自 examples/fleet.yaml spec: allocationOverflow: labels: mykey: myvalue version: "" # 置空字符串可以清空已有的 label 值 annotations: otherkey: setthisvalue3.3 底层实现
从源码看,该功能由一个独立的控制器驱动:
- 配置类型
AllocationOverflow定义于 common.go,含Labels、Annotations与校验方法Validate; - 控制器位于 allocation_overflow.go:
AllocationOverflowController监听GameServerSet事件,仅处理Spec.AllocationOverflow非空且确有 labels/annotations 的集合(第 83-90 行);同步时调用CountMatches(统计当前 Allocated 且与配置匹配的实例数,见 common.go)判断是否存在溢出,再通过Apply把配置的元数据打到溢出的 GameServer 副本上(第 145-156 行); - 单元测试覆盖
CountMatches/Apply/Validate及控制器行为(common_test.go、allocation_overflow_test.go)。
4. 三个晋升 Stable 的特性
4.1 PodHostName:GameServer 名作为 Pod 主机名
该特性让 GameServer 的 Pod 使用 GameServer 名称作为spec.hostname,使集群内 DNS 解析(如<gs-name>.<namespace>.svc.cluster.local)与 GameServer 资源名保持一致,简化了游戏服务端对自身身份的识别与节点间寻址。
实现位于 gameserver.go:构造 Pod 时若未显式设置Hostname,则以strings.ReplaceAll(gs.Name, ".", "-")填充(Kubernetes DNS 不允许点号),并在 gameserver_test.go 中对默认行为、已有 hostname 覆盖等场景做了断言。
4.2 ResetMetricsOnDelete:资源删除即重置指标状态
该特性指示 metrics 服务在任一 Agones 资源(Fleet、GameServerSet、Autoscaler 等)被删除时,立即注销并重新注册对应的 OpenCensus metrics view,从而重置其状态——避免删除重建同名资源后指标出现残留历史值或时序断裂。
实现位于 controller_metrics.go:registerViews()(第 201-207 行)注册全部状态视图,资源删除时对相关 view 执行view.Unregister后再注册(第 209-225 行);配套测试 controller_test.go 直接以ResetMetricsOnDelete命名,验证 Fleet 副本数与 Autoscaler 状态指标的重置行为。
4.3 SplitControllerAndExtensions:为高可用拆分控制器与扩展服务
这是 1.37.0 在架构层面的重要变化:将原来单体 controller 的职责拆分为两个二进制:
controller:负责 Kubernetes 对象监控(informer/worker),并使用leader election(选主)机制保证同一时刻只有一个活跃控制器,避免重复处理;extensions(新增,横向可扩展):专注管理 Webhook 端点(GameServer/Fleet/Autoscaler 的 mutating/validating webhooks)与 Allocation 的 HTTP/gRPC 端点。
从源码可以印证分工:
- cmd/controller/main.go 中的
whenLeader封装了基于client-goleaderelection.RunOrDie的选主逻辑,--leader-electionflag 控制开关(第 322 行); - cmd/extensions/main.go 中
extensions进程构建 HTTPS Server、webhooks.NewWebHook(httpsServer.Mux)挂载 webhook 路由、apiserver.NewAPIServer提供 API,并注册 GameServer/GameServerSet/Fleet/FleetAutoscaler 各包导出的NewExtensions(第 239-242 行),同时以多 worker(NumWorkers)并发处理请求——这正是"横向可扩展"的来源。
这一拆分让负责重计算/写操作的主控制器可以安全地选主收敛,而承载外部流量的 webhook/API 层则可以按需水平扩容,显著改善大规模集群下的高可用性。1.37.0 中该特性晋升 Stable,此后作为默认架构随 Helm 安装生效。
5. 本版本其他实现增强(Enhancements)
除上述主特性外,1.37.0 还包含以下实现增强(PR 编号与贡献者来自发布文档):
- Counters/Lists 测试与示例补全:
#3488增加 Counter conformance 测试(@igooch)#3500为 simple-game-server 增加 List SDK 方法(@igooch)#3507、#3510、#3516、#3519、#3521分别为 GameServer、Fleet、GameServerAllocation、FleetAutoscaler 增加 Lists 的 e2e 测试(@igooch)#3524增加 Go 语言的 Lists conformance 测试(@igooch)#3546增加 Counters and Lists 的 REST API conformance 测试(@igooch)#3528增加 Counter 与 List 的 Fleet 聚合指标(@igooch)#3537、#3552分别补齐 CountsAndLists 的 SDK 参考与 YAML 示例/参考文档(@Kalaiselvi84)
- 稳定性与运维:
#3508禁用 SDK Server 的 resync(@Kalaiselvi84)#3502支持appProtocol(@Kalaiselvi84)#3526为 agones-allocator 在 Helm chart 中增加clusterIP(@govargo)#3387GKE Autopilot 支持 Extended Duration Pods(@zmerlynn)
- 特性晋升:
#3517PodHostName → Stable、#3518ResetMetricsOnDelete → Stable、#3523SplitControllerAndExtensions → Stable、#3515FleetAllocationOverflow → Beta、#3527CountsAndLists → Alpha(均 @Kalaiselvi84)。
6. 安装与镜像
1.37.0 通过官方 Helm chart 安装(需先添加 stable 仓库):
helm repo add agones https://agones.dev/chart/stable helm install agones agones/agones --version 1.37.0需要开启 1.37.0 时仍为 Alpha 的CountsAndLists特性时,可在 Helm values 中把agones.featureGates.CountsAndLists设为true(对应控制器进程的--feature-gates参数;特性解析逻辑见 features.go 的ParseFeatures)。注意:Stable 特性(如本版本的 PodHostName / ResetMetricsOnDelete / SplitControllerAndExtensions)不可被关闭。
本版本发布的容器镜像(us-docker.pkg.dev/agones-images):
- 核心组件:
release/agones-controller:1.37.0、release/agones-sdk:1.37.0、release/agones-ping:1.37.0、release/agones-allocator:1.37.0 - 示例服务:
examples/allocation-endpoint-proxy:0.6、examples/autoscaler-webhook:0.9、examples/cpp-simple-server:0.16、examples/crd-client:0.12、examples/nodejs-simple-server:0.9、examples/rust-simple-server:0.12、examples/simple-game-server:0.23、examples/supertuxkart-example:0.10、examples/unity-simple-server:0.3、examples/xonotic-example:1.6
7. 迁移与升级建议
- Counters/Lists 上手路径:先以
gameserver.yaml中的counters/lists声明一个最小 GameServer,用 SDK 的UpdateCounter/AddListValue验证读写;再在gameserverallocation.yaml中依次加入选择器过滤、priorities与分配动作,最后在 Fleet 上配置priorities影响缩容。完整可运行参考见 simple-game-server、fleet.yaml 与 gameserverallocation.yaml。 - Player Tracking 用户:对照 alpha.proto 的既有方法,评估用 Counters/Lists 等价实现"容量追踪、玩家列表、按容量过滤分配"的迁移方案,尽早验证后再切换。
- 架构升级注意:SplitControllerAndExtensions 进入 Stable 后 controller 默认启用 leader election,升级时请确认集群 RBAC 允许 controller 创建/读取 Lease(选主依赖),并注意
extensions作为独立 Deployment 的副本数与 webhook 证书配置。 - 指标行为变化:ResetMetricsOnDelete 默认开启后,删除资源会立即重置其指标视图,依赖历史指标做长周期监控(如 Grafana 跨删除聚合)的场景需调整查询方式。
8. 总结
1.37.0 标志着 Agones 从"面向玩家的专用追踪"走向"面向任意游戏逻辑的通用追踪":Counters and Lists 用最小的 API 面积(两个 map + 一组 SDK 方法)覆盖了玩家追踪、高密度房间管理乃至游戏专属分配优先级等广阔场景,并以"先参考文档、后深度指南"的节奏逐步完善;与此同时,FleetAllocationOverflow 与三个 Stable 特性共同提升了分配的可见性、指标的一致性和控制面的高可用性。对于正在规划多人在线游戏托管平台的团队,本版本的 Counters/Lists 生态是值得尽早投入评估与迁移的方向。
- 游戏开发
- 云原生
【免费下载链接】agones
Dedicated Game Server Hosting and Scaling for Multiplayer Games on Kubernetes
相关推荐
Agones 1.40.0 版本解析:Kubernetes 1.29 支持、Counters/Lists 的 CSharp SDK、多项特性晋级与性能优化
Agones 1.40.0 版本解析:Kubernetes 1.29 支持、Counters/Lists 的 CSharp SDK、多项特性晋级与性能优化 本指
游戏开发云原生Agones 1.32.0 发布解读:Go 1.20 升级、三大特性晋升 Beta 与 SafeToEvict 晋级 Stable
Agones 1.32.0 发布解读:Go 1.20 升级、三大特性晋升 Beta 与 SafeToEvict 晋级 Stable Agones 1.32.0(
游戏开发云原生ZCode 中的 React 应用初始化:从"每次挂载都执行"到"每次加载只执行一次"
ZCode 中的 React 应用初始化:从"每次挂载都执行"到"每次加载只执行一次" ZCode 的桌面客户端(Electron)renderer 使用 Re
游戏开发云原生
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考