你如何衡量服务质量?

[原文发表地址] How do you measure quality of a service?

[原文发表时间] 2013-10-14

自从几年前我们开始走上在线开发的道路后,我已经了解了很多。在众多我已经了解的事情里,其一是衡量服务的健康状况。我不妄想对于问题只有唯一的解决方法,所以我很高兴借鉴任何人的不同意见。

这篇文章的目的,在于我将 “服务质量” 定义为服务的可用性和响应的程度。

问题

解决这种问题的“传统方法”被称作“合成事务处理”。在此方法中你创建一个“测试代理”每隔N分钟就发送一些请求到你的服务器,一遍一遍的重复这个操作,直到失败的响应都指向一个问题并且时间窗口被标记为“失败”。然后你计算失败的时间间隔数目并在随后的窗口中除以间隔的总数,例如,让我们将30天定为你的可用性度量。

那么这样做有什么问题呢?我先讲一个故事。。。

当我们第一次推出团队资源管理器时,我们有许多关于SQL Azure的问题。我们是第一次正式在SQL Azure上开发高规模,互动式的服务。在过程中,发现了很多问题(现在已经好了很多,如果你关注这个问题)。但是,在我们推出服务的三到四个月后,我正在雷德蒙德与SQL Azure团队的许多领导者一起就怎样解决使我们头疼的SQL Azure问题进行讨论,我需要了解他们快速解决问题的方案。

当我在他们的地板上通过中央走廊的的时候,我注意到他们有一个服务仪表盘正在滚动显示一组live状态服务的数据。顺便说一句,这是一个很普遍的方法(我们也用过)。它是一种很好的方法来给团队强调在服务业务中“live-site”是最重要的事情。我停了几分钟只是看着滚动屏幕上显示的他们的服务。所有的服务都是绿色的。事实上,看着仪表盘你根本不知道有任何的问题——可用性是好的,性能是好的等等。但作为服务的一个用户,我可以向你保证实际上没有任何的性能是绿色的。我很失望因为我参加了一个有着有趣开始的会议。

第二次,是在每个人说“布莱恩说,SQL Azure 糟透了”之前。我说的是在两年前,对我们来说它还有些非常重要的可靠性问题 。虽然现在不是很完美,但是它工作很稳定,而且说实话我不确定没有它我们是否可以更轻松的做我们的服务。它提供的高规摸弹性数据库是真正梦幻般的。

那为什么会出现这种情况呢?为什么运行服务的人在健康服务方面和使用服务的人有不同的看法?好吧,这有很多答案,但是其中一些取决于你如何衡量和评估服务的健康状况。

经常测量一项服务的健康状况并不能反映用户实际上拥有的经验。我以上所描述的“传统”模型可以说明这个理论。当你运行综合事务时,你通常需要运行他们的服务端点的某个子集,针对一些数据的子集。此外,虽然很容易行使“读”的路径,但是“写”的路径却很棘手,因为你通常不想更改数据。为了解决这个问题,在TFService的早期版本中,我们设置了一些相似的集成事务处理记录,例如能够登录,请求几个web页面,阅读某些工作项等等。这一切都发生在我们服务提供团队创建的测试帐号中(因为我们显然不能和用户帐号混在一起)。从理论上讲任何一位客户都可以关闭我们的系统而我们的集成事务处理仍能正常工作。

依我的愚见这是这种方法的根本问题。你的集成事务处理仅仅只运行小的数据子集(尤其在一个独立的多用户系统)和小的端点子集,遗留了很多会错过客户实际上拥有的经验的途径。

我见过的另一个错误是总是在聚集视图中评价服务。你可能会说我的请求有99%是成功的并且你认为这个数据是ok的。但是如果所有的错误都集中在一小部分客户上,他们会放弃你。然后会是下一组等等。所以你不能让你的眼睛太模糊。你要了解每个客户发生了什么。

一个解决方案

好吧,对于这个问题的讨论足够了,让我们开启讨论解决方案的旅程。

我从开始就学会了的一个大的经验就是我希望我们最主要的可用性测量是基于真实的客户经验而不是综合事务(我们仍在使用综合事务,而且以后会更多)。幸运的是,多年来,TFS拥有了我们称为“活动日志记录”的功能。它记录了任何发送给系统的请求,谁创建了它,什么时候接收的,它用了多长时间,它是否成功等等。这对于理解和诊断TFS的问题是非常有价值的。

我学到的另一个经验是 “可用性”衡量,如果你想要的是一份有意义的同时包含可靠性和性能的用户经验。 只是统计失败的请求数,这会留下一个巨大的差距。如果你的用户必须要等待很长的时间,系统在一点响应也没有的时候只会是不可用状态。

最后,任何可用性检测应该反映总体系统的健康状况而不仅仅是给定组件 健康 状况。你也许会感觉一个组件运行良好,但是如果用户需要同时和3个组件互动来做某些事情,只要它们中的一个有问题就会导致用户操作失败。

我们的第一次可用性度量是统计在可用性日志中的请求数。公式是可用性=(总请求数-失败的请求数-响应慢的请求数)/总请求数。在很长一段时间里,这个公式对我们很有用。它很好的反映了我们工作中的各种不稳定情况。它基于真正的用户经验并且同时包含了可靠性和性能。此外我们也对外进行综合事务的监督,顺便说一句,这不是我们首要的可用性度量。

