开发者之路

你好!我叫Alexey Skorobogaty。2015年,我加入Lamoda,担任开发人员。现在,我是电子商务平台的系统架构师,也是CORE团队的技术主管。在本文中,我想分享我在过去5年中获得的真知灼见-外卖格式,包括故事,模因和文学链接。



图片



我很高兴在文章下的评论中进行任何讨论:问题,观点,反驳!



有已知



在Lamoda,我加入了团队,致力于订单处理系统的支持和开发。不清楚,但是非常有趣。



在一个我曾经工作过的小型但雄心勃勃的网络工作室之后,我对一家大公司的认真态度印象深刻。安排好的开发过程似乎是一种完美的机制。对于这样一个复杂而关键的系统,领导者和团队成员进行严格但指导性的代码审查至关重要。对我来说,指向任务飞了,实际上只影响一个或两个文件,而不再。战争的迷雾使大多数代码库和系统行为对我隐瞒了。



大约一个月后,我完成了与对工作系统进行真正更改有关的第一批任务之一。其实质归结为在向客户返还资金时在报告中添加了一个字段。代码审查,单元测试,质量保证工程师测试版本-一切看起来都还不错。由于系统庞大而复杂,因此我们按照规定每周发布两次-星期四,我的任务投入生产。一天中的大部分时间,发布工程师都在忙于构建和推出代码,然后在带有监视图,错误,队列,日志的选项卡之间进行强制性切换-所有可能指示问题的信息。但是一切看起来都很棒。该代码被合并到master分支中并分散处理其他任务。



日志和监视中的静音隐藏了一个可怕的错误:数据库查询返回的行数不正确。退还的总金额比实际退还的金额高出好几倍……但是我们仅在星期一才知道这一点。我仍然记得第二天早上我们乘办公室电梯时,技术主管看着我多么疲惫和可耻。他发现了这个错误,直到凌晨三点才准备发布。我的错误使公司遭受了一些冲击。这是我的第一个严重错误,但远没有最后一个。人们会犯错,而且他们会一直犯错。



外卖#1:业务流程和数据是第一位的。务必密切注意系统使用的数据。进行更改之前,确定要处理的内容。了解进行调整的环境。始终从上级上下文的角度考虑要解决的问题。换句话说,要清楚地了解业务流程中正在发生的事情以及谁是受影响模型的使用者。应用程序的结构可以具有任意数量的抽象层,并且抽象本身的质量也不同,但是,如果模型或业务流程整体被破坏,则绝对没有任何意义。



我继续在同一个团队中工作,积累了经验,六个月后,在团队站立会议上,我抛出了一句话,总的来说,我了解我们的订单处理系统是如何工作的。



我当然是错的



大型系统的复杂性绝对不可低估。美国政治家唐纳德·拉姆斯菲尔德对此表示非常满意:

图片...据我们所知,有著名的;有些事情我们知道,我们知道。我们也知道,存在未知的事物。也就是说,我们知道有些事情我们不知道。但是,还有未知的未知数-我们不知道,我们不知道的那些。如果您看一看我们国家和其他自由国家的历史,通常很难做到最后一类。



要点2:在使用复杂的系统时,重要的是要了解我们对它们的了解,不知道的东西以及它们甚至无法猜测的行为。这不仅涉及工具并遵循“可观察性监控”趋势,而且还涉及设计中的依存关系管理和风险评估。例如,在决定对关键系统使用很酷的趋势数据库之前,我强烈建议您坚持使用此站点boringtechnology.club



一切都被打破



在使用订单处理系统两年后,我可以说我对80%的应用程序充满信心。也就是说,对于系统的每个模块,我都了解其工作原理,并且可以进行更改。我知道特定模型反映了哪些业务流程,它们如何相互联系并相互影响。我与附近团队设计的付款处理系统进行了集成。除了集成之外,还必须摆脱旧代码的遗留问题,因为付款以前是我们系统的一部分-此任务是我对大型模块的最后也是最大的重构。一切都进行得如此顺利,甚至都没有意思。



同时,作为一名开发人员,我内部发生了冲突。老实说,我不明白为什么我们的订单处理系统对我们整个业务的运营至关重要,为什么如此脆弱?相邻的大型系统同样脆弱。从我两年的工作中获得的所有经验来看,似乎只有在执行标准测试用例时,才能期望复杂系统具有某种可靠性。而且,当您尝试进行业务需求的更改时,不幸的开发人员的第一次激烈操作会使事情分崩离析。



考虑到所有这些,我碰到了《一切都碎了》一文,作者在其中写了一个相同的问题,但涉及的范围更大(并且也是相同的,但从不同的角度来看)-软件分解)。每当我从外面发现自己内在的感觉都感到兴奋时,就是那段时间,在阅读了这篇文章之后,我终于感到自己模糊的不满变成了生动而明显的见解:

软件是如此糟糕,因为它是如此复杂。



我们不必在工作中举个例子:仅在那一刻,仅增加了两极,我们就暂时中断了订单的创建。



