ACK One x OpenKruiseGame 全球游戏服多地域一致性交付最佳实践

news2024/12/23 23:06:32

作者:刘秋阳、蔡靖

前言

在当今全球一体化的经济环境下,数字娱乐产业正日益成为文化和商业交流的有力代表。在此背景下大量游戏厂商尝试游戏出海并取得了令人瞩目的成绩,许多游戏以全球同服架构吸引着世界各地广泛的玩家群体。游戏全球化部署不仅扩大了单个产品的市场规模,而且提高了游戏厂商在全球范围的影响力,但与此同时也带来了许多技术挑战:

图片

游戏服务所要求的高频交互和低延迟性质,使得在全球同服框架下,游戏服务器需要在多个地区进行部署。在实际运营过程中,我们通常需要根据目标用户群的地理位置和对延迟的容忍度预先规划服务器的设置地点。一般而言,以下这些区域是我们优先考虑的服务器地址——美东地区人口稠密,能为大批北美玩家提供服务;法兰克福地区是欧洲互联网的交汇点,能有效服务整个欧洲的玩家网络体验;新加坡地区则广泛覆盖东南亚的玩家群体;东京地区主要为日本和韩国的玩家提供支持

面对不同地区可能存在的配置差异、游戏版本更新以及服务器数目的不一致,如何在全球范围内有效实现游戏服的一致性交付,成为我们在全球同服架构设计时必须面对和解决的核心挑战。本文将通过一个示例来为大家讲解全球游戏服多地域一致性交付最佳实践。

部署架构

在示例中,我们计划在上海、东京、法兰克福三地开服,因此我们需要这三个地区的基础设施资源。面对基础设施异构且复杂的情景,云原生带来的声明式 API、一致性交付的特性可以充分屏蔽底层资源的差异性,让游戏运维工程师专注应用本身,大幅度提高游戏服交付效率。从区域自治稳定性、用户调度复杂性的角度考虑,每个开服地域独立部署Kubernetes集群,并通过多集群的能力统一运维管理是我们认为游戏服一致性交付的最佳方式。

在本次实践中,我们选择阿里云分布式云容器平台 ACK One 管理多地域 Kubernetes 集群。ACK One 作为阿里云面向混合云、多集群、容灾等场景退出的企业级云原生平台,可以连接和管理任何地域、任何基础设施上的 Kubernetes 集群,并提供一致的管理,支持对应用、流量、安全、存储、可观测等进行统一管控。

本示例的部署架构如图所展示,包括 3 个不同地域的生产环境和 1 个开发测试环境。通常来说,通过在研发测试环境中验证并确认版本稳定后,再将其部署到生产环境,这一流程有助于确保项目的整体稳定性,并有效预防潜在的风险。

示例采用多集群混合云架构。具体地,Shanghai 集群、Frankfurt 集群、及 ShangHai Dev 集群为阿里云 ACK 集群;而 Japan 集群为非阿里云 Kubernetes 集群,其以注册集群的方式集成和纳管。在每个集群内部,我们采用了 GameServerSet 来部署游戏服务器。GameServerSet 是由云原生计算基金会(CNCF)孵化中的开源项目 OpenKruise 所提供的游戏专项工作负载。与原生的 Deployment 和 StatefulSet 工作负载相比,GameServerSet 具备游戏语意,更贴近游戏场景,使得对游戏服务器的运维管理更加方便和高效。

图片

集群纳管

Kubernetes 集群准备完成后,我们使用 ACK One 舰队统一管理云上云下集群:

首先,通过 ACK One 注册集群 [ 1] 将 IDC 或第三方公共云集群注册到阿里云,具体地:

  1. 创建注册集群 [ 2] ,并在创建好的注册集群,右侧单击操作列下的详情

  2. 集群信息页面单击连接信息页签。

  3. 集群导入代理配置区域根据需要选择公网或者私网,然后单击右侧的复制,将公网或私网页签的内容复制到一个文件中,并执行 kubectl 命令,将目标集群注册至新集群中。例如,新建 agent.yaml 文件,将以上内容复制到 agent.yaml 文件中,并在目标集群中执行 kubectl apply -f agent.yaml 命令。

