分类目录归档:架构和远方

思考:如何让研发的价值更大

当你成为一个技术团队的管理者时,就会经常会被老板问到,研发的价值在哪里?如何让研发的价值更大?现在的研发团队和行业内相比效率/能力/水平怎么样?如此种种……

每个公司每个技术团队的管理者都有自己的逻辑来回答这个问题,因为这是带团队的核心逻辑之一,且各有缘法。

今天这篇文章不是想准确的回答这个问题,也不是标准答案,只是这些问题最近引发的一些个人思考。

先抛两个公式:

公式一:研发的价值 = (业务价值 + 技术价值) – 非正常成本 – 正常成本

公式二:研发的价值 = 单位有效时间内产出的价值 × 有效时间 – 非正常成本 – 正常成本

这是简化的研发的价值模型,可以作为理解研发价值创造的基础框架。实际应用中可能还需要进一步的细化和调整,因为价值的计算可能远比这两个公式复杂。

总体来看,让价值更大在于攻守,如何攻,如何守,攻就是提高产出价值,守就是减少成本。

在攻的方面,提高产出价值包括提高业务价值和技术价值。我们都知道业务需求是做不完的,如何在做不完的业务需求里面产出更大的价值, 关键点在于业务需求本身的价值和业务价值生效的时间,将具有更大价值的业务需求更快的上线是提高研发侧业务价值的主体逻辑。当然,需求上线后可能还有 bug 之类的,这个我们作为守的那部分来聊。

提高业务价值

提高业务价值的主体逻辑包括两层意思,一个是更大价值的业务需求,另一个是更快的上线。

更大价值的业务需求我理解为做重要的事情,实际上是我们对于事项的一个优先级排序。对于重要的事情分两个阶段,一个是确定事项前的判断,一个是事项确定后的判断,确定前的判断有以下要点:

  • 战略和期望:这是一个前期非常重要的判断项,公司层面的战略、技术长期规划,老板对这个组织的期望等等
  • 业务影响和目标价值:直白的说,看这些事项对业务目标的达成情况的影响,对收入增长的影响,对于 NPS 这些的影响等等
  • 第三方约束和风险:比如已经签了合同的,有截止时间要求的,比如一些严格的技术风险,或者稳定性的问题等等

基于以上这些我们有了一个对事情的判断,但是当这些事情过滤后对于一个管理者来说,还需要做的一个重要性的判断是资源。

资源是最后一个项,是一个相对后期的项,看我们在人力、时间,财务资源上投入多少,这个是过程态中我们要持续看的,根据这些来看我们个人和团队的精力如何分配等。资源需求较大的事项,即使重要性较高,也可能因为资源的限制而需要降低优先级。

在明确了事项的优先级后,下一步就是更快的上线了,更快的上线从研发管理的角度可以分为三个层面,研发流程、工程系统、团队协作和沟通。

  1. 研发流程

    • 精简流程:优化开发到上线的流程,减少不必要的步骤,以加快从需求到部署的时间。可以有一个系统来看每个流程阶段的时间花费,如果没有系统用表格顶一下也行。具体落地指标可以看平均需求交付周期、每流程交付时间等
    • 敏捷实践:采用敏捷方法论,如 Scrum 或 Kanban,以小批量、快速迭代的方式推进项目。在实际落地过程中可以以需求吞吐量、平均需求交付周期、每需求人力成本等。
  2. 工程系统

    • 系统工程化建设:投资于自动化测试、持续集成(CI)、持续部署(CD)等工程系统,以提高开发和部署效率。
    • 技术架构优化:根据业务需求,对技术架构进行持续优化,确保其支持快速增长和变化,并降低长期维护成本。
  3. 团队协作和沟通

    • 跨部门协作:促进开发、运维、产品和其他相关部门之间的沟通,确保需求的快速流转和问题的及时解决。
    • 沟通机制:建立高效的沟通机制,包括定期会议、即时通讯工具和项目管理软件,确保信息流通畅通。
    • 团队授权:赋予团队更大的决策权,使得团队能够快速作出决策,而不必每一项都上报等待批准。

