概述
在过去的几天,拳头游戏电竞技术团队在努力解决围绕着2022季中冠军赛的一系列技术问题,尤其在我们用来为线下选手和远程参赛选手平衡ping值的工具上。
我们初次发现的问题是一个存在于我们称之为“延迟服务工具”中的错误 -这个工具是用来将所有参赛选手的延迟(ping值)调整到 35ms范围, 而该错误会使在釜山场馆中的选手在比赛时产生额外的延迟,并使得其实际延迟高于场馆现场电脑屏幕上显示的延迟(35ms)。因此,在远程对局中,在中国的选手是在 35ms ping值区间进行比赛的,但在釜山的选手ping值则较之更高。很不幸,我们并没有在季中冠军赛开始之前发现这个问题,其根本原因是一个代码漏洞错误计算了延迟,导致该数值在日志中也是错误的。因此,即使我们的监控显示一切正常,而实际上却存在着错误。
我们在5月13日对该延迟服务工具进行了配置修改,以解决这个漏洞。考虑到之前实际网络延迟增加对釜山场馆中的比赛造成的影响,我们做出了艰难但是必要的决定:对B组对局ping值不相同的三场比赛进行重赛。
然而,5月13日这一配置修改带来的另一个问题是,现在在釜山选手电脑屏幕上显示的是错误的、低于实际 ping值的数字 ——尽管实际ping值现在已被修正并确保对等。 其后果是,当我们播放选手屏幕画面时,屏幕上会呈现一个错误的较低的 ping值。同时,由于我们团队没能及时将这个外显误差进行有效沟通,故而观众会认为在场馆里的选手正在以低于他们实际延迟的ping值进行比赛。
本篇文章将从技术角度复盘从赛前到现在(小组赛结束)发生的整个情况。
赛前阶段
当我们开始计划今年季中冠军赛最后阶段的技术设置时,新冠疫情带来的持续挑战摆在了我们面前。LPL赛区代表队,Royal Never Give Up (RNG) 不会从上海前往釜山,而会远程参赛。
表面上看,简单的解决方案是让远程参赛的队伍连到季中冠军赛比赛服务器就行,其他队伍在线下进行比赛。然而这样的解决方案也并不理想,存在诸多问题。
问题之一就是釜山和上海之间相隔大概 850 公里(中间隔着黄海)。这意味着,网络通信需要在上海和韩国的季中冠军赛比赛服务器之间来回传输。
数据在客户端和服务器间往返传输所需的时间就是我们常说的“ping值”(又称为延迟)。从 RNG 俱乐部所在地到季中冠军赛的比赛服务器,大约自然延迟是 35毫秒(ms) 。 而且其他十支参赛队伍会在釜山的比赛场馆里参赛,他们的延迟会低很多,大约在 15ms左右。请注意,我们本文里的ping值通常都指一个范围,因为ping值常会在+/-5ms的极小范围内波动。
如果是一名普通《英雄联盟》玩家,35ms 到 15ms 之间的差异或许是很难察觉到的。但对职业选手来说,这足以改变比赛手感,产生细微但仍能察觉到的差异。拳头游戏电竞赛事核心原则中的一条,就是保证竞赛公平性。我们希望让所有参赛的队伍,能够在平等竞技条件下竞赛。
既然说到平等竞赛环境,那我们说明一下ping值差异问题。
让远程参赛成为可能
因为电竞赛事是在网络上进行的,我们希望能寻找一些远程参赛的办法。
但随之而来的两个问题是:
1) 上海和釜山之间 35ms 的延迟是否能够保证最高水准的竞技发挥?
2) 我们是否能提供同等竞赛环境,让所有选手都有相同的延迟?
对于第一个问题的回答是:“是”。对于英雄联盟电竞赛事来说,在最高级别的比赛中,我们认为最高可忍受的延迟极限为 40ms(上下浮动5ms)。 通过与内部和外部合作伙伴,包括我们内部的游戏分析和设计团队的深入讨论和分析,我们在2020年中确认了这个范围。当ping值超过40ms范围时,大部分职业选手会开始注意到延迟,它也开始影响诸如英雄选择、技能释放以及对对手的操作做出快速反应的能力。
对于第二个问题的回答,我们考虑了以下几个方案:
方案一:每支队伍都在自然延迟下进行比赛
该方案建议,远程参赛队可自行选择所拥有的最快速网络,直连到季中冠军赛比赛服务器。这意味着现场参赛队伍会在低 ping值(~15ms)下比赛,而远程参赛队伍(以RNG为例)则要在其自然延迟下比赛。从中国连接到釜山的自然延迟约为 35ms。
我们考虑过,但还是否决了这个方案。因为基于竞赛公平性的原则,我们希望保证对每个参赛队伍的公平。
方案二:将服务器架设于韩国和中国的中间点
还有一种解决方案是,如果中韩两国之间的ping值是 35ms,直接把服务器放在两地中心点,延迟均分,不就各自只有 17.5ms 了吗?实际上这个方案的实施仍然具有诸多挑战…其中一个最大的问题是,要在汪 洋大海中间架设服务器。
方案三:使用人工延迟
所以如果在韩国参赛的队伍ping值很低,而在中国参赛的队伍ping值又相对较高,那给韩国那边加上一些延迟使两边对等,这可行吗?我们能做到吗?
事实证明,《英雄联盟》的开发团队已经有了一种引入人工延迟的方法,即延迟服务(Latency Service)。也有人叫它:“假ping”。这是一种客户端/服务器功能,旨在解决疫情下,远程竞赛需要公平竞赛环境的需求。延迟服务允许我们设置一个目标值(如 35ms),它会在客户端和服务器上为每个玩家加入延迟,使大家保持基本相同的延迟水平。
我们曾成功地在过去一些英雄联盟电竞赛事里运用了该工具,当时的比赛都是远程进行的。但这次是首次在全球性赛事上使用这一工具,并且其中部分选手还在釜山本地场馆进行对局。虽然我们之前使用过,但环境中的部分细微差异总有可能造成我们无法预见的错误。在训练赛服务器上的人工延迟应用效果比较理想,再加上我们长期使用的可靠网络基础设施和测试方法,我们当时认为已经有足够多的应用实例,能在小组赛阶段之前发现所有的重大问题。
我们的选择
再三衡量各种方案后,我们认为最重要的是保证竞赛公平性,那么使用方案三 - 人工延迟便是最好的解决方案。
了解人工延迟:它的工作原理
延迟服务工具内置在《英雄联盟》的本地客户端/服务器端的网络协议栈中。它会持续测量每个玩家和服务器之间的实际网络延迟,根据需要,通过添加延迟进行调整,以达到目标延迟值。这是一种客户端/服务器端解决方案,目的是通过引入延迟来保证双方的延迟均等。
上图显示了系统的各个组件。图片顶部是游戏服务器组件,底部是游戏客户端(选手的电脑)。在目前这种情况下,延迟服务的目标延迟值为 35ms。图中的红色箭头表示存在的实际网络延迟。正如所看到的,釜山的选手 1 和选手 2 显示为 15ms 的“真实”ping值,而上海的选手 10 显示为 35ms的ping值。黄色框表示在客户端和服务器端人为添加了多少延迟。在这种情况下,选手 1 和选手 2 分别向客户端和服务器端添加了 10ms 的延迟,达到了目标延迟 35 ms。选手 10 已经具有等于目标延迟 35 ms 的实际延迟,因此没有添加延迟(0ms)。
同等竞赛环境还是两个不同的竞赛环境?
想要深入了解这一话题,可能要提起我们曾经对于远程环境和本地环境所做的一个决定。
对于电竞赛事技术团队来说,我们一直追求把现场赛事的风险降到最低。2012年洛杉矶,第二届全球总决赛比赛因网络问题被迫中断。这段回忆,将永远烙刻在所有拳头电竞人心中。
在决定2022 季中冠军赛的网络架构设计时,我们意识到必须在两种不同的策略之间做出决定。
策略一:所有场景下使用同等种网络架构设计
在国际比赛中,我们的竞技比赛都是在使用场馆内的线下服务器上。这为我们提供了高度的可靠性,因为它允许我们直接控制网络和服务器硬件。考虑到有一支队伍远程参赛,那么就必须构筑这样一个场景:至少会有一支队伍将通过互联网服务器进行比赛。那么如果有一支队伍需要通过互联网服务器参赛,一个策略就是彻底放弃我们的本地部署,转而让所有队伍都通过互联网服务器进行比赛。
鉴于稳定性原则,我们知道如果必须架设互联网比赛服务器,那就要选择十分信得过的部署方案。很显然,韩国的比赛服务器是值得考虑的选择。这是一个仅供职业比赛使用的环境,和韩国公共服务器位于同一数据中心,并常用于LCK韩国联赛。同样这也意味着这个服务器有无数小时的运行数据来验证其网络的良好连通性和架构的可信赖性。所以当至少有一支队伍需要远程参赛时,用这个节点是合理的。但接下来的问题是,是应该在所有比赛中使用它,还是只针对远程比赛使用。这便引出了策略二:最小化网络风险。
策略二:仅在必要时使用远程参赛,最小化网络风险
在之前的策略中,考虑到某些比赛需要在互联网环境中进行,那么问题就变成了:“何不统统放在这个环境下呢?”这个答案很简单:互联网的可靠性。互联网有时候风平浪静,有时候则未必。如果所有季中冠军赛比赛都在互联网服务器上进行,那么任何网络问题都可能导致比赛在进行中出现问题。如果只是远程比赛通过互联网进行,那网络出现问题的概率就会大大降低。我们相信通过我们的计划,能够将风险降到最低。由于我们相信我们有能力通过使用人工延迟来实现ping值在同等竞赛环境,所以这只是一个复杂性与可靠性的简单问题。为了实现更低的风险(减少互联网的不可靠性),我们增加了一点复杂性(两种网络架构设计)。
考虑到这两种选项,并基于我们的评估,我们决定采用策略二,它能够为赛事的可靠性和竞赛公平性带来最低的风险。
下方的图表就是我们所选择的网络架构设计,展示了在不同情况下网络是如何链接运行的。
最合理方案
考虑到以上种种因素,我们决定在使用人工延迟服务并维持竞赛公平性的情况下支持两种不同的网络架构设计。两支都在场馆的队伍比赛时,将使用架设在季中冠军赛场地内的本地服务器。而对上远程参赛队伍时,对战双方均在韩国数据中心的比赛服务器上进行比赛。拳头游戏电竞技术团队设置了系统并进行了基础架构测试,以确保一切运转正常。其中包括了各种测量和监控,如 ping值、网络抖动,以及对丢包的仔细检查。我们也让队伍在这个比赛服务器上进行训练赛,并让他们来到现场,进行技术测试。
但在第一比赛日结束后,选手告诉我们,比赛的时候感觉很卡。部分选手表示,即便游戏屏幕上显示 35ms,但实际体感却高于 35ms。当时我们所有的日志和基础架构监控显示一切正确,但我们决定继续调查,找出问题的原因。
找寻漏洞
引起这些问题的原因还是不清楚。由于架构监控工具并没有汇报错误,但我们却收到报告说比赛很卡。我们缺少特定漏洞或特定游戏内情况来定性。于是我们又回到了基础问题上。哪些数据是可用的?我们手里都有哪些日志?我们能收集到什么信息?
对此我们采取了两步走的做法。首先是向参赛的职业队伍收集问题,帮我们理解情况,到底哪里出了岔子。你们是在哪儿发现问题的?是场馆服务器还是比赛服务器?是场馆网络环境还是训练赛环境?是所有对局都这样?还是只是个别情况?与此同时,因为标准报告没有显示任何错误,所以我们开始查看其他日志和指标,寻找任何可能的差异。我们也提取了赛事客户端和服务器端的日志,并开始深入研究。
举个例子,我们曾假设问题是,也许游戏服务器没有保持稳定的帧率。于是我们提取了日志,并将数据放入一个查看工具中,把数据可视化为上面的图表(如上示意)。它显示了我们在每场比赛中都有非常稳定的帧率。所以这并不是职业选手报告的问题原因。
查阅日志是一项极其细致而艰巨的工作。数据本身看起来就像一页又一页看似随机的数字流,必须通过各种工具进行编译,将其可视化,使其有意义。每一轮的彻查,我们都没有发现异常。
在我们查看日志和代码时,我们逐渐收到了来自各方队伍的更多反馈。大家对季中冠军赛场地环境的抱怨比其他任何环境都多。这和我们的理解有所相背。毕竟,线下比赛和选手在同一建筑里的硬件上进行的。在拥有完美可控的网络环境下怎么会比通过在韩国互联网服务器上进行比赛感觉更糟糕?
这引发了另一个设想…如果日志的延迟测量显示良好,但体验相反,那会不会是日志出了问题?会不会是我们测量延迟的方式有问题?
开发团队随即写了几段代码来验证这个猜想。一般情况下,日志是根据游戏数据包在服务器的网络层和客户端的网络层之间的往返产生的。这些日志没有发现任何错误。所以我们换了一种方式用新工具来测试延迟。不再测试网络层的流量延迟,改为测试整个“端到端”的循环,从用户点击,再到看到该点击响应。换句话说,测量的不再只是网络表现,只要游戏中任何系统之间的互动会被选手接触到,就都会去测量。
可以参考以上的图表了解这个概念。现有的网络 监控测量的是包括网络层延迟和延迟服务时延,这一点会通过绿色箭头展示在上图中。但是新的工具模拟了输入层的输入,然后测量在该输入和服务器响应之间发生的全栈延迟。红色箭头展示了新工具的监测轨迹。
有了这个新工具,我们就能在实验室中进行测试,看看能不能重现选手们的问题。
我们做的第一件事,就是在不运行延迟服务下,设置一个基准线。因为我们有来自公共服务器上无数小时的玩家数据,我们相信服务器没有任何漏洞,因此我们以它们来做参照组。 第一个设置基准线的实验模拟了在韩国参赛的队伍和在中国参赛的队伍均从互联网接入服务器的场景。
实验一:关闭延迟服务工具,对比韩国和中国的网络
这类实验的数据十分复杂,这里我们将其整理之后用图表的形式展现出来,可以帮助大家理解我们所看到的情况。
如果你沿着横轴(游戏时间)看,会发现一开始(图表左侧)的延迟值很低。几分钟后(图中从左到右的中间部分),我们开始模拟较高ping值的网络(例如:上海)。我们可以看到,竖轴上的延迟在上升。这和预想的完全一样。在低ping值网络下,延迟较低;在高ping值网络下,延迟较高。
第一个实验,作为参照组,说明用新工具测量的结果是符合我们预期的。这是个好的开始。
下一个实验,我们会用相同的步骤进行检测,但这次我们开启延迟服务工具。
实验二:开启延迟服务工具,对比韩国和中国的网络
我们需要记住的是,人工延迟服务的目的就是无条件平衡网络 ping值。所以如果我们更改了实验室中的网络ping值特性,那么我们的预期就是延迟服务将加入延迟,使得测量值保持相同。然而,数据却表明不是这样的。正如所看到的,上海的模拟网络所显示的延迟比韩国模拟网络所显示的延迟要低。这是在我们意料之外的,这也展示了延迟服务为韩国网络环境带来了比上海网络环境更高的延迟。
从这份报告我们可以确定三件事:
1) 问题是真实存在的,且确实与选手们报告的情况相符
2) 我们自己可以在实验室重现这个问题
3) 问题很可能就出现在人工延迟工具上
从这些信息入手,我们就知道需要在代码中的何处寻找问题。 在运行各种额外的测试以了解我们更改实验室环境的特性时发生了什么后,我们意识到,只有在实际 ping显著低于目标延迟的情况下才会出现计算错误。 在这种情况下,实际延迟将远远高于屏幕上显示的延迟。
这便解释了目前的一系列问题。为什么日志不显示这些问题:因为运算错了。为什么场馆比网络服务器体感还差:因为环境 ping值越低,这个漏洞就越明显。这也解释了为什么在釜山现场的选手觉得比赛体感延迟比屏幕上显示的约 35ms差多了:因为实际延迟确实高于 35ms。
既然找到了问题,那下一步就是尽快解决它。
幸运的是,查阅代码后,我们可以很好的理解这一问题。从这里出发,我们假设可以通过做一个配置改变,来补偿这个计算错误。
既然我们有了办法来模拟环境,也有了办法来使用自研工具测试实际延迟,那么就可以通过调节配置,得到我们想要的结果。
以下图表显示了与两个实验相同的网络环境,但这一次使用了将错误修正后的配置文件。
实验三:在正确的配置下启用延迟服务工具
和前两次实验一样,先模拟一个低 ping值环境,几分钟后再模拟一个高 ping值环境。和之前实验结果不同的是,在使用了更改的配置后,这次延迟服务的补偿终于正确了。这张图表显示,即便 ping值从低切换到高,延迟都是基本相同的。
问题解决了吗?
这个配置修正了一个游戏中 ping值计算的错误,却也产生了一个副作用,即釜山场馆内选手屏幕上的帧数和 ping值显示(Ctl-V)会出现错误。显示的 ping值会比实际 ping值低大约 13ms。这是因为,我们上述对延迟服务所做的配置更改,本质上是在目标值上直接添加了一个偏移量,以补偿计算错误。这会对客户端中记录和显示的 ping值应用偏移量产生下游效应(稍后我们会详细分析这点)。其结果是外部客户端显示的数字将比实际 ping 低 13 ms左右。虽然这个结果不是完美的,但当时我们认为确保同等竞赛环境里的对等延迟是一件更重要的事情,即便这意味着釜山场馆外显屏幕会显示错误的数值。
下一步措施,以及一个困难的现实
既然我们已经知道如何准确测量真正的延迟,并找到了一个通过更改配置能够补偿这个计算错误的解决方法,我们马上准备了一个计划进行修正部署,并准备向选手和粉丝沟通,说明之前出现的问题。
但当我们明白了问题所在,我们却面临着一个困难的现实。
我们意识到,在场馆内的选手之前都是在高于35ms范围 的网络下进行比赛的,但在上海远程参赛的队伍,却是在实际的35ms范围内进行比赛的——35ms左右是釜山至上海的自然网络延迟 。我们没有做到公平竞争原则下的延迟对等。
我们需要立即告知队伍。唯一的问题是,这个差异是否大到足以需要重赛。这是一个赛事运营的决定。经过估算,由于计算错误,前三个比赛日中釜山和上海的真实延迟差值大约在15 - 20ms 之间。这也让我们最终做出一个艰难的决定,即使用更新后的配置,将三场受影响的比赛进行重赛,以确保竞赛公平性。
理解ping值的显示数字
在我们决定重赛早期比赛之后,我们知道我们还有很多工作要做。这意味着重新制定赛程,并与队伍联系,以确保他们了解正在发生的事情和原因。 这还意味着我们准备对比赛场馆的服务器和数据中心服务器的配置进行更改,并重新运行所有测试以验证更改是否正确运行。 我们还邀请职业选手前往比赛现场测试新设置下的服务器,多次检查我们是否解决了这个问题。 我们甚至进行了盲测,让职业选手在不知情的情况下尝试两种配置,并让我们知道哪一种感觉像 35ms 延迟,哪一种感觉不止于此。
很不幸的是,我们并没有及时且清晰地将这个外显误差向各位玩家以及转播团队沟通。
不久之后,我们的粉丝就指出了对韩国队伍来说似乎是不公平的优势。 我们开始看到粉丝发布一张显示 22ms 延迟的屏幕截图,而不是预期的约 35ms 的延迟。
这是我们必须回应的问题。
如之前提到的,延迟服务中漏洞的解决方法是添加到配置文件中的补偿偏移值。 此偏移量对屏幕显示的数值有副作用:
在上海的选手屏幕显示的 ping值是正确的
在釜山的选手屏幕显示的 ping值不正确,并且比实际延迟低约 13ms
这里重申一下原因,上海的屏幕显示的ping值是正确的,因为当他们使用延迟工具时,他们已经达到了35 ms左右的延迟目标,因此延迟工具并不会为他们的体验添加补偿。而釜山的屏幕数字显示不正确的原因是,在引擎中引入了延迟配置偏移量,它纠正了引擎中的延迟错误计算,让实际延迟能够达到35ms这个目标。但这将产生让日志和ping值显示偏移约 13 ms 的下游效应。
为了验证这一点,我们从 30 多个进程中收集了客户端日志,并绘制了屏幕上显示的 ping/延迟数据图表(如下示意)。
上图只显示了RNG相关的比赛,竖轴是显示的ping值。 与上一个部分显示数据的图表不同,在这种情况下,横轴代表离散的数据集,每个游戏都有一个数据集。 因此,每个绿色方块都是报告的 ping值的直方图,这些都是从客户端日志中读取一个选手的一场比赛的数据。 正如这里可以看到的,这些值存在一些波动,并且值都在 33 ms 和 39 ms 之间的范围内。 这符合 RNG 的 35ms +/- 5ms 的已知自然延迟值。
下一个要查看的数据集是釜山选手在配置更改之前和配置更改之后的客户端日志(如下示意)。
在上图中,我们过滤了数据,仅显示在釜山比赛场馆进行的比赛。左侧显示的游戏是配置更改之前进行的比赛。正如这里可以看到的,显示数值在 33 到 39ms 之间,范围为 35ms +/- 5。我们也知道,通过更新“端到端”的监测工具进行检验以及结合选手报告,真正的延迟和所显示的不同。
在图表的右侧,我们看到在使用能够提供相同真正延迟的新配置后,显示延迟数值介于 19 ms和25 ms之间-通常在22 ms +/- 5 ms的波动范围以内。将这两个值相减可以看出,显示ping值中的偏移误差是一致的,大约为13ms (35ms - 22ms = 13ms)。因此,在配置更改并解决实际延迟问题后,当釜山屏幕显示ping值显示 22 ms左右时,实际上真实延迟是 35 ms左右。
回到显示 T1 与 SGB 比赛的屏幕截图,这解释了当时 Zeus 的屏幕显示ping值为 22 ms左右,而在添加我们从实验中得到的校正偏移值后,真正的延迟则是在 35ms左右。
结论
作为支持现场比赛的拳头游戏电竞技术团队,我们一直竭尽所能地对比赛环境进行测试、检查、再三检查,以确保无虞。我们一直是以为职业选手创造同等竞赛环境作为最高优先级。我们的目标是让技术让路,将舞台留给运动和比赛本身。
我们也希望尽一切努力坚持竞赛公平性,并为全世界的粉丝创造更好的观赛体验。任何计划的修改,都可能带来风险。但我们希望做到最好,来规避风险,并为选手和粉丝创造最好的体验。
但在这次整件事情中,我们未能及时发现的漏洞影响了比赛,我们对ping值显示错误问题的沟通也不够及时透明。我们再次对此造成的问题和困扰致以深深的歉意。
我们深知这几天对大家并不容易,因此我们正在进行额外的测试和验证,以确保后面的对抗赛和淘汰赛阶段顺利无虞。我们还要感谢队伍和选手们在此期间表现出的坚韧,尽管有诸多障碍,他们仍为我们解决这些问题提供了宝贵的反馈。虽然我们不敢妄言以后永远不会再出现任何可能影响比赛的程序问题,但我们承诺一定从这次事件中吸取教训,更及时地与队伍和粉丝进行沟通,并持续地为良好的赛场环境做出不懈的自我监督和自我改进
精彩评论
拳头:说点他们看不懂的糊弄糊弄他们
不知道是不是我没看明白,他里面有没有对私自篡改公告的事情做解释啊
为什么不早点说,被发现了先修改岁月史书,看事情败露了才发这么长一篇,一开始就说清楚不好么?这样怎么保证公信力
省流:拳头用心编了 已经原谅我们了
读了几遍尝试理解了一下拳头公告,拳头给的简略网络架构图告诉了我们:游戏显示的ping(方便说明我用ping模块来指代)没有计算客户端的发包延迟(10ms),因为计算ping的方式是记录走完路径“客户端发包-服务端人工延迟-服务端计算-回到客户端网络层”的时间,而客户端的人工延迟发生在刚才这段路径的起点之前,也就是说无论你怎么调,游戏显示的ping一定会比实际ping要小(对应kr那边显示35ms实际比35ms要卡,以及kr不等式22=35),逻辑上是自洽的,但实际情况谁也说不准。
我只是一只懒狗: 有课代表吗
配合你的id食用更佳😝
这么大的公司出这种问题 至少得给RNG一个补偿吧 而不是说什么“我们一定吸取教训,并且不敢保证下次不会”
有无董哥解释下,可信度如何