通过此步骤,Japan 集群已经被注册到阿里云。

其次,开启 ACK One 多集群舰队 [ 3] ,并在 ACK One 控制台 [ 4] 上关联注册集群和云上集群。由于集群跨多个地域,所以 ACK One 舰队会使用公网的方式关联集群,舰队所在 VPC 则需配置公网 NAT 网关。

至此,一个多集群舰队已经 Ready。示例对应的示意图如下:

图片

游戏服发布

在执行示例具体的发布操作之前,我们一起认识下云原生的交付思想 —— 声明式而非面向过程,这也就意味着云原生式的应用交付关注的并不是应用的部署过程而是对应用的定义。而应用的定义就是 Yaml,它通过配置参数化的方式描述这个应用该是什么样子。因此,一切有关应用的变更和发布实际上都是对应用描述(Yaml)的更改。

至此我们发现,我们需要一个仓库将 Yaml 落盘,记录当前对应用的描述,并且能够追溯和审计过去 Yaml 的变更。说到这里我相信大家会发现 git repo 天然符合该特点,运维工程师可以通过提交 Commit 和 Merge Request 的方式将 Yaml 上传并落盘,权限管理、审计都遵循 git 规范。在理想状态下,我们只需要维护一套对游戏服描述的 Yaml,一键触发全球多地域的游戏服发布,无需面向过程一一操作集群,去执行部署动作。这就是 GitOps 的思想。

在 GitOps 落地过程中最富有挑战的事情实际上是对游戏服应用的描述抽象。正如文章开头提到的,每个地域的游戏服或多或少存在着一些差异,似乎难以通过一个 Yaml 将所有游戏服都概括。举个例子,在上海我希望发布 10 个游戏区服,而在法兰克福我只希望发布 3 个区服,这样一来,一个 Yaml 因为 replicas 字段的差异就无法描述不同地域的游戏服。难道我们需要为每一个地域维护一个 Yaml 吗?这样也非合理的做法,当进行非差异性字段变更时(例如,为所有地域的游戏服打上一个标签),我们需要重复地执行多个 Yaml 的更改,集群数量多的时候容易造成遗漏或者错误,这并不符合云原生交付思想。

实际上,我们可以通过 Helm Chart 进行游戏服应用的进一步抽象,将差异性的部分作为 Value 提取出来。在我们本次的示例中(GitHub 游戏服 Helm Chart 示例 [ 5] ),我们抽象出这样几个差异性字段:

  • 主镜像 —— 每个地域/集群的主镜像可能存在差异
  • sidecar 镜像 —— 每个地域/集群的 sidecar 镜像可能存在差异
  • 副本数 —— 每个地域/集群的发布的游戏服数量可能存在差异
  • 是否自动伸缩 —— 每个地域/集群对于自动伸缩的要求可能存在差异

除此之外的其他字段都保持一致,意味着不存在地域差异性影响。

在理解了 GitOps 并对游戏服应用进行了抽象、描述后,我们利用 ACK One GitOps 进行应用交付的实操。接下来我们展开具体的操作:

连接 Git 仓库

登录 ArgoCD UI:在 ACK One 控制台左侧导航栏舰队 -> GitOps -> GitOps 控制台,并在登录页面,单击 LOG IN VIA ALIYUN,登录到 ArgoCD UI。需要公网访问则需要开通公网访问 GitOps [ 6]

  1. 在 ArgoCD UI 左侧导航栏选择 Settings,然后选择 Repositories > + Connect Repo。

  2. 在弹出的面板中配置以下信息,然后单击 CONNECT 添加连接。

图片

图片

图片

发布 PvE 类型游戏