以上是业务价值,将具有更大价值的业务需求更快的上线是核心逻辑。

提高技术价值

对于技术价值而言,逻辑略有不同,技术价值在将更大价值的技术更快的上线的基础上, 需要坚定不移的持续投入和有规划的稳步建设

持续投入是指在资源方面,特别是人力资源方面,需要在业务需求紧张的情况下保障技术需求的投入资源占比。

有规划的稳定建设是指在保障系统稳定的前提下,有规划的对技术架构进行优化,明确技术发展路线图,按照既定的规划逐步实施技术改造和优化,确保每一步都有明确的目标和时间表。

提高有效时间内的价值

从公式二:单位有效时间内产出的价值 × 有效时间 来看,要提高研发价值,需要提高单位有效时间内产出的价值以及提升有效时间。那么如何提高单位有效时间内产出的价值?

一个是从业务层面,将具有更大价值的业务需求更快的上线,另一个从人的层面,提高单兵能力,因为研发最终是要落在人身上,强化单兵能力,对于提升整个团队的有效时间内的产出有极大地促进作用,单兵能力的高低能决定团队总体效能的高低。

至于提升有效时间,从研发管理角度来看一个是以机制形式保障研发的开发投入时间,如研发静默时间,在静默时间不允许插入非写代码相关的事项;

另一方面是以目标为导向,推动团队集中精力专注于某个目标的达成,如小黑屋之类的,当然,其本质上是延长工作时间,也就在一定程度上提升了有效时间,此法慎用,除非文化本来如此,能留下来的是能接受这种文化的人。

以上是攻的角度,也就是提高产出价值来思考,从守的角度来看,更多提就是减少成本,这里主要是减少非正常成本。

减少非正常成本

非正常成本是指在生产和运营过程中由于管理不善、技术失败、人为疏忽或外部因素导致的超出正常开支的成本。这些成本通常不是生产或提供服务的必需开支,而是由于各种非计划事件造成的损失,可以以某种方式减少或规避。

这里的非正常成本我的理解包括以下的部分:

1. 项目延期和需求变更

项目延期和需求变更会导致增加额外的人力成本,延迟了需求的上线时间,可能导致业务损失或风险发生。我们一般可以通过更精细的项目管理来减少延期,通过正式的变更控制流程,评估变更的必要性和影响,以控制变更带来的成本。

2. 技术难题

当在项目过程中遇到了预料之外的技术挑战和难题,可能会导致项目停滞,以至研发团队无法按时完成项目,需要额外的研发投入或影响产品需求计划等。

我们一般在项目开始前对技术难题进行充分调研和风险评估,如果是在项目中遇到了,快速协调资源解决,甚至是请外部的专家来解决,从内部来看,提升现有团队人才梯队,提升团队成员能力,让成为技术难题的项越来越少是更优的解决方案。

3. 产品缺陷

产品缺陷我们通常称之为线上 BUG,当一个线上 BUG 出现后就会有一个流程串起一批人来解决,这个成本比在更前置的开发阶段或测试阶段发现并解决的成本更高,甚至会影响到用户的使用和口碑。

我们一般是通过代码审核、自动化测试、生死用例、showcase 等各种流程和机制来保障和提升产品的质量,同时对于已经出现的问题,使用缺陷管理系统,确保所有缺陷被记录、跟踪并及时处理。

4. 过度设计

过度设计是指在开发过程中投入的工作远超过解决问题所需的程度,这通常体现在过于复杂的系统设计、不必要的功能,或过早优化的代码上。涉及到开发、维护和产品质量三方面,这种过度设计会导致更多的开发和测试时间,更复杂的维护工作,以及可能降低的产品质量。

在设计时尽量遵循  KISS(Keep It Simple, Stupid) 原则 ,避免不必要的复杂性。

5. 历史债务

技术债务是指由于短期内的快速开发和决策,而在长期内需要支付的额外工作。例如,为了赶项目进度,团队可能会选择快速但不完美的解决方案,而不是花费更多时间来寻找更好的解决方案。

