亚马逊AWS官方博客
莉莉丝《远光 84》在 AWS 上对版更操作的优化
关于莉莉丝
莉莉丝游戏是中国中生代游戏公司代表,在中国游戏市场保持领先地位。莉莉丝游戏自主研发运营多款精品游戏,包括《远光 84》、《战火勋章》、《剑与远征》、《万国觉醒》、《剑与家园》、《艾彼》等。2020 年 4 月,根据第三方统计机构 AppAnnie 、SensorTower 发布的数据,莉莉丝游戏在“中国游戏公司收入榜”中位列第三。同年 1 月 – 4 月,莉莉丝在“中国游戏公司出海收入榜”排行榜稳居冠军宝座。2022 年 4 月 25 日,莉莉丝游戏宣布,在新加坡成立发行公司 Farlight Games,总部设于新加坡,为莉莉丝游戏的全球发行提供支持和服务。
关于《远光 84》
《远光 84》是一款多端互通的大逃杀英雄射击游戏。相较于传统吃鸡游戏,Farlight 84 会通过其独特的喷气背包、英雄技能、武装载具、局内成长系统和多次复活机会,为大家带来上手更快、节奏更紧凑、更加“横冲直撞”的对局体验——在这里,相比于“苟”在角落里,你将看到更多激情“刚枪”的身影。Your Farlight, Your Highlight!
版更操作对大型 FPS 游戏的挑战
为了丰富玩家体验并持续吸引玩家,游戏开发会保持高频率的更新,不断优化游戏内容。持续的版本迭代对游戏的长期运营提出了较大挑战。对于一款拥有百万级 DAU 的大型 FPS 游戏,每一次游戏重大版本更新,都会有至少数小时的停服时间。在这段时间内,游戏技术团队需要完成代码部署与业务测试,时间非常紧张,如果碰到各类意外状况,则版本更新时间会更长;与此同时,在这段时间内,玩家也不能进行游玩,非常影响玩家体验,甚至造成玩家流失。
为了尽量降低版本更新对业务造成的影响,远光 84 团队与 AWS 合作,一起构建了基于 AB 服的权重切换方案,在尽量缩短版更时间的同时,也极力减少新版本上线后的 bug。
AB 服权重切换方案
AWS 架构优化与调整
此方案采用了 ALB + NLB 的组合,利用 ALB 的权重特性对流量进行 AB 服切换,NLB 后端接入 traefik 完成业务路由。
1. A/B 服建设
原有的生产环境被定义为 A 服,复制并优化出一套同样的环境,定义为 B 服。游戏新版本运行在 B 服。在 B 服的建设中,主要实现以下两点:
(1)统一将 80、443 与其他业务端口的路由都收口到 traefik,由 traefik 完成全部业务路由。
Traefik 是一个边缘路由器,这意味着它可以是整个应用平台的大门,拦截并路由每个传入的请求:它知道所有的逻辑和规则,这些规则确定哪些服务处理哪些请求(基于 path,host,headers 等)。
traefik 原理示意:
因为 traefik 也能独立进行证书相关的处理,在处理逻辑上与外部的 LB 服务存在一定的重叠。通常情况下,都是利用外部 LB 的强大性能进行证书卸载,而 traefik 只做流量路由。在 traefik 的默认配置中,443 端口默认会处理 tls 证书,为了与 NLB 证书处理相结合,必须要将做此配置 entrypoints.websecure.http.tls=false。完成该配置后,进入 443 端口的流量,traefix 都按正常流量进行处理,而不再做证书卸载操作。
对于客户端 IP 保留的需求,则需要对每个 entryPoint 做如下配置:
entryPoints.web.forwardedHeaders.trustedIPs=127.0.0.1/32,0.0.0.0/0
entrypoints.websecure.forwardedHeaders.trustedIPs=127.0.0.1/32,0.0.0.0/0
通过此配置,从 80 和 443 端口进入的流量,traefik 对 x-forwarded-for HTTP 标头进行放通,后端服务可以解析此标头,并获得客户端 IP。
(2)traefik 通过 NLB 对外进行服务。
在服务暴露时,我们选择 NLB 为 LB 类型,POD 以 IP 模式挂载到 NLB 后端 targetgroup,访问 NLB 80 端口的流量会被导入 traefix 80 端口。对于 443 端口的服务,我们也可以采取同样的方式,在 NLB 上进行证书卸载,并将流量导入 traefik 80 端口。对于其他业务端口,因为 traefik 上可以实现按端口进行路由,也支持后端 ingress 规则,可以通过不同的访问域名,进行业务路由。
NLB 服务 annotations:
service.beta.kubernetes.io/aws-load-balancer-type: external
service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip
service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing
service.beta.kubernetes.io/aws-load-balancer-ssl-cert: “arn:aws:acm:us-west-2:xxxxxxx:certificate/c3baddcb-560c-4057-b822-43451821afbd”
service.beta.kubernetes.io/aws-load-balancer-ssl-ports: “443”
NLB 后端接入配置示例:
在完成上述建设后,B 服是一个独立的游戏服务环境,可以通过 NLB 对外提供访问。在游戏版本更新的数天甚至数周前,我们可以将新版本部署到该环境中,配置影子域名,进行访问和充分测试,以减少新版本上线后的 bug。
2. A/B 服权重切换
在完成 A/B 服的独立建设后,我们需要为其配置统一的接入环境,让 A/B 服真正联动起来。在本方案中,我们采用了 ALB 作为统一的入口,并利用 ALB 的权重分配属性,对 A/B 服进行流量切换。
NLB 利用 private link 技术,在每个 AZ 中占用一个 ENI IP,可以通过该 IP 访问到 NLB。以 3AZ 的 NLB 为例,我们组建一个 IP 模式的 target group,该 target group 中包含 NLB 的 3 个 IP,并以 Http 协议 listen 在 80 端口上。A/B 服分别有一个 NLB,我们分别为 A/B 服创建此 IP target group。
随后,再单独创建前端 ALB,并为 ALB 创建监听器和相关规则。在 ALB 转发规则中,可以添加多个 target group,并做权重分配。对于 80 端口,我们将之前创建的 A/B 服 IP target group 均加入其中,并配置 A 服 target group 权重为 1,B 服 target group 权重为 0,以此确保所有流量均流入当前的生产环境。对于 443 端口,除了对证书进行额外配置以外,其他操作保持与 80 端口配置一致。
在进行版本更新时,因为 B 服已经完成了代码部署和业务测试,则只需要在前端 ALB 上调整 target group 权重即可。
完整架构图:
ALB 监听器配置:
游戏业务优化与调整
在业务层面,由该款游戏主程对游戏业务进行调整,主要从服务、技术、流程等 3 方面进行了优化。
服务优化
在业务上,将 B 服定义为影子服,其对外暴露的所有服务,在域名上均添加 shadow 后缀,以示与生产服进行区分。这一点尤为重要,特别是进行版更后线上验证时,必须让团队全员对影子服的概念和功能有充分理解,进而避免由于多环境切换带来的逻辑混乱。
建设影子服,相当于重建一套完整的服务系统,对于如何梳理微服务的复杂调用以及如何处理历史遗留问题,都存在一定挑战。对于微服务梳理,首先整理出全部的对外域名,对每个域名进行分析,深入到内部服务,完成该服务与 trafik 路由的整合。对于历史遗留问题,这是一次业务优化的契机,因为影子服不承担生产流量,但又与生产息息相关,所以是一个比较适合做业务优化测试的环境。
技术优化
对比生产环境,影子服在进行业务优化的同时,必然会产生不同的配置与参数。远光 84 项目通过 Consul 做配置管理与服务发现,并实现了“配置覆盖”的概念,即:影子服在切换到生产环境的时候,生产环境的配置也被覆盖,确保架构、代码、配置同步切换。
在切换时,考虑到影子服也需要提供对外访问(供项目团队进行代码部署与测试),需要进行“DNS 双向切换”,即:生产域名指向影子服,影子服域名指向原生产环境。在完成切换后,可以继续在影子服上进行各类测试,保持项目团队的使用方式不变。
流程优化
由于影子服可以独立提供服务,在缩短版更窗口的同时,更重要的是给项目团队提供了提前验证的机会。对比以往只能在版更窗口内测试的方式,影子服提供了更灵活的测试方式和更长效的测试窗口。
为了更充分利用影子服提前验证的功能,除了采用新代码以外,测试数据必须采用真实业务数据。为此,我们通过 AWS 数据库克隆技术,将生产环境的 DocumentDB 和 MemoryDB 进行克隆,并提供给影子服进行测试。借助此方案,在不影响生产环境的同时,最大限度地模拟生产环境来进行游戏新版本测试。
除了进行功能测试和压力测试外,莉莉丝各团队还基于影子服进行了内部竞赛,以真实的业务对游戏新版本进行充分测试。通过内部竞赛,我们确实发现了几个 bug,并进行了紧急修复,从而提升新版本上线后的玩家体验。
优化后的版本更新方案
版本更新前:
为缩短版本更新操作时间,我们可以将针对 B 服的所有配置检查、资源开启、代码部署、QA 测试等操作前置到版本更新前的准备期。另外,从原有 A 服的架构,切换到 A/B 服的架构,涉及到接入端 DNS 变更的问题。考虑到 DNS 缓存的长尾效应,在前端 ALB 已经接入 A 服后,即可完成 DNS 切换。DNS 记录已经刷新的客户端,通过前端 ALB 访问到 A 服;未刷新的客户端,会按原有地址直接解析到 A 服,从而确保 DNS 缓存的长尾效应不影响客户端对当前游戏环境的访问。准备阶段的主要操作:
- AWS 配置检查:确保 A 服与 B 服配置一致,特别是 EKS IP 资源池配置,确保 B 服开启时,能够拿到充足的 IP 进行 POD 部署。
- 业务配置检查:确保 A 服与 B 服配置一致,如有新配置,则只在 B 服上生效。
- B 服资源开启与代码部署:开启资源、开启服务、部署新版本代码,并连接到测试数据库(该数据库是从生产库克隆的数据)。
- QA 测试:在 B 服务器上,进行充分测试,最大限度找出 bug。
- ALB 预热:考虑到现有环境已经有大量玩家,在前端 ALB 承接生产流量之前,必须要对 ALB 进行预热。在本次操作中,AWS 技术经理联系后端产品团队,在短时间内完成 ALB 预热,确保 DNS 切换后,线上业务平稳运行。
- DNS 切换:将 DNS 解析从原 A 服地址,切换为前端 ALB;如果有意外情况发生,则立即进行回滚。
- A 服在线监测:由 A/B 服架构中的 A 服承担生产流量,持续监控一段时间,重点注意此架构是否出现异常。
版本更新期间:
- 停止服务:关闭 A 服,缩减 POD,玩家不能访问游戏。
- 调整数据库指向:配置 B 服,将数据库地址指向生产数据库,并测试数据库连通性。
- 调整 ALB 权重:配置 A 服 target group 权重为 0,B 服 target group 权重为 1,全链路业务测试通过后,即完成版本更新。
版本更新完成后:
- 持续优化:版本更新后,A 服为影子服,在影子服上继续进行后续的版本迭代测试,为下一次版本更新做准备。
方案优势与经验总结
从业务角度,此方案有以下几点优势:
- DNS 保持不变:前端 ALB 与 DNS 映射配置保持不变,客户端接入配置不变。
- 提前验证:影子服部署完毕后,QA 团队可由影子服 NLB 进行独立访问,可提前数天进行充分测试,减少新版本上线后的 bug。
- 缩短停服窗口:在停服期间,生产服完成服务停止后,影子服将数据库配置指向生产库,最后完成 AB 两个目标组的权重调整,即完成版本更新。
- 新技术尝试:在影子服上进行新技术部署,并采用生产环境数据进行测试,降低新技术落地风险。
合作经验:
AWS 产品插件化的灵活组合,给技术方案提供了各种可能性。在多种方案的选择中,结合业务目标与实际操作经验,与客户深度配合,共同打造与客户业务相匹配的优质方案。
《远光 84》主程张星评语:“AWS 团队的专业素养为我们注入了信心,使我们能够不断推动技术探索和实践的进步。通过与他们反复合作共建,我们的架构得到了显著的改善,显著提升了玩家的体验,同时也实现了持续的成本削减。”