网易游戏如何做到动态伸缩?

Posted by 刘勇(lyonger) on 2021-05-14

网易游戏如何做到动态伸缩?

  • 目前网易的海外游戏大部分运行在公有云上,比如网易游戏《荒野行动》、《终结者2:审判日》、《量子特攻》等一直稳居海外畅销榜前列。同时海量公有云实例的服务器成本投入巨大,因此更灵活的计费方式、服务器的动态伸缩成为了我们急需突破的问题。

  • 今天由网易游戏资深运维工程师lyonger为大家带来《网易游戏如何做到动态伸缩》的分享。

背景介绍

  • 大家知道,相比传统的计算资源,公有云最大的特性在于支持按需计费、可快速创建与销毁,网易游戏的动态伸缩方案恰好就是基于这些特性来实现的。
  • 谈到按需计费、快速创建与销毁。大家可能会联想到云原生中的serverless,它具备无状态(可快速创建与销毁)、无需管理服务器、自动伸缩、按需计费等特性。那它能解决游戏业务下的动态伸缩问题吗?答案是:现在来看它更适合web业务,对游戏业务还有些"水土不服"。主要原因是web的无状态特性具有天生优势,而游戏业务则不同。它的特性就是有状态的,比如各游戏服务之间启停有严格的先后顺序、需持久化存储、对数据库依赖重等,这导致游戏业务不能很好的"享受"云原生技术本身带来的自动伸缩"福利"。 那怎么发挥公有云的优势呢?

适合动态伸缩的游戏类型

  • 那么游戏业务需具备怎样的特性才适合动态伸缩呢?从网易游戏《荒野行动》、《终结者2:审判日》的成功经历来看,主要有如下几个特性:
  1. 玩家在线人数存在高低谷,像波峰浪谷一样此起彼伏。人数增长的时候自动扩容,人数逐渐下降的时候自动缩容,这样才能更好的发挥动态伸缩的效果。
    image
  1. 大世界游戏。如下图所示,大世界的游戏,玩家在服务器列表看到的区服往往是由分散在不同机器群组上的游戏服务组成,比如中心服部署在A机器群组、大厅服在B机器群组、战斗服在C机器群组、周边服在D机器群组,我们可以对某类游戏服务进行动态伸缩且玩家依旧在同一个服体验。而滚服型游戏是所有游戏服务均在同一台机器中,并不能针对单个游戏服务动态伸缩,只能针对单个游戏服伸缩,而伸缩游戏服并没有解决旧游戏服的负载问题,且不灵活。
    image

动态伸缩方案详情

  • 了解完什么特性的游戏适合动态伸缩后,我们看看网易动态伸缩的演进历程,又遇到了哪些问题。总体的演进历程如下图所示,经历了四大难关,下面我带你一起体验这奇妙的旅程吧。
    image

公有云的调研过程

  • 网易游戏是在混合云下部署的,以AWS为例,在方案选型时,我们了解到有两个服务提供了动态伸缩的功能,分别是AutoScalingGamelift。前者主要基于采集的metricCloudWatch Alarm来实现EC2的动态伸缩,是EC2的一个附加功能。后者是为游戏量身定做的一套托管、部署的解决方案,托管整个游戏的会话连接数信息,通过配套的SDK采集信息来实现EC2的动态伸缩。

  • 如下图所示,AutoScaling Group主要使用EC2实例的CPU使用率作为metric来设定伸缩的阈值。这会带来以下两个问题:

    • 缩容时会立刻把实例终止掉,玩家会立刻掉线,这种情况是不可接受的。
      image
    • 它只提供AutoScaling Group里所有EC2实例的CPU网络流量这些常规指标,无法按业务指标设定阈值进行动态伸缩。
  • 关于无法按业务指标设定阈值进行动态伸缩的问题,通过再进一步调研发现AutoScaling Group配合CloudWatch Alarm使用时,支持通过日志方式采集数据,日志里出现某个关键字时可触发一个alarm,最后以这个alarm来触发autoscale事件,从而达到根据业务指标来动态伸缩的目的。
    image

  • 关于缩容时会立刻把实例终止掉的问题,云厂商提供了生命周期钩子的解决方案。钩子可以设在启动或者终止实例的时候,可以在终止实例前,调用lambda或者发一个SNS消息, 甚至调用Step Funtions完成一系列的任务,比如轮询游戏服的状态,看还有没有玩家在战斗,最后通过改变实例的状态,让AutoScaling继续终止实例。
    image

  • 通过上面的尝试后,似乎一切都很美好,但随着深入调研又遇到如下"三座大山":

    • 通过日志方式采集数据时,用户需在机器上安装一个agent,这在原来的基础上多引入了一个未知依赖,让动态伸缩策略的正确性不再变得那么可靠。
    • 使用生命周期钩子的解决方案,牵涉到的公有云服务很多,排查问题比较困难。
    • 网易游戏使用的云服务器不止一家云厂商,而是基于混合云。因此需要一套和公司平台工具适配的通用方案来实现。
  • 跨过上面这些"大山",你就能看到山外"绚丽多彩的风景"。嗯,我们可是万能的SRE,冲吧。