为了解决技术债务,可能需要进行代码重构或重新设计系统,这将带来额外的开发和测试时间。此外,技术债务可能会降低开发团队的生产力,例如,如果代码质量低,团队可能需要花费更多的时间来理解代码、修复错误和添加新功能。

我们一般是要将历史债务管理起来,识别和记录技术债务,并制定计划逐步解决,同时在新项目中避免产生新的技术债务。

6. 线上故障

线上事故对于任何技术团队来说都是一种非常严重的非正常成本

这类事故可能会对用户产生直接的影响,包括用户体验降低、数据丢失、服务中断等。这不仅可能导致用户对产品或服务的信心降低,甚至可能导致用户流失。此外,严重的时候,线上事故还会导致公司的资产损失。

为此,我们需要建立全面的监控系统,及时发现并响应线上故障,同时制定灾备计划和故障恢复策略,以减少故障影响,并对每次故障进行事后分析,总结教训并采取预防措施避免未来的重复。

在我们的研发过程中,持续的减少以上的非正常成本是提升整体研发价值的守的逻辑。

除此之外,我们还需要考虑整体系统的复杂度,用持续优化对抗世界的不确定性。

康康说:老板要的无非是「人少活好效率高」

换句话说是成本低质量高产出多,而质量高也是为了成本低,只不过和人少的成本相比是不一样的成本。

老板看的还是 ROI

对于系统复杂度的认知:从滴滴超大型线上故障想到的

在当今时代,互联网已成为我们生活中不可或缺的一部分,涉及到日常的方方面面。无论是打车、购物还是社交,我们都依赖于各种应用程序。但是,这些服务一旦出现中断,就可能引起严重的后果。

2023 年 11 月份,我们见证了两次重大的网络服务故障:11 月 12 日下午,阿里云服务出现异常,导致依赖其服务的多个厂商及其产品功能受损,包括其自身的产品钉钉。紧接着,11 月 27 日晚,滴滴打车应用程序出现故障,直到 28 日中午才逐渐恢复正常。这次滴滴的服务中断超过了 12 个小时,引起了用户和司机的混乱和不便。

就在昨天,12 月 1 日上午,上海医保系统无法进行结算,网友形容「看病一分钟,排队两小时」,凸显了网络服务依赖的脆弱性。

特别一点说,滴滴出行在 2023 年 11 月 27 日发生的故障,使我们不得不重新思考我们对系统复杂度的认知。从滴滴的恢复过程中可以看出,系统经历了部分恢复、再次出现问题,数据混乱等现象。整个系统看似处于混乱之中,但在多方努力介入处理后,逐渐恢复稳定并重新运作。这个过程好比一个受伤的系统在逐步疗愈。

公众的反应也多种多样,有人归咎于滴滴的「降本增效」策略,有人认为是管理层的失误,还有人指责技术升级不当。但如果把滴滴看作一个整体的系统,它无疑是高度复杂的,由人员、组织结构和各种在线系统组成。这个系统的复杂性在平时可能被我们低估,因为每个人通常只关注自己负责的那部分工作。

要理解一个系统的系统复杂度,可以从四个维度来考察:组分复杂度、结构复杂度、功能复杂度和描述复杂度。

组分复杂性

组分复杂性是指一个系统中各个部分(或称为「组分」)的多样性、数量以及它们之间的交互关系所带来的复杂性。 这种复杂性主要体现在以下几个方面:

  • 1. 构成复杂性:也就是系统由多少个不同的部分组成,这些部分又是如何相互关联和影响的。滴滴出行的系统由订单处理、司机分配、定位导航、支付处理、用户反馈等多个子系统组成。这些子系统都有自己的运行逻辑和规则,而且它们之间还需要相互配合和协调。这些系统的交互和协调就构成了滴滴的构成复杂性。
  • 2. 分类复杂性:指的是系统内部的各个部分有多种多样,它们分布的规律性、差异性以及由于各个部分的不同性质带来的复杂性。如滴滴的用户包括乘客和司机,他们的需求和行为都各不相同。比如乘客可能有急需用车的,也有提前预约的;司机可能有全职的,也有兼职的。而滴滴系统需要根据这些不同的需求和行为来做出响应,如何处理这些不同的分类就构成了滴滴的分类复杂性。
  • 3. 规模复杂性:这是指系统内部包含的部分的数量和种类的多少。数量越大,种类越多,系统的复杂性就越高。滴滴的用户数量非常庞大,每天需要处理的订单数量也是海量。这就要求滴滴的系统必须能够在短时间内处理大量的信息并做出决策,比如如何快速匹配乘客和司机,如何计算最佳路线等。同时,滴滴还提供了多种服务类型,如快车、专车、顺风车等,每种服务类型又有自己的规则和特性。如何管理这些大规模的数据和多样化的服务就构成了滴滴的规模复杂性。