PvE 类型游戏通常存在区服概念,大多情况下由运维工程师手动控制各地域的开服数量。关于 PvE 游戏云原生化最佳实践可参考 OKG PvE 游戏最佳实践文档 [ 7]

白屏化管理应用

在初次尝试 ArgoCD 时,我们可以使用白屏控制台为每个地域的集群分别创建 Application:

  1. 在 ArgoCD UI 左侧导航栏选择 Applications,然后单击+NEW APP。

  2. 在弹出的面板配置以下信息,然后单击 CREATE 进行创建。(以 opengame-demo-shanghai-dev 为例)。

图片

  1. 创建完成后,在 Application 页面,即可看到 opengame-demo-shanghai-dev 的应用状态。如果 SYNC POLICY 选择的是 Manual 方式,需要手动点击 SYNC,将应用同步部署至目标集群。应用的 Status 为 Healthy 和 Synced,表示已经成功同步。

图片

  1. 单击 opengame-demo-shanghai-dev 应用名称,即可查看应用详情,展示应用相关的 Kubernetes 资源的拓扑结构及相应状态。
通过 ApplicationSet 一键发布

对 ArgoCD 有所熟悉了之后,我们也可以通过 ApplicationSet 对象来一键发布游戏服。各个集群的差异性通过elements抽象出来,例如下面 Yaml 中,以集群维度抽象出三个字段:cluster 集群名称用于区分 Application 名称;url 用于区分目标集群地址;replicas 用于区别不同集群发布的游戏服数量。

编写完成该 ApplicationSet Yaml 后,将其部署到 ACK One 舰队集群即可自动创建出四个 Application。

kubectl apply -f pve.yaml -n argocd

# pve.yaml 内容如下:
apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: minecraft
spec:
  generators:
  - list:
      elements:
      - cluster: shanghai-dev
        url: <https://47.100.237.xxx:6443>
        replicas: '1'
      - cluster: shanghai-prod
        url: <https://47.101.214.xxx:6443>
        replicas: '3'
      - cluster: frankfurt-prod
        url: <https://8.209.103.xxx:6443>
        replicas: '2'
      - cluster: japan-prod
        url: <https://10.0.0.xxx:6443>
        replicas: '2'
  template:
    metadata:
      name: '{{cluster}}-minecraft'
    spec:
      project: default
      source:
        repoURL: '<https://github.com/AliyunContainerService/gitops-demo.git>'
        targetRevision: HEAD
        path: manifests/helm/open-game
        helm:
          valueFiles:
          - values.yaml
          parameters: #对应helm chart中提取的value参数
          - name: replicas
            value: '{{replicas}}'
          - name: scaled.enabled 
            value: 'false'
      destination:
        server: '{{url}}'
        namespace: game-server #部署到对应集群的game-server命名空间下
      syncPolicy:
        syncOptions:
          - CreateNamespace=true #若集群中命名空间不存在则自动创建

在该 Yaml 中,所有的镜像版本都一致,若希望各集群镜像版本出现差异,可以仿照 replicas 的方式,添加新的 parameters 参数。

发布 PvP 类型游戏

对于 PvP 类型的游戏,房间服的数量由自身伸缩器调配,而非运维工程师手动指定。有关 PvP 类型游戏的云原生化最佳实践可参考 OKG PvP 游戏最佳实践文档 [ 8]

在 OKG 中我们通过为 GameServerSet 配置 ScaledObject 对象来实现房间服的弹性伸缩。因此,scaled.enabled 在此场景下需要开启。此外,房间服的副本数有 ArgoCD 和 OKG 2 个控制者而冲突,可以通过让 ArgoCD 忽略 GameServerSet 资源的副本数变化来解决,具体在 spec.ignoreDifferences 设置相应字段即可。考虑以上情况,该 pvp.yaml 如下所示:

apiVersion: argoproj.io/v1alpha1
kind: ApplicationSet
metadata:
  name: pvp
