gitbook/乔新亮的CTO成长复盘/docs/323620.md
2022-09-03 22:05:03 +08:00

10 KiB
Raw Blame History

25 | 异常设计,让错误无处遁形

你好,我是乔新亮。

今天,我想和你聊聊有关异常设计的话题。

如果你认真听了前面的内容,那么对你来说,异常设计应该不是一个新鲜概念了。在高可用设计、监控体系建设部分,我们都聊到了对异常的管理。

那么,为什么今天我们又要单独聊异常设计呢?因为异常管理虽然属于监控体系的一部分,但并不完全依赖于监控体系或高可用设计。在企业的监控体系建设完成前,异常设计一般就可以独立发挥作用,达到快速见效的目的。

异常管理可以提升 IT 团队快速定位问题的能力、降低生产系统异常出现的频次和数量,更重要的是,它是让 IT 团队从面向技术,转为面向产品、面向用户的关键步骤,所以我们这里独立出来讲。

那么,在开始之前,我们有必要明确一下,究竟何为异常?

你可能会想,导致系统不能正常工作的问题就是异常呗。

说得对,但不全对。有些异常,可能当下未必会对生产环境产生影响,但不代表未来也不会;有些异常,可能在流量压力小时未必会出问题,但不代表流量压力大时也不会。

就像在平时,每位同学都会打印 Log有 Warning有 Error。大部分同学关注 Error而不关注 Warning ,甚至有时 Error 也是选择性忽略的。反正打印这些,也不一定会导致线上服务受影响,看看就得了。

但很可能恰恰就是这些被忽视掉的 Error 和 Warning最终导致了严重故障的出现。

所以,所谓异常,指的就是那些让产品无法履行当初承诺用户的契约的问题。

下面,我们通过几个具体的例子来理解一下。

那些被忽视掉的异常

早些年经常网购的同学可能听说过电商界的两个绰号“二手X”、“无货X”。

商品缺货、出现品质或质量问题,一直以来就是电商界的两大“顽疾”。但严格地说,这些都是因仓储系统、订单系统、质量监测系统不够完善,而导致在业务运营层级发生的概率性问题,并非研发同学心目中的“恶性故障”。

但随着用户规模的增大,原本“不值一提”的低概率问题就会被无限放大。举个例子,一家电商平台缺货的概率可能只有 2%,也就是说,配货成功率高达 98%,看起来没啥问题。但当平台用户数量达到一百万时,就会有多达两万人受到缺货问题的困扰。这两万人中,可能只有 30% 的用户有在社交平台发帖的习惯。可即便如此,也会有 6000 人出现在各大社交平台上,发帖吐槽该电商平台的缺货、质量问题。

“好事不出门,坏事传千里”,于是,“无货 X”、“二手 X”的绰号就出现了企业声誉严重受损用户对企业的信任也极大降低企业需要付出更大的努力来赢回用户。

所以,许多你不太关注的异常,最终会在产品层面对用户体验产生恶性影响。一般情况下,产品经理对这类问题的感知更敏锐,但职能型研发组织中的产品经理往往不参与代码编写,一般也不会深度参与开发过程;对于程序员来说,通常也不会主动和产品经理沟通类似问题。

于是,这类问题往往会顺利通过开发、测试,最终进入生产环境。在没有异常设计的情况下,让用户买单。那些用户经历的坏体验,对于开发人员来说,可能只是一个简单的错误提示而已。

当然,这是业务和产品层面的异常。对于很多普通技术人来说,对于底层技术层面的异常,可能更为熟悉。

我曾听一位做 C++ 服务器开发的同学,讲过他们企业发生的趣事。他们经常会处理许多到不同 CDN 节点的高频下载请求,但会有一部分下载超时或耗时增加的异常出现。

他们当时的做法是,当下载耗时超过 200ms 时,在 Log 中打印 Warning ;当下载因超时而失败时,设置定时重试,并在 Log 中打印 Error 。

我好奇地问,然后呢?

他回答,然后就没什么啦,重试一般都能成功。

我继续问,如果一直不成功呢?

他挠挠头,那可能就会导致业务出问题了,研发就得起床查 Log 了。

我又问,如果重试可以成功,但当并发压力增大时,来不及多次重试呢?

他尴尬地笑了下,没说话。

你看,往往我们在做所谓的“异常设计”时,并没有实现给用户的契约。对于电商平台而言,没有实现“成功下单 = 成功配送”的契约;对于那位做 C++ 服务器开发的同学来说,没有实现给其他系统模块的“准时下载”的契约。

大家通常认为,当下的异常没有导致生产环境出现严重问题,所以以后也不会出问题,但实际情况往往不是这样。

在我看来,没有兑现契约,即为异常,就应该控制起来。

那么,到底怎么做好异常设计呢?我们大致可以分为三部分来理解,分别是认知、方案和治理。

对于异常设计的认知、方案和治理