结构复杂性

结构复杂性关注系统的整体结构以及各个部分之间的排列、组织和层次关系的复杂性。这种复杂性主要体现在以下三个方面:

  1. 组织复杂性:这是指一个系统内部各个部分之间的组织方式有多么复杂。例如,一个公司的组织架构,有多少部门,这些部门之间是如何分工合作的,就构成了组织的复杂性。又或者像滴滴系统是由多个子系统组成的,包括订单处理系统、定位系统、支付系统、评价系统等等。这些子系统需要协同工作,以提供顺畅的出行服务。

  2. 层次复杂性:这是指一个系统可以被划分为多少个层次或等级,以及这些层次之间的关系也会非常复杂。如滴滴的系统,从上层的应用架构,到底层的服务架构,再到更下面的物理架构层,每个层次都有其内在的复杂性,而层与层之间的交互和协作也会引入额外的层次复杂性。以基础设施为例,这些基础设施的任何故障都可能导致滴滴的线上故障。

  3. 过程复杂性:这是指一个系统内部的运行和交互过程有多么复杂。滴滴的运行涉及到许多复杂的过程,如订单匹配、路线计算、费用结算等。这些过程中都涉及到了大量的计算和决策,而且经常需要实时地调整和优化。同时,滴滴的运行还受到外部环境的影响,比如交通状况的变化、法规政策的变更、天气变化等,这些都会影响到滴滴的运行过程,使其变得更加复杂。

结构复杂性就是由于一个系统内部各个部分之间的关系错综复杂,使得系统的行为和性质变得难以预测和理解。

功能复杂性

功能复杂性实际上描述了一个系统在不同情况下处理问题的难易程度,包括预测、保持和调控三个方面。

  1. 预测复杂性:就像预测天气一样,系统未来的状态可能会因为很多不确定的因素而变得难以预测。如滴滴系统在未来某一时刻的状态,如,预测在特定时间和地点的需求量可能会因为许多因素(天气、节假日,甚至是附近有没有大型活动等)而变得相当复杂。

  2. 保持复杂性:保持系统稳定正常的运转也需要对各种要素进行精细的平衡,如遇到大流量的冲击,安全攻击,甚至爬虫或者某些 BUG,想象你在平衡一只装满水的杯子,这需要非常多的复杂性和一些精细的调整。

  3. 调控复杂性:如果你想改变系统的某些功能,就像在一个复杂的机器中更换部件一样,像增加某些功能,对于现有复杂度的影响,以及删减某些功能或子系统,对系统中的组分的影响,结构的情况等等。

在我们面对一个复杂系统时,对系统进行预测、保持和调控都是在钢丝上跳舞。

描述复杂性

简单来说,描述复杂性就是理解和描述一个系统需要多少工作量和信息量的度量。 稍微复杂一点,描述复杂性是从描述系统的状态的工作量、信息量以及存储量角度来定义系统的复杂性。它以数学的复杂性理论和信息论为基础,主要包括以下三个方面:

  1. 计算复杂性:这是指解决一个问题所需要的计算资源,包括时间和空间,也就是我们在编程时常说的时间复杂度和空间复杂度。例如,一个问题如果需要很长的时间或大量的内存来解决,那么我们就说它具有高计算复杂性。

  2. 算法复杂性:这涉及到解决问题的过程中的多样性和随机性。想象你正在解决一个复杂的拼图,需要尝试不同的拼接方法,这就是算法复杂性,描述了解决问题的过程中的步骤和方法有多复杂。

  3. 有效复杂性:如果你要向别人解释一个很复杂的概念,你需要多少话才能解释清楚,这就是有效复杂性,代表了描述一个系统的规律性需要多少信息。