spec:
  generators:
  - list:
      elements:
      - cluster: shanghai-dev
        url: <https://47.100.237.xxx:6443>
      - cluster: shanghai-prod
        url: <https://47.101.214.xxx:6443>
      - cluster: frankfurt-prod
        url: <https://8.209.103.xxx:6443>
      - cluster: japan-prod
        url: <https://10.0.0.xxx:6443>
  template:
    metadata:
      name: '{{cluster}}-pvp'
    spec:
      project: defaultminecraft
      ignoreDifferences: # 设置 GameServerSet minecraft副本数目由集群自控制
      - group: game.kruise.io
        kind: GameServerSet
        name: minecraft
        namespace: game
        jsonPointers:
        - /spec/replicas
      source:
        repoURL: '<https://github.com/AliyunContainerService/gitops-demo.git>'
        targetRevision: HEAD
        path: manifests/helm/open-game
        helm:
          valueFiles:
          - values.yaml
      destination:
        server: '{{url}}'
        namespace: pvp-server
      syncPolicy:
        syncOptions:
          - CreateNamespace=true

总结

本文通过一个示例介绍了 ACK One 在全球游戏服多地域一致性交付最佳实践。示例中涉及到 4 个 Kubernetes 集群和一个简单游戏服 Yaml。而当实际生产环境中,很可能出现集群数量更多、游戏服应用描述更复杂的情况,此时做好应用的抽象是关键之处。

欢迎加入云原生游戏钉钉群 (群号:44862615) 和 OpenKruiseGame 开发者以及游戏行业研发运维工程师们共同沟通讨论;有关 ACK One 的相关问题也可以加入钉钉群 (群号:35688562) 进行咨询。

相关链接:

[1] ACK One 注册集群

https://help.aliyun.com/zh/ack/distributed-cloud-container-platform-for-kubernetes/user-guide/overview-9?spm=a2c4g.11186623.0.0.3e4157eb3o9J3v

[2] 创建注册集群

https://help.aliyun.com/zh/ack/distributed-cloud-container-platform-for-kubernetes/user-guide/create-a-cluster-registration-proxy-and-register-a-kubernetes-cluster-deployed-in-a-data-center?spm=a2c4g.11186623.0.0.2f833eb6R1YTOq

[3] 开启 ACK One 多集群舰队

https://help.aliyun.com/zh/ack/distributed-cloud-container-platform-for-kubernetes/user-guide/enable-fleet-management?spm=a2c4g.11186623.0.0.8cc462853sti0H

[4] ACK One 控制台

https://account.aliyun.com/login/login.htm?oauth_callback=https%3A%2F%2Fcs.console.aliyun.com%2Fone

[5] GitHub 游戏服 Helm Chart 示例

https://github.com/AliyunContainerService/gitops-demo/tree/main/manifests/helm/open-game

[6] 需要开通公网访问 GitOps

https://help.aliyun.com/zh/ack/distributed-cloud-container-platform-for-kubernetes/user-guide/enable-gitops-public-network-access?spm=a2c4g.11186623.0.0.e7db48aeenz8AX

[7] OKG PvE 游戏最佳实践文档

https://openkruise.io/zh/kruisegame/best-practices/pve-game

[8] OKG PvP 游戏最佳实践文档

https://openkruise.io/zh/kruisegame/best-practices/session-based-game/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1635141.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

UDP文件传输工具之UDP传输的优点和缺点

在当今快节奏的网络通信时代&#xff0c;UDP以其独特的优势&#xff0c;在众多应用场景中扮演着关键角色。本文将深入探讨UDP的优缺点及其应用场景&#xff0c;并重点介绍镭速软件如何通过技术创新&#xff0c;显著提升UDP传输的效率和可靠性。 UDP传输的优点 UDP的显著优势在…

2024王炸组合!基于Mamba的遥感图像处理引爆顶会!

