• 制造不可靠的系统


    什么是建模?

    人脑是一种模式寻找装置。然而,这是一个代价高昂的过程,思考的主要目标是首先终止/解决导致该过程开始的原因;因此它开发了几种机制来防止它过于频繁地发生;与我们在这里讨论有关的是心智模型。现实很复杂,混乱,太混乱,我们有限的大脑能力和资源无法理解(如果可能的话);所以我们的大脑会尝试创建一个非常简单且(大多数情况下)易于理解的替代现实,这就是建模的全部内容!从我们如何看待自然如何运作,例如在科学中,到适当的社会行为,到害怕或寻求什么,所有这些都是我们心智模式的结果。值得注意的是,模型既不是客观现实,也不应如此!

    所有模型都是错误的,但有些模型是有用的。

    — 乔治盒子

    一般来说,有两种模型:

    1. 没用(在上下文中)
    2. 有用的(在上下文中)

    上下文部分在这里非常重要,例如,牛顿的引力理论(顺便说一下,理论也是模型!)与广义相对论,两者都在不同的上下文中有用(平面时空在在可能弯曲的时空中低速与近光速)并且一个不会取代另一个,因为历史上的一些记者试图说服人们事实就是如此,科学已经改变了主意!无偏见的上下文感对于设计成功、可靠的系统 (恕我直言) 至关重要。

    什么是可靠性?

    软件可靠性的含义没有全球公认的定义;有人说它关乎运行可靠性,有人说它关乎客户体验,有人说它强调程序的正确性,还有一些人将它与容错性和可用性混淆!(然而,在某些情况下,这些可能是一些因素)所以我需要在本文的上下文中定义我所说的可靠性。我使用我们在英语中使用的可靠性;一个可靠的系统是我们可以信任的系统,它可以尽可能完美地完成我们的意思,并且不会做任何我们不希望它做的事情。乍一看似乎是正确的,但我认为这是它的超集;例如,您不会依赖每分钟崩溃的缓慢系统,但如果有足够的时间,它会完成它的工作!

    建模如何影响系统的可靠性?

    解决问题的过程

    你不能忽视现实,走得很远!这里的推理非常直观,但大多数时候都被忽略了。

    让我解释:

    我们想让事情变得更容易,消除任何成本、金钱或精神能量。

    1. 我们开始将我们的条件视为要解决的问题。
    2. 为了解决这个问题,我们需要收集数据。
    3. 将现实映射到一个更简单的模型以适应我们的想法。
    4. 定义要解决的问题,然后开始试验模型。
    5. 希望我们能在一些迭代后解决这个问题。
    6. 我们需要找到一种方法在现实中实施解决方案,以实现我们的第一个目标。

    当我们想要实施解决方案时,实际上,我们有很多选择。最常见的方法之一(也是我们在这里感兴趣的方法)是通过编程来利用计算机系统

    你的思维可能解决现实世界中的问题的唯一原因是你的思维模型与现实世界之间存在关系,所以如果你没有对建模给予足够的关注,你就无法在没有任何模型的情况下开始实施; 这意味着您正在隐式地实现一个幼稚的模型,这增加了面临我们在本文中讨论的严重问题的机会,并且也大大降低了模型与现实的相关性。例如,您最终将进入幻想世界!

    拥有一个与现实不完全相似的模型也是一种负担,因为现实在上述模型中以意想不到的方式表现。例如,托勒密的太阳系地心模型,它比圆形轨道的日心模型更精确,但在描述他那个时代未知的其他现实部分时遇到了很多麻烦,而椭圆轨道的日心模型则解决了这些问题,因为它既更直截了当,也更准确地描述了现实。注意,这并不是说有正确的模型,其他模型都是错误的!如前所述,模型只是我们理解和解决问题的工具。我们不应该将它们与现实混为一谈。

    托勒密本人在他的《天文学大成》中指出,任何描述行星运动的模型都只是一种数学装置。由于无法知道哪个是正确的,因此应使用获得正确数字的最简单模型。

    忽略业务

    回到软件行业,如果你在设计一个企业软件系统,你就是在为一个建立在人员沟通、组织结构和业务流程(本身就太复杂!)的系统的现有模型建模;创建另一个具有任何逻辑和概念不匹配的模型会非常迅速地增加复杂性并同时降低生活幸福感。

    您无法通过更多的技术努力来解决业务问题!

    这就是领域驱动设计帮助建模的地方。DDD 是指战略模式和想法,而不是像实体和存储库这样的战术模式,它教会我们发现现有的业务模型,而不是试图创建可能不匹配的另一个模型,从而降低整体复杂性并考虑整体社会技术因素。
    当现有模型是已经存在了一段时间并且已经成熟的业务时尤其如此。

    过于简化的系统

    一切都应该尽可能简单,但不能简单。

    - 艾尔伯特爱因斯坦

    一个试图过度简化现实的系统最多会丢失一些重要的业务概念,或者在最坏的情况下会走错方向。

    我最喜欢的这种现象的例子是,当软件开发人员试图引入比所需更多的一致性时,最终结果总是缺少一个重要的概念,然后需要这个概念来处理业务流程中可能出现的冲突,并且还会创建缓慢的可怕软件片段和意大利面条在性质上。例如,在银行交易中,资产不会立即转移(以原子方式),并且有一段时间资产处于软状态,即既不在源账户也不在目标账户;尝试以原子方式对其进行建模将需要 2PC,这(几乎)始终是不良建模的标志. 或者,就此而言,更常见的一种是购物车试图以原子方式进行仓储,但由于没有考虑到仓库缺货或物品在事故后调整的可能性,因此遇到了同样的问题这导致一些货物成为浪费!

    这种建模问题几乎总是在竞争条件下结束!

    除非您错过了一个概念,否则现实世界中没有竞争条件!

    过度抽象

    呆伯特:哦不!极端的抽象程度让我们失重了!

    另一个糟糕的建模情况是过度抽象的情况,这也会丢失重要的概念;例如,虽然我们可以从数学的角度将方法调用替换为远程调用,但这会隐含地假设网络是可靠的,但事实并非如此!并且充其量会使许多错误处理复杂化,或者由于忽略分布式系统的性质而引入了无法正确处理的错误。
    解释前者,您无法知道该方法是否在远程位置执行并且响应没有及时到达,或者它从未到达目的地;这是一个根本性的问题,它很努力地告诉我们不能这样解决!

    另一个常见示例是将本质上的异步交互建模为同步交互。这只会使事情复杂化,因为您将可能的场景缩小到一个不够大的问题空间,因此您要么忽略问题,要么尝试非常努力地理解启发式方法以部分缓解与您的主要问题无关的问题,但是一个坏模型引入的问题!
    这就是为什么在设计可靠的分布式系统时 RPC 几乎总是一个坏主意。

    忽略物理

    当您引入并发或任何分布时,您正在改变有关程序运行方式的物理定律;你正在改变时间的本质,从牛顿世界观(有一个独特的全球时钟)到广义相对论中的多体物理学(每个物体都有自己的相对时钟);您还将普通逻辑更改为时间逻辑,如果不考虑时间行为就无法得出结论。

    你的问题变得复杂了好几个数量级,你不能忽视这些问题,最多继续工作几天!将分布式系统添加到组合中;您最终将获得更多数量级的复杂性!

    不了解分布式/并发系统与大多数开发人员所习惯的系统有何不同是导致许多业务失败以及相关人员痛苦和痛苦的原因。

    我的分布式对象设计第一定律:不要分发你的对象。

    — 马丁·福勒

    这是一个如此广泛的话题,需要一本书才能触及表面!但我会提到一些常见的谬误:

    • Time:正如我前面提到的,时间及其所有导数(例如速度,...)都是相对于观察者而言的,并且没有全局时间,这意味着在分布式系统中,您无法比较时间,并且总排序是不明确的。
    • 排序:您必须显式地为您的排序建模,因为没有隐含的排序,最常见的方法是使用将创建偏序的相关 ID,这可以通过将时间替换为我们使用时间的意思来解决前面提到的所有问题,这是因果关系。
    • 同步:在分布式系统中,你是异步的;您无法做出其他决定,因为自然是异步的;这样想,甚至光、电和核力都是事件驱动的 :) 因为它们是通过发送微小粒子(例如光子、胶子、W 和 Z 波松子)作为消息来传输的,所以之后没有同步行为我们离开了量子领域。
      请注意,我所说的异步不是指使用消息代理,而是异步通信!这可以使用 HTTP 来实现,例如,拉取与推送等待,就像在 Atom 提要与 RPC 中一样。
    • Delivery:上述属性的一个结果是,我们既不能保证只发送一次,也不能保证消息的排序。正如以下引文中幽默地指出的那样:

    分布式系统中只有两个具有挑战性的问题:

    2. 一次性交货

    1.保证消息的顺序

    2. 一次性交货

    — 马蒂亚斯·维拉斯

    • 延迟:计算机很快!但不幸的是,没有什么能比光传播得更快,虽然它非常快,但它不是即时的,甚至光也不够快,无法覆盖糟糕的建模错误!

    其他因素

    忽略组织

    为现实世界的应用程序建模是一项复杂的任务,每个规模很大的系统都需要大量的团队合作,而且远远超出了个人的能力。团队合作很难;它必须像任何其他技能一样掌握,但对许多人来说似乎并不那么自然,因此通常需要指导和良好的管理才能实现。这是一项复杂的任务,因为它需要管理技能和正确的使用条件,而且大多数个人甚至团队都无法控制。
    但如果碰巧出现这种情况,可靠的系统似乎是在可靠的组织中建立的,那里有持续改进的文化和开放的沟通结构,团队围绕能力而构建,并有足够的自主权来做需要的事情,并且可以在需要时影响和改进整个组织。僵化的组织无法创建可靠的系统,因为这是一种迭代改进的努力,无法在这类组织中实施。例如,围绕权威形成的组织与产生良好结果的组织完全相反,因为没有自主权。人们不会用最相关的信息和技能做出决定。

  • 相关阅读:
    软件测试架构师需要掌握那些知识点和技能?
    java 企业工程管理系统软件源码+Spring Cloud + Spring Boot +二次开发+ MybatisPlus + Redis
    ensp配置访问控制拓扑如何配置
    JVM知识总结(性能调优)
    【Android】了解强引用、软引用、弱引用、虚引用
    【华为OD题库-025】 找出两个整数数组中同时出现的整数-java
    全球南方《乡村振兴战略下传统村落文化旅游设计》许少辉八一新枝——2023学生开学季辉少许
    Day04-GET和POST请求
    java+mysql基于SSM共享型汽车租赁系统-计算机毕业设计
    TypeError: this.cliEngineCtor is not a constructor,webstorm和eslint的版本纠结
  • 原文地址:https://blog.csdn.net/vvoennvv/article/details/127680752