在过去的6个月左右的时间里,我们发现从我们相信实际的服务经验的重要性开始这项措施日益分歧。它被规划成一个比现实更乐观的画面。为什么呢?有很多原因。我认为的主要现象是“更改行为”。如果你获取到一个失败的请求,因为各种原因,你可能不想再发送其他的请求。例如:如果你尝试去开始一个build并且它失败了,将导致所有它生成的请求永远都不会发生也没有机会失败。其结果是,如果用户实际上已经能够取得进展、,你可能会低估失败的请求总数。当然,如果系统不能工作,你的用户不会仅仅靠墙坐下敲着脑袋,他们会一起去吃午饭。在这个例子中,如果没有人使用系统,可能性就是100%(我们会,好吧,实际上就是未定义的分母是0,你明白了吧)

我们已经花费了过去的几个月时间在一个新的可用性模型上。我们尝试了几十次并且模拟了我们所有的数据来检测我们是否恰当的反应了“真正的用户体验”。在最后,都不重要了。

数据仍然衡量了在活动日志中代表的真实用户请求的成功与失败情况。但是计算过程是很不一样的。我们试图增加的一个约束是我们希望它既可以适用于个人用户去衡量自己的经验也可以适用于所有的用户的聚合。当我们进入需要为SLA违规行为提供补偿的业务时,这最终是很有价值的。

首先,像传统的监测,我们已经介绍了每一次失败的“时间罚款”。也就是说,如果我们得到一个失败就意味着我们标记整体时间间隔为失败。这是为了对付我在上面描述的“修改行为”的现象。它把分子从请求数改变为一个时间段。我们同样需要把分母改变为一个时间段来使这个公式成立。我们原本只是用客户或用户乘以在一个月中的时间间隔,但是那确实影响可用性曲线。相反,我们期望分母反映实际尝试使用服务的人的数量以及他们尝试持续的时间。要做到这一点,我们定义了一个汇总期。任何在汇总期使用服务的人都会被统计为分母的一部分。所以,让我们看看公式。

用英语描述,过程是这样的:

对于每一个在5分钟汇总期内使用服务的用户,统计他们每分钟内经历的失败数(失败的请求或者速度慢的请求)。把在1分钟内所有使用服务用户的故障数加起来。用5分钟汇总期内使用服务的客户数乘以5分钟后的值来减去它。这样你就获得了在5分钟汇总期内的“成功客户时间”数。除以总客户时间(在5分钟汇总期内使用服务的客户数乘以5分钟),之后给予你一个客户成功率a%。在窗口中求所有的5分钟汇总期的平均数(在24小时里有288次)来得到可用性a%。

我们仍然在调整1分钟间隔,5分钟汇总期,10秒perf阈值的值。

在我们试过的所有模型中,这个模型提供了一个合理直观的,恰当反映真实用户问题(没有激进)的结果,并且更贴近我们认为的客户实际看到的经验。它基于真实的客户体验而不是人工合成,它会捕获系统中的任何用户体验的每一个单一问题。为了形象化展示区别,请看下图。橙色线是旧的可用性模型。蓝色线是新模型的结果。你所看到的是一个24小时可用性数值图。当我们把它变成一个30天的SLA运算平均值,它会减弱的稍多一点。

image

有一句谚语:“谎言,该死的谎言和数据统计”。我可以手工制作一个可以满足我任何需求的可用性模型。我可以让它看起来很好或很坏。当然,那些都不是目的。你想要的是一个可以告诉你你的用户体验的可用性数据。当你的用户不满意的时候你期望它是坏的。当你的用户满意的时候,你期望它是好的。

这是所有你需要的吗?

总的来说,我发现除了一些缺失外这个模型工作的很好。问题是无论你在哪里测量,总不能避免会有失败。在我们的案例中,当请求到达我们的服务时,活动日志会被收集。在IIS传输时,在云网络中时,在云负载平衡时,在ISP中时,等等,它都可能会失败。在这里我们会人工汇总事务,因为你主要只是测试一个请求是否可以到达你的系统。我们利用我们的全球服务监控服务将终端放置在世界各地并每隔几分钟进行一次事务汇总。对于如何将这些数据融入到我们的可用性模型中,我们 有些想法,但是在几个月内可能不会这样做(此刻这不是我们最主要的问题)。

当我刚开始进入这个领域时,云业务负责人告诉我——在外面的监控(什么GSM,主题演讲,Gomez等等)仅仅衡量了互联网和“生产测试中”的可用性。——在你自己的数据中心中进行测试,衡量的是你自己的应用程序的健康状况。我认为这是很有见地的。我认为你仍然需要去做但更重要的是要想想它在你的整体健康评估战略中所扮演的角色。

关于SLA的一个字

我不能遗漏SLA(服务水平协议),即使这个可笑的长帖子没有一个字是关于它的。SLA通常定义客户可以对你的服务所期望的最低水平。我见过这种现象发生在团队中,当团队定义了SLA后,那定义变成了目标。如果我们在SLA中承诺99.9%的可用性,那么目标就变成了99.9%的可用性。我怀疑我的团队和其他人已经很多次听到我抱怨这种情况了。SLA不是目标!SLA是你不得不把钱还给客户前你要达到的最低标准。 目标是100%的可用性(或之类的)。

当然,所有这些都是折衷方案。为了获取最后0.0001%的可用性你需要做多少事情以及相同时间内你可以提供多少很棒的新功能来代替。所以,我从来不会要求我的团队做任何事都不能有一点失败。但是我们会调查每一次失败,我们学习并且了解我们能做些什么来防止它,评估成本效益,了解问题以及解决方案。眼下,我努力推动我们定期地朝着99.99%可用性的目标前进(就是期望在一个月中停机时间少于4.32分钟)。

对不起写了这么长。希望它至少对某些人是有用的 。一如往常,欢迎任何评论。

Brian