我们庞大而重要的系统是如此糟糕,因为它们不适合我们的头脑!而且,系统中封闭的所有业务流程都不适合经理和分析师的头脑-通常,没有这样的人会了解它们如何协同工作。



要点3:在设计系统时,考虑其认知负荷很重要。它包括技术解决方案的复杂性以及主题领域的模型和过程。精心设计的系统在主题领域具有较高的认知负担,而技术解决方案则较低。理想情况下,单个系统应具有一个人可以处理的认知负荷。



好的,问题很明显。但是,假设我们有机会重写一个过于复杂,因此很糟糕的系统,并将其简化。您还要注意什么?在控制论中,存在Conant-Ashby定理:



一个好的系统调节器必须具有该系统的模型。良好的调节器



这个定理的含义是,如果我们要控制某个对象,则需要该对象的良好(准确且可理解的)模型。而且,对象越复杂或关于它的信息越少,就很难获得一个好的模型-这会对管理产生负面影响。



我认为很少有人会不同意我们的所有服务都是模型。但是我们要建模什么?注意业务流程,不仅要建模状态,还要建模行为,这一点非常重要。



在2017年底,我搬到了新的CORE团队。然后成立了这个小组,专门负责执行IT策略的任务,以分解整体系统。我们的主要目标是削减庞大但脆弱的订单处理系统(语音处理:然后,武士尚不知道这条路有起点,但没有终点!)。

对我而言,这是一种新体验。具有完全不同的原则和思维方式的团队。做出决定很快,有实验并且有犯错的权利。两者之间取得了完美的平衡:我们尝试并回滚了影响最小的地方,但我们在关键时刻详细规定了每个步骤。



我们编写了一项新服务,可以使用另一种语言从头开始创建订单(作为php开发人员,我们切换到了golang)。我们评估了第一个结果,然后再次重写。重点是简单性和可靠性。他们将数据模型放在中心,并围绕整个体系结构进行构建。结果是可靠和有弹性的服务。我们使用实验机制设法使它投入运行而没有失败。随着时间的流逝,已构建的系统已多次显示其价值。



图片



外卖#4:所有模型都是错误的,但有些是有用的。对状态进行建模不足以构建正确且稳定的系统。有必要查看行为:通信模式,事件流,负责此或该数据的人员。您应该查找数据之间的关系,并注意这些关系的原因。



都是关于dum dum da da dum dum



在我的大学里有一门数学分析课程,由一位副教授和博士学位授课。埃琳娜(Elena Nikolaevna)。她很严格,但很公平。在测试过程中,时不时地会遇到一些问题,为解决这些问题,有必要“略微扭曲”这些讲义-采取独立的步骤来理解材料。顺便说一句,在我第二次通过的期末考试中,我必须表现出思维的灵活性,并凭直觉将问题视为“好”。这是E.N. 她告诉了我们整个课程,十年后我正在使用:

当您不知道该怎么做时,请做您所知道的。



这就是为什么我为认识Matan感到骄傲。因为根据E.N.仅仅了解材料是不够的,但了解它也很重要,以便能够合成新的东西。



要点5:您走得越远,您承担的责任就越大,您必须做出的决策就越多。在某个时刻,绝对的信心作为一个类别消失了,但是随着勇气迈出了一步,平衡的艺术就来了。



有时候,您周围没有合适的人可以消除现有的不确定性。您必须自己评估风险并为自己承担责任。面对不确定性做出决策。



在2018年下半年,我们的团队领导了礼品券项目。最初,我负责处理过程及其周围的开发。后来,到今年年底,整个项目的技术领导权接管了我,并承担了部分团队离职后恢复权力平衡的任务。



开发人员的头脑和世界秩序中存在的规则在接缝处破裂,然后最终崩溃。对一个大型而复杂的项目的责任使我对概念和彩虹的发展世界的理想主义思想落空了。残酷的限制和足够的解决方案世界要求我理解和修订我遵循的所有方法和规则。



图片



外卖#6:冒名顶替综合症。如果我暴露了怎么办?当然,如果什么都不做,它们将暴露出来。如果您做重要的事情,那么一段时间后,您会发现没有人可以揭露您。



发散与收敛



按照我的“开发者之路”的时间顺序,从技术角度来看,应该有一个关于个人政策项目的有趣故事。在这个项目中,我们实现了实时数据处理,并且在运行中迅速改变了系统架构的原理,并转向事件驱动架构。但是关于这一点,我已经有一个来自Highload '19会议的单独报告(以及有关哈布雷的文章)。因此,我宁愿告诉您有关技术而非管理的“重要事项”。



当开发人员成长为高级职位时,应将其理解为“准备承担责任并知道如何自主决策”,接下来的经典步骤是团队领导。团队负责人是主要负责团队的人,即用于人员和发展过程。客户不来找开发人员,他来找团队负责人,也要求团队负责人承担义务。



事实证明,这很矛盾:开发人员一旦成长为能够独立工作的工程师,便会陷入一场名为管理的风暴中。