首先,对于异常设计,有五点认知一定要明确,分别是:

  1. 异常一定要消灭:有异常,基本就意味着系统存在风险,一定要消灭异常;
  2. 异常一定要管理:消灭异常是个长期工程,短期要通过管理行为来进行控制;
  3. 对异常的处理水平,会极大影响产品的用户体验:用户规模越大,异常的影响往往越大;
  4. 每个异常都要有具体的负责人:没有和具体的负责人一一对应,往往就意味着管理流于形式;
  5. 与终端用户相关的异常,要以最高优先级处理:即便是 IT 研发,也要以用户为中心。

有了对异常的正确认知后,我们就需要在体系上对异常进行管理。

前面,在高可用设计部分,我曾经分享了“交易体系”和“协同体系”的设计差别。简单来说,交易体系负责处理相对稳定的业务流程,协同体系则是当异常出现时,需要接入的流程。比如客户要订 500 斤白菜,由交易体系来完成,库存满足、正常履行;库存不足时,则需要协同体系完成剩余流程。

但很多同学只做交易体系,不做协同体系,只抛出异常,而不处理异常,因此常常会引领用户走上“断头路”。在某些情况下,用户无路可走,只能找客服投诉。

认知到位后,下面我们一起来看如何落实异常设计。异常设计一般包含异常注册、异常事件触发、异常协作流程以及异常统计。

要管理好异常,我们首先要完成对异常的注册,注册内容大概分为以下几项:

  1. 异常的 ID 和名字;
  2. 对异常的描述;
  3. 异常出现的代码位置;
  4. 负责此异常的研发、测试和产品人员;
  5. 异常发生时的代码版本;
  6. 当时使用的异常处理程序。

同时,企业也要建设异常中心,各个系统都要在异常中心注册异常,一旦运行阶段出现异常,就要抛出异常事件,触发异常处理的协同流程。

当然,很多企业在还没有很好地管理异常时,就已经建设了大量的系统,因此很难再做异常设计。但很多异常都被记录在了日志里,因此研发同学可以通过收集日志中的异常,继而进行归类处理,再通过异常治理完成异常的注册,这样就间接达到了目标。

异常注册、收集后要做什么呢?当然是交由相关负责人进行处理了,这时我们就进入了异常的治理流程。不是所有的异常都要从 Log 中消失,但对于保留下的异常,一定提交管理层进行审批,说明保留原因;理由不够充分的,需要按排期规划并解决。

比如到 CDN 节点的下载行为有一定概率会失败,我们就要调查究竟是服务商提供的节点有问题,还是系统程序在编写方面有问题,又或者是相关机房的网络情况不好。总之,问题一定要明确并解决掉。

管理层也要关注异常的处理情况,包括:

  1. 异常的数量;
  2. 异常的发生频次;
  3. 系统内异常数量的增速或降速;

……

在季度末、年末,我们会对管理层进行绩效考核,并将异常管理情况纳入考核体系,以此实现异常治理的闭环。

你可能会想,写个代码可真难啊,越来越麻烦了。不要怕麻烦,要关注投入产出比。做好异常设计,我们既可以做到高可用、高可靠问题的防微杜渐,还可以帮助研发和测试人员快速定位 Bug。最重要的是在企业层面我们可以实现用户体验驱动内部经营完善的经营逻辑。对于一个技术人来说,这无疑是能帮助你上台阶、再成长的。

在苏宁的时候,我主导研发了“神鉴”系统,目标就是为了做好企业的异常管理。在彩食鲜,我们也在不断完善异常管理,虽然时间不长,但相关工作已经卓有成效。前几天,相关人员还汇报道,我们科技中心所有产品的异常码都已经被统一管理起来,相关异常编码、响应信息都会被实时收集、归类,保证可视化、可统计。

你看,当我们能把繁杂的技术细节,纳入体系化的管理流程里时,还有什么样的困难我们克服不了呢?

当你用这种思路去管理异常时,就可以对一家企业有更深入、更近距离的了解。只要仔细观察一家企业是如何对待异常的,就可以判断这家企业的精细化运营和管理水平。

结语

今天,我们聊了聊与异常设计相关的话题,最终的目的,是让企业的潜在产品和研发问题,全部暴露出来,达成最好的产品体验。

但在落地异常设计时,也一定不要着急。要知道,异常,是会和我们长期共存的,对异常的处理和记录,也会逐渐成为企业数字资产的一部分。

对于直接影响用户体验的问题,要有契约精神,快速迭代;对于企业宏观角度的异常治理,要坚持长期主义,不断优化。

此外,企业的一个核心竞争力就是持续进化的能力。因此,在保持进化的过程中,企业发生的任何问题,都要纳入到异常管理流程中,将异常管理数据化、产品化、系统化,通过持续的治理和数据分析,让企业不断进化,最终建立竞争优势。

相信你一定能将异常管理做得越来越好,让一切错误无所遁形。

我们下一讲再见!