在这些方面中,计算复杂性和算法复杂性主要关注解决问题的过程,而有效复杂性则更多地关注对问题本身的描述。

上面四种复杂性中,组分复杂度和结构复杂度看起来会有一些相似的地方,容易搞混,它们关注的角度和内容有所不同:

  1. 组分复杂性:这是关注系统中各个部分(或组分)的多样性、数量以及它们之间交互关系的复杂性。组分复杂性的关注点在于系统的各个组成部分以及这些部分之间的关联关系。例如,一个城市的交通系统中,公交、地铁、出租车、自行车等多种交通工具以及它们之间的转换和配合,这就构成了交通系统的组分复杂性。

  2. 结构复杂性:这是关注系统的整体结构以及各个部分之间的排列、组织和层次关系的复杂性。结构复杂性的关注点在于系统的整体架构、层次关系以及系统运行的过程。例如,一个公司的组织架构中,不同部门的划分、部门之间的协作关系,以及公司运营、决策的流程,这就构成了公司的结构复杂性。

简单来说,组分复杂性着重于系统的各个部分和它们之间的关系,而结构复杂性则更加关注系统的整体架构和运行过程。在实际应用中,我们往往需要同时考虑这两种复杂性,以全面理解和处理复杂系统。

通过这种四种复杂性我们能较全面的评估我们所面对的系统的复杂度,不低估,也不过度夸大它的复杂性。

对系统复杂度的综合评估揭示了系统的脆弱性和潜在的优化路径,引导我们设计出更为韧性强、可适应性高的系统结构。这种洞察力使我们能够制定针对性的决策和策略,优化资源配置,创造更加流畅的用户体验,并在面对不断变化的需求和潜在危机时,保持服务的连续性与质量。

通过深入理解系统的组分、结构、功能和描述复杂度,我们不仅能够减少业务中断的风险,还能在持续的服务创新中保持竞争优势,实现系统的长期可持续发展。

研发效率提升的秘诀:日志管理的系统化策略

你是否也遇到过线上出问题了,查找日志,发现都是 ERROR 日志?

你是否也遇到过虽然有日志,但是日志实在太多,在茫茫日志中无法有效地定位到问题?

你是否遇到过要去排查前人写的代码产生的 BUG,却还需要把先把相关的代码过一遍,找到相关日志点,再去搜索日志?

你是否遇到过日志越来越多,不同的人都在打,有些日志没有用了,还是在不停的打?

你是否遇到过奇怪类型的日志,甚至相互冲突以至于无法定位问题?

你是否遇到过因为打个日志,导致客户端崩溃?

……

当日志不在大家的视野中,凭着个人的喜好去打,去定位问题,最终整个日志就会变成一个不断膨胀的怪物,变成大家使用起来都感到困扰和无助的混乱池塘。

当日志的生成和使用没有统一的规范和标准,每个人都按照自己的方式和喜好来记录和查找日志,日志的内容和格式就会变得五花八门,导致理解和分析日志的难度大大增加。另外,无效的、重复的、甚至是错误的日志会像野草一样无序地生长,使得日志的数量越来越大,而有效的、有用的日志则可能会被淹没在这个日志的海洋之中。

此时,我们需要建立一套有效的日志管理策略,包括设定清晰的日志记录标准,实施有效的日志标准管理,优化日志存储和清理策略等。只有这样,我们才能把这个日志怪物驯化,使得日志成为我们解决问题的有力工具,而不是一种困扰。

从过往的经历和上面描述的这些问题里面我们洞察了如下的问题点:

  1. 日志规范管理的问题
  2. 日志无序增长的问题
  3. 日志劣化和无人维护的问题
  4. 日志导致的线上问题

那么我们如何有效的去解决这些问题呢?