不,也许对于某人来说,这条道路似乎很舒适,并且从用于计算机系统交互的极其明确的算法和协议到一群人的协调的过渡看起来是合乎逻辑的。但是在我看来,个人简介聊天和团队负责人会议中的大多数对话都围绕着“痛苦”的概念,这并非毫无道理。



团队领导的痛苦是什么?是不是因为工程师负责管理?不,为什么会发生这种情况是可以理解的-我们没有这样的技术管理学院,并且假定IT工程师是超人,他能弄清楚一切,包括诸如管理之类的“简单”事物。



但是我决定走另一条路,选择技术主管的职位作为下一个职业步骤。作为一名架构师,我与开发团队一起工作,现在我听到家伙们一年前对管理人员所说的话:

为什么需求开发如此差?拐杖解决方案!什么两个星期?在这里工作一个月。



但是ehehei,现在解决这个问题是我的任务。但是,一旦将您的思想转化为成本与收益范例,您就会意识到所有这些问题都无法解决-您可以过上无聊的生活!



外卖#7:开幕!经理不处理问题;他们管理混乱。



作为技术主管,我的工作是消除开发团队的不确定性。要求没有解决?拐杖解决方案?架构不提供吗?这些都是系统脆弱和分歧的信号。



假设订单创建服务中的任务设置如下所示:您

需要添加X字段和Y字段。如果X为1



,则要求输出的Y'字段中的值等于Z值。问题在于需求的陈述。这里的错误是,完全不清楚您要实现的系统状态。声明中规定的步骤完全会导致实施和操作过程中的不确定性。

在完成了几项类似的任务之后,订单创建服务将处于相当脆弱的状态-例如,当我们添加几个字段而一切中断的情况将开始发生。



目标:确保系统状态的收敛,任务说明的一致性以及减少不确定性以实现稳定性。



图片



从事代表工作的人们正在不断建立和更新超越领域的模型。这些活动对于Internet系统的弹性至关重要,并且是适应能力的主要来源。高于线,低于线



架构师必须了解社会技术系统的统一性。为了能够协调表示线上方的过程,以便表示线下方的系统满足正确性,稳定性和适应性的约束。



图片



总结#8:恭喜,如果规则停止工作,那么您已经达到当前模型停止工作的边界条件。现在是时候修改您的想法并选择一种新模型,该模型可以满足当前的限制并允许您建立适当的流程和规则。



软是简单的,人是硬的!



不完全是。这就是一本关于建筑的书。感觉就像我走的越远,我越常重复读这本书。



技术概念,算法和标准很明确-您只需要加以理解并始终如一。我并不想减少工程师的工作-如果您不每天构建这样的系统,则分布式系统的算法将非常复杂。但是,在很多情况下,我们在工作过程中面临的主要困难往往是当我们需要了解为什么该服务或该服务需要这种领域的抽象级别时出现的。而且,编写服务的人不在身边这一事实常常使问题更加复杂。



易于实现的算法比数学上准确的算法更为成功。 Paxos在数学上是准确的,但是仅通过对Raft协议的描述(易于实现),开发了共识算法的实际应用。

人们批评Golang语言的局限性。但正是在此之上编写了Docker,Kubernetes和许多其他分布式系统。精心设计的约束系统是成功系统的基础。



如果技术不必考虑人为因素,那么一切都会变得容易得多。但是他们必须这样做。任何涉及多个人的IT建设系统,都必须考虑人为因素。



在这里,技术出现在软件和人员的交汇处,旨在构造混乱并描述复杂的交互。域驱动设计,微服务,敏捷-所有这些都创建了描述交互原理和规则的约束。出现了很清楚如何工作的结构。但是随着此类技术的出现,它并不总是会变得更好。经常出现相反的情况-钱不能买什么



#9:程序可以而且应该很简单。为此,您需要加倍努力以形成工程文化。最终决定服务性能的是她。



图片



阅读清单



书籍



经理的道路:卡米尔·富尼尔(Camille Fournier)-领衔增长与变革的技术领导者指南-链接



优雅的难题:工程管理系统,威尔·拉尔森(Will Larson)-链接



团队拓扑:为快速流动而组织业务和技术团队,Manuel Pais和Matthew Skelton-链接



扶正软件,朱瓦尔·洛-链接



系统思考:入门,Donella草甸-参考



文章



心智模型,街总Fernam -链接



复杂性偏差:为什么我们更喜欢复杂的简单。费尔南街(Fernam Street)-链接



钱不能买到的东西,少错-链接



变得异常以真理为导向,少错-链接



编程规律与现实:我们知道我们认为的吗?-链接



没有子弹项目的本质和软件工程事故-链接



故障排除的 技巧-链接



从易碎软件到反脆弱软件-链接



可以理解的计算机-链接



塔克曼错了!(关于小组) -参考



如何在几乎所有的失败,仍然赢得大-链接



简单之前的通用性,使用后方可重新使用-连接

简单,请-一个宣言软件开发-链接



软件设计是人际关系-链接



All Articles