你好,我是乔新亮。
今天,我想和你聊聊有关异常设计的话题。
如果你认真听了前面的内容,那么对你来说,异常设计应该不是一个新鲜概念了。在高可用设计、监控体系建设部分,我们都聊到了对异常的管理。
那么,为什么今天我们又要单独聊异常设计呢?因为异常管理虽然属于监控体系的一部分,但并不完全依赖于监控体系或高可用设计。在企业的监控体系建设完成前,异常设计一般就可以独立发挥作用,达到快速见效的目的。
异常管理可以提升 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++ 服务器开发的同学来说,没有实现给其他系统模块的“准时下载”的契约。
大家通常认为,当下的异常没有导致生产环境出现严重问题,所以以后也不会出问题,但实际情况往往不是这样。
在我看来,没有兑现契约,即为异常,就应该控制起来。
那么,到底怎么做好异常设计呢?我们大致可以分为三部分来理解,分别是认知、方案和治理。
对于异常设计的认知、方案和治理
首先,对于异常设计,有五点认知一定要明确,分别是:
- 异常一定要消灭:有异常,基本就意味着系统存在风险,一定要消灭异常;
- 异常一定要管理:消灭异常是个长期工程,短期要通过管理行为来进行控制;
- 对异常的处理水平,会极大影响产品的用户体验:用户规模越大,异常的影响往往越大;
- 每个异常都要有具体的负责人:没有和具体的负责人一一对应,往往就意味着管理流于形式;
- 与终端用户相关的异常,要以最高优先级处理:即便是 IT 研发,也要以用户为中心。
有了对异常的正确认知后,我们就需要在体系上对异常进行管理。
前面,在高可用设计部分,我曾经分享了“交易体系”和“协同体系”的设计差别。简单来说,交易体系负责处理相对稳定的业务流程,协同体系则是当异常出现时,需要接入的流程。比如客户要订 500 斤白菜,由交易体系来完成,库存满足、正常履行;库存不足时,则需要协同体系完成剩余流程。
但很多同学只做交易体系,不做协同体系,只抛出异常,而不处理异常,因此常常会引领用户走上“断头路”。在某些情况下,用户无路可走,只能找客服投诉。
认知到位后,下面我们一起来看如何落实异常设计。异常设计一般包含异常注册、异常事件触发、异常协作流程以及异常统计。
要管理好异常,我们首先要完成对异常的注册,注册内容大概分为以下几项:
- 异常的 ID 和名字;
- 对异常的描述;
- 异常出现的代码位置;
- 负责此异常的研发、测试和产品人员;
- 异常发生时的代码版本;
- 当时使用的异常处理程序。
同时,企业也要建设异常中心,各个系统都要在异常中心注册异常,一旦运行阶段出现异常,就要抛出异常事件,触发异常处理的协同流程。
当然,很多企业在还没有很好地管理异常时,就已经建设了大量的系统,因此很难再做异常设计。但很多异常都被记录在了日志里,因此研发同学可以通过收集日志中的异常,继而进行归类处理,再通过异常治理完成异常的注册,这样就间接达到了目标。
异常注册、收集后要做什么呢?当然是交由相关负责人进行处理了,这时我们就进入了异常的治理流程。不是所有的异常都要从 Log 中消失,但对于保留下的异常,一定提交管理层进行审批,说明保留原因;理由不够充分的,需要按排期规划并解决。
比如到 CDN 节点的下载行为有一定概率会失败,我们就要调查究竟是服务商提供的节点有问题,还是系统程序在编写方面有问题,又或者是相关机房的网络情况不好。总之,问题一定要明确并解决掉。
管理层也要关注异常的处理情况,包括:
- 异常的数量;
- 异常的发生频次;
- 系统内异常数量的增速或降速;
……
在季度末、年末,我们会对管理层进行绩效考核,并将异常管理情况纳入考核体系,以此实现异常治理的闭环。
你可能会想,写个代码可真难啊,越来越麻烦了。不要怕麻烦,要关注投入产出比。做好异常设计,我们既可以做到高可用、高可靠问题的防微杜渐,还可以帮助研发和测试人员快速定位 Bug。最重要的是,在企业层面,我们可以实现用户体验驱动内部经营完善的经营逻辑。对于一个技术人来说,这无疑是能帮助你上台阶、再成长的。
在苏宁的时候,我主导研发了“神鉴”系统,目标就是为了做好企业的异常管理。在彩食鲜,我们也在不断完善异常管理,虽然时间不长,但相关工作已经卓有成效。前几天,相关人员还汇报道,我们科技中心所有产品的异常码都已经被统一管理起来,相关异常编码、响应信息都会被实时收集、归类,保证可视化、可统计。
你看,当我们能把繁杂的技术细节,纳入体系化的管理流程里时,还有什么样的困难我们克服不了呢?
当你用这种思路去管理异常时,就可以对一家企业有更深入、更近距离的了解。只要仔细观察一家企业是如何对待异常的,就可以判断这家企业的精细化运营和管理水平。
结语
今天,我们聊了聊与异常设计相关的话题,最终的目的,是让企业的潜在产品和研发问题,全部暴露出来,达成最好的产品体验。
但在落地异常设计时,也一定不要着急。要知道,异常,是会和我们长期共存的,对异常的处理和记录,也会逐渐成为企业数字资产的一部分。
对于直接影响用户体验的问题,要有契约精神,快速迭代;对于企业宏观角度的异常治理,要坚持长期主义,不断优化。
此外,企业的一个核心竞争力就是持续进化的能力。因此,在保持进化的过程中,企业发生的任何问题,都要纳入到异常管理流程中,将异常管理数据化、产品化、系统化,通过持续的治理和数据分析,让企业不断进化,最终建立竞争优势。
相信你一定能将异常管理做得越来越好,让一切错误无所遁形。
我们下一讲再见!
精选留言
2020-12-21 05:38:11
乔老师,可以分享下您是怎么做知识储备的?或者可以分享您觉得不错的书籍吗?
2020-12-21 14:37:23
2020-12-22 14:23:47
在试读乔老师第一课“五年上一个台阶”,就把那节课微信转给了十几个同事、甚至不同行业的朋友,也经常跟女朋友一起听、一起讨论。真的是发自内心的认可和分享,认为这一门课可以为在“业务导向型公司”的技术人员解困,找到真正可以努力的方向。
随着听的章节越来越多,也逐渐意识到:技术人员并非只有技术能力维度;以前领导的做法是有道理的,自己在对领导的某些处理上是不正确的,一味的以技术视人、视环境会让自己走进误区、耽误的是自己的成长;作为一个客户端出身的技术人员,不懂的东西实在很多,向往架构、cto的方向走,要补的东西很多,所以最近也在结合其他课程,看看后端各种架构设计;也意识到思想、认知非常重要,同样用一个现有的流行的框架,有思想和没思想的感受是完全不一样的,就是观大象全貌和盲人摸象的区别。
我认为乔老师的课、观点,给了我很多启发和信心,这只是一个开始,感谢您给了我这个开始。
2021-03-18 17:14:22
2021-03-08 08:54:36
2020-12-21 14:00:40
"异常,是导致不能履行契约的所有问题"
请教一个工程层面的问题,写代码时,如果当前已经捕获异常,有两种处理方式
1.在下层处理一下,包装成返回码;
2.直接抛出异常,由出口统一处理
您偏向那种方式?
2020-12-21 12:21:03
2023-07-19 21:08:51
2021-03-07 18:38:42
2021-02-24 10:39:00
有了这样的意识后要把他们坚持落地困难还是挺大的,昨天在部门会议上提到团队目前监控设计还有很多事情要做,生产环境出现问题后直接在生产环境调试解决 Bug,即便回滚也不能完全回滚到未变化前版本,团队 Leader 对此并不在意,并指出"规定不能在生产环境调试 Bug" 太叫针儿。改变不了别人,只能改变自己,努力学习提升认知,即使现在不能实践至少知道什么是对的。
2021-02-20 21:42:48
2021-01-25 22:35:05
2020-12-27 14:52:37
2020-12-22 14:41:53
2020-12-22 09:52:03
2020-12-21 19:40:51
产品经理如果把微观细节设计不好,开发兄弟们100%做不好异常设计开发,反正我以前的经历都是这样过来的。
团队中其他开发兄弟给我最大的压力就是这个异常设计问题,很多弟兄们技术比我好,但在异常出现时用户体验、业务流程如何闭环方面做不好,往往把用户带到了死胡同,用户不知道如何进行下一步操作。
我现在都不愿意管其他研发兄弟们,心里很累。辛亏以前用户每日PV数量不超过6000万,并发量1000左右。
对用户操作的理解,业务流程的理解,技术方面对数据一致性、锁冲突等因素的理解决定着异常设计和处理的水平。
2020-12-21 12:36:27