对比传统方法&#xff0c;基于Mamba的遥感图像处理在计算效率和分析精度方面遥遥领先&#xff0c;Mamba遥感也成为了论文研究的新方向。 具体来说&#xff0c;在融合高分辨率的空间图像和低分辨率的光谱图像获取综合信息方面&#xff0c;Mamba可以提升性能&#xff0c;同时保持…

特斯拉全自动驾驶能力(FSD)或与百度合作;小红书内测自研大模型丨 RTE 开发者日报 Vol.196

开发者朋友们大家好&#xff1a; 这里是 「RTE 开发者日报」 &#xff0c;每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE&#xff08;Real Time Engagement&#xff09; 领域内「有话题的新闻」、「有态度的观点」、「有意思的数据」、「有思考的文章」、「…

【工具资源】药物研发平台;物理符号优化平台;手术视频可视化解答

在 AI for Science 的规模化推广过程中&#xff0c;低门槛使用且开源的高性能工具至关重要。一方面&#xff0c;科研人员能够通过上手使用&#xff0c;更加直观地了解 AI 的能力&#xff1b;另一方面&#xff0c;当团队中缺乏交叉学科人才时&#xff0c;已有工具能够减少科研人…

[华为OD] C卷 服务器cpu交换 现有两组服务器QA和B,每组有多个算力不同的CPU 100

题目&#xff1a; 现有两组服务器QA和B,每组有多个算力不同的CPU,其中A[i]是A组第i个CPU的运算能 力&#xff0c;B[i]是B组第i个CPU的运算能力。一组服务器的总算力是各CPU的算力之和。 为了让两组服务器的算力相等&#xff0c;允许从每组各选出一个CPU进行一次交换。 求两…

C++学习第十课:指针陷阱与引用传递(阶段练习题)

C学习第十课&#xff1a;指针陷阱与引用传递 在C中&#xff0c;指针和引用是两个强大的特性&#xff0c;但它们也可能导致一些常见的错误。本课将深入探讨使用指针时可能遇到的问题&#xff0c;并介绍引用的概念和使用方式。 大纲标题与代码详解 1. 日常使用指针容易犯的错误…

CSS的布局模式

前言&#xff1a; 我们可以看到京东的官网上的一些例子&#xff08;如下图&#xff09;&#xff0c;在同一排中能够存在多个div&#xff0c;这是通过布局方式&#xff08;例如浮动&#xff09;来实现的。 CSS传统的布局模式&#xff1a; <1>普通流&#xff08;又称之为标…

mysql UNION 联合查询

mysql UNION 联合查询 业务需要拉数据&#xff0c;这里需要对查询不同格式的数据进行组装&#xff0c;此处采用联合查询 注意1&#xff1a;null as 设备关爱 &#xff0c;结果为null&#xff0c;表头为设备关爱 注意2&#xff1a; UNION 或者 UNION ALL 联合查询自行选用 注意3…

OpenTK:安装和说明

OpenTK介绍 OpenTK是一个开源、跨平台的游戏开发库&#xff0c;由MonoGame团队创建。它为C#开发者提供了一个简单易用的接口&#xff0c;以便使用OpenGL、OpenAL和OpenCL进行3D渲染、音频处理和并行计算。OpenTK的目标是提供一个一致且高效的框架&#xff0c;让开发者能够专注于…

经典文献阅读之--SurroundOcc(自动驾驶的环视三维占据栅格预测)

0. 简介 环视BEV已经是很多场景中需要的功能&#xff0c;也是视觉代替激光雷达的有效解决方案&#xff0c;而《SurroundOcc: Multi-camera 3D Occupancy Prediction for Autonomous Driving》一吻则代表了这个领域的SOTA算法&#xff0c;文中通过多帧点云构建了稠密占据栅格数据…

windows下安装onlyoffice

文章目录 1、 安装ErLang2、 安装rabbitmq3、 安装postgresql4、 安装onlyoffice(社区版) 1、 安装ErLang 下载地址&#xff1a;https://erlang.org/download/otp_win64_24.2.exe opt_wind64_24.2.exe 直接运行&#xff0c;一步一步安装 2、 安装rabbitmq 下载地址&#xf…