网易动态伸缩方案

网易动态伸缩方案v1.0

  • 为了看到山外"绚丽多彩的风景",我们研发出了网易动态伸缩v1.0版本,主要架构如下:
    image

  • 主要分为策略模块、执行模块、周边平台三个部分:

    • 策略模块:主要提供了类似AutoScaling GroupCloudWatch Alarm采集业务数据来设定阈值,触发动态伸缩策略的能力。
    • 执行模块:主要接收策略模块发来的指令,比如要对哪些游戏服务扩缩多少台机器。把接收的指令转化为指令流程,依次调用周边平台API。
    • 周边平台:Aladdin为远程服务器指令执行平台、Skyline为混合云管理平台、ELK主要提供扩缩容数据展示。
  • 随着业务的深度使用,逐渐暴露出以下2个问题:

    • 策略模块由游戏进程实现,未和游戏业务解藕,且需产品自己实现,接入有成本。
    • 执行模块没有鉴权功能,存在安全隐患。

网易动态伸缩方案v2.0

  • 为了解决v1.0遇到的问题,实现了v2.0版本,主要架构如下:
    image

  • 在v1.0的基础上主要做了如下改善:

    • 策略模块:与游戏进程解藕,集成在我们的扩缩容框架Transformers中,无需产品额外开发实现。
    • 执行模块:在前面加了一次ApiGateway,主要用于鉴权、分发任务的执行。
    • 记录模块:主要根据游戏在线人数记录扩缩容的历史图表数据。

动态伸缩的流程说明

  • 网易动态伸缩方案可以适配多种不同的公有云,但不同云下的扩缩容流程大体一致,详情如下:

扩容流程说明

  1. 策略模块根据采集的指标,触发执行模块执行扩容指令;
  2. 执行模块调用skyline混合云api对指定厂商的公有云服务器开机;
  3. 执行模块调用Aladdin远程服务器指令执行平台对刚开机的公有云服务器上执行指令,部署游戏进程进行扩容。

缩容流程说明

  1. 实现策略模块根据采集的指标,触发执行模块执行缩容指令;
  2. 执行模块调用Aladdin远程服务器指令执行平台对刚需缩容的公有云服务器上执行指令,关闭游戏进程进行缩容;
  3. 执行模块调用skyline混合云api对指定厂商的公有云服务器关机;

总结

  • 穿越了旅程中的重重荆棘,我们不仅看到了收获了"旅途中的风景",更得到了公司乃至业界同仁的认可。通过游戏动态伸缩方案,最终为公司节省了不少成本。
    image

  • 同时网易游戏资深运维工程师杜俊超作为主题演讲分享的重磅嘉宾,在中国区Game Tech Day游戏开发者大会上分享了关于网易动态伸缩方案的实现细节,感兴趣可查阅网易游戏的微信公众号文章

  • 孔子曰:“学以致用,知行合一”,作为一名技术人员,从开源技术中学到技能只是"基本功",最终能把技术转化成业务价值才是"武世绝学"。我们要学会从运维岗位中创新、突破自己,为完善业界的游戏运维方案献出绵薄之力。

其他



支付宝打赏 微信打赏

赞赏一下