大概有如下六个步骤:制定标准、系统化实现标准管理、实现统一的日志 SDK 接入、使用统一的日志管理系统、定期复盘标准并落地日志的生命周期管理。具体如下:

  1. 制定标准:日志的标准应包括但不限于如下几个方面:

    • 日志级别:定义不同级别的日志,如 DEBUG、INFO、WARN、ERROR 等,以便于过滤和查找。
    • 日志格式:定义统一的日志格式,包括时间戳、日志级别、日志来源、日志内容、错误堆栈等信息。
    • 日志内容:明确记录哪些信息,如请求信息、业务数据、错误信息等。避免记录敏感信息,如用户密码、身份证号等。
    • 日志保留时间:根据日志的重要性和存储成本,设定不同级别日志的保留时间。
    • 是否废弃:类似于接口的 Deprecated 注解,废弃的接口在定时间内会停止上报,并无法查询。
  2. 系统化实现标准管理:以系统的方式将标准、SDK 下载管理起来,并且和集成的日志系统关联上,主要包括以下三点:

    • 标准管理:实现日志标准的管理和维护,包括日志的级别、字段、格式等。此外,也应当支持标记废弃等生命周期相关的字段,以确保所有人员都能了解到哪些标准不再使用。
    • SDK 下载:提供一个 SDK 的下载功能,允许开发同学根据需要下载适合特定平台或语言的日志 SDK。这种 SDK 应当已经集成了日志标准,以确保开发者在使用 SDK 时能够自动地遵循标准并上报到统一的日志平台。
    • 日志系统跳转:和真正的日志系统(如 ELK)打通。如提供一个默认的跳转链接,可以直接跳转到 ELK 的对应界面,查看满足这些参数的日志。
  3. 实现统一的日志 SDK 接入:提供一个统一的日志 SDK,用于记录和上报日志。这样可以简化开发同学的工作,只需要调用 SDK 提供的接口,就可以按照标准记录日志。而且,SDK 可以处理一些公共的日志任务,如添加时间戳、格式化日志、处理错误堆栈、防止打日志时崩溃等。SDK 应该是跨平台、跨语言的。

  4. 使用统一的日志管理系统:使用一个专门的日志管理系统,来收集、存储、查询和分析日志。这样可以提供一致的日志服务,提高日志的可用性和可维护性。例如,可以使用 ELK(包括 Elasticsearch、Logstash、Kibana)作为日志管理系统。

  5. 定期复盘标准:随着业务和技术的发展,可能需要更新日志标准。因此,需要定期复盘标准,看是否需要改进。定期复盘标准的频率可能会因为具体情况而变化。如果业务和技术环境比较稳定,那么可能每年复盘一次就足够了。如果环境变化比较快,那么可能需要每季度甚至每月复盘一次。

  6. 日志的废弃管理:日志的生命周期管理包括日志的生成、收集、存储、查询、分析和废弃等步骤。其中,废弃管理是一项非常重要的任务,因为它直接关系到日志系统的健康和效率。日志的废弃管理可能包括以下几个方面:

    • 过期删除:设置日志的保留期限,过期的日志将被自动删除。这个期限可能会根据日志的级别和重要性而变化。比如,ERROR 级别的日志可能需要保留一个月,而 DEBUG 级别的日志只需要保留 3 天。
    • 空间限制:设置日志的存储空间限制,当存储空间达到一定的阈值时,最旧的日志将被自动删除,以释放空间。
    • 废弃标识:为废弃的日志添加标识,这样在查询和分析日志时可以忽略这些日志。同时,废弃的日志应当尽快被删除,以节省存储空间。
    • 废弃通知:当一个日志标准被废弃时,需要通知所有相关的人员,以避免他们继续使用这个标准。同时,也需要更新日志 SDK 和管理系统,使它们不再支持这个废弃的标准。

回顾一下,我们制定了一套清晰的日志标准,随后通过系统化的管理方式实施和维护这些标准。借助统一的日志 SDK 和日志管理系统,我们可以提升日志生成和使用的效率。这样,日志便从混乱的信息池转化为强大的问题解决工具,从而提升整体的研发效率