若依:Linux Centos 7.9 安装部署RuoYi前后端集成版

目录 1.虚拟机操作系统版本 2.删除旧的jdk 3.下载JDK 17 &#xff1a; 4.下载 mvn 3.9.6&#xff1a; 5.下载mysql:5.7.44版本 6.git下载若依&#xff1a; 7.修改数据库连接&#xff1a; 8.mvn 清理和打包 9.启动若依&#xff1a; 1.虚拟机操作系统版本 2.删除旧的jd…

Qt QThreadPool线程池

1.简介 QThreadPool类管理一个QThread集合。 QThreadPool管理和重新设计单个QThread对象&#xff0c;以帮助降低使用线程的程序中的线程创建成本。每个Qt应用程序都有一个全局QThreadPool对象&#xff0c;可以通过调用globalInstance来访问该对象。 要使用其中一个QThreadPool…

XY_RE复现(四)舔狗四部曲

一&#xff0c;我的白月光 BOOK框还叉不掉&#xff0c;主函数很长 int __cdecl main(int argc, const char **argv, const char **envp) {__m128 si128; // xmm6__int128 *v4; // raxint v5; // r13dunsigned int v6; // ecx__m128 v7; // xmm0_DWORD *v8; // raxHMODULE Modu…

ROS 2边学边练(37)-- 使用时间参数(C++)

前言 在前几篇内容中&#xff0c;我们已经了解过了tf2广播、tf2监听&#xff0c;并且还了解了如何添加一个坐标系到tf2树图中&#xff0c;以及如何查看坐标系间的转换情况。实际上&#xff0c;是通过lookupTransform函数来查找的&#xff0c;这个函数允许我们查找所有的转换数据…

数据结构中的栈(C语言版)

一.栈的概念 栈是一种常见的数据结构&#xff0c;它遵循后进先出的原则。栈可以看作是一种容器&#xff0c;其中的元素按照一种特定的顺序进行插入和删除操作。 压栈&#xff1a;栈的插入操作叫做进栈/压栈/入栈&#xff0c;入数据在栈顶。 出栈&#xff1a;栈的删除操作叫做…

品牌百度百科词条需要什么资料?

品牌百度百科词条是一个品牌的数字化名片&#xff0c;更是品牌历史、文化、实力的全面展现。 作为一个相当拿得出手的镀金名片&#xff0c;品牌百度百科词条创建需要什么资料&#xff0c;今天伯乐网络传媒就来给大家讲解一下。 一、品牌基本信息&#xff1a;品牌身份的明确 品…

神之浩劫2下载教程 MOBA新游神之浩劫2在哪下载/怎么下载

《神之浩劫2Smite 2》重新定义了MOBA游戏的征服模式&#xff0c;为玩家带来更多的互动和进展。最近的开发者深度挖掘展示了游戏地图的全新设计&#xff0c;既简化了基本操作&#xff0c;又丰富了游戏选择。游戏中的敌人也有了新的进展方式。例如&#xff0c;击败火巨人和金之怒…

兄弟们,哪一家做智慧校园的公司比较靠谱?

开发技术参数 1、使用springboot框架Javavue2 2、数据库MySQL5.7 3、移动端小程序使用小程序原生语言开发 4、电子班牌固件安卓7.1&#xff1b;使用Java Android原生 5、elmentui &#xff0c;Quartz&#xff0c;jpa&#xff0c;jwt 6、SaaS云平台&#xff0c;私有云部署…

社区新零售:重构邻里生活圈,赋能美好未来

新时代的邻里脉动 在城市的肌理中&#xff0c;社区作为生活的基本单元&#xff0c;正经历一场由新零售引领的深刻变革。社区新零售&#xff0c;以其独特的商业模式、创新的技术手段和以人为本的服务理念&#xff0c;重新定义了社区商业的边界&#xff0c;重构了邻里生活的形态…