大家好 今天,我们发布了本·奈德(Ben Neidel)网站上的下一则评论的译文-该网站一定会让您对原始内容感兴趣。 这次,我们将讨论“
分布式系统。设计模式 ”这本书,它是对今年年初出版的“
Master Kubernetes ”书的补充,从本质上讲,它是GoF在分布式系统设计上的类似物。

阅读愉快。
周末,我读了《分布式系统》一书。 设计模式,作者:
Brendan Burns 。 我确实很喜欢这本书,尽管我必须承认,我希望在其中找到一些不同的材料。 因此,在书的描述中仅顺便提及了容器。 同时,尽管本书中描述的模式不仅适用于容器化,但此处描述的几乎所有模式都是在容器上下文中给出的,然后在Kubernetes部署管道中考虑它们。 原来是这样。 我刚刚开始熟悉面向容器的开发和部署,并且从这种“容器”的角度讨论架构模式对我来说是一个启示。 这种方法帮助我很好地了解了如何在微服务领域正确区分小型服务,每个小型服务都有特定的机会。
该书的作者Brendan Burns是开源项目Kubernetes的共同创始人。 因此,其所有应用程序示例都是围绕基于Kubernetes配置文件的容器部署构建的,这不足为奇。 在阅读本书时,我对Docker有所了解,对Kubernetes一无所知。 因此,我试图通过简单地阅读来确定Kubernetes配置文件的“目的”。 但是,我相信,如果读者至少对Kubernetes有一定的经验,那本书会更有用。
阅读本书,我无法摆脱与Gregor Hope和Bobby Wolf的工作“
企业应用程序的集成模板 ”的联系。 Burns讨论的许多模式与Hope和Wolfe讨论的消息队列模式非常相似。 实际上,我必须说,两本书中甚至都以相同的方式提到了许多模式(例如,Scatter / Gather)。 这是合乎逻辑的,因为这两本书的主题都是将复杂的整体系统划分为一组小型的,紧密定制的可重用服务。 我认为甚至可以说,伯恩斯提出了一些特定的方法,这些方法将对实现基于消息的工作流的功能所涉及的生产者服务和消费者服务有用,与《企业应用程序集成模板》一书中描述的方法相同。
同样,我相信这两本书之间的相似之处证明了设计模式的强大作用。 它们在如何引导我们找到可靠的解决方案方面以及设计模式都促进了技术交流这一事实,因为它们允许我们以通用语言进行推理。
同时,“分布式系统”一书中介绍了我最喜欢的一种方法。 设计模式”与消息队列的使用量正好相关。 Burns建议不要强迫工作容器直接从系统中提取消息(类似于在Amazon的简单队列服务(SQS)系统中完成的操作),而是要创建一个“大使”(大使模式)。 这样的“大使”容器将与工作容器一起部署,并提供用于操纵队列的通用API。 使用Ambassador容器,您可以抽象化与消息队列中元素的永久存储有关的实现细节,从而使工作容器完全独立于任何特定的技术解决方案。
“工作队列的容器来源的大使”只是贯穿整个主题的一个例子,该主题贯穿于本书,是一条红线:使用小容器的集合,这样每个容器都可以专注于特定任务并尽可能地重用。 Burns在单个容器级别探讨了这个概念,讨论了使用命令行参数和环境变量对容器进行参数化。 然后他上一个级别,讨论在单节点环境中的多容器侧车和大使模式。 最后,他展示了如何使用多容器模式创建强大的微服务架构。
我认为Burns能够完美地表达整个微服务领域的“梦想”:
微服务方法具有许多优点,其中许多与可靠性和灵活性有关。 微服务将应用程序分为几个小部分,每个小部分负责提供特定的服务。 通过缩小服务范围,每项服务都可以发展和维持一支可以用两个比萨饼喂饱的团队。
减小团队规模还可以减少维持活动的成本。
此外,微服务之间正式接口的出现削弱了团队之间的相互依赖性,并在服务之间建立了可靠的契约。 这样的正式合同减少了团队紧密同步的需要,因为提供API的团队了解确保兼容性的必要程度,并且使用API的团队可以依靠稳定的服务而不必担心所使用服务的实现细节。 这种分解使团队可以独立控制开发速度和发布新版本的时间表,这使他们有机会进行迭代,从而改进了服务代码。
最后,划分为微服务可提高可伸缩性。 由于每个组件都分配给单独的服务,因此可以独立于其他组件进行扩展
(第79-80页,俄语翻译)
我说的是“梦想”,因为正如伯恩斯本人承认的那样,设计微服务系统和设计其体系结构很困难。 监视和调试这种系统比监视和调试单片模拟程序要复杂得多。 有了这个,我很容易同意。 根据我在微服务方面的有限经验,我确认共享服务会迅速建立高度连接,并且服务之间的“可靠合同”会迅速成为一个不断变化的目标,并且正在经历越来越多的新变化。
最后,我想谈谈FaaS概念-“功能即服务”。 像Amazon的Lambda Service这样的系统让我感到feel贬不一。 从极其抽象的意义上讲,我喜欢这样的系统,但是我不知道它们如何在特定的应用程序中表现出来。 伯恩斯(Burns)在第二部分“设计服务系统的模式”中谈到了FaaS,但不幸的是,它并没有为我完全阐明Faas问题。
我非常喜欢Burns建议使用FaaS解决已知问题的一部分:
与开发分布式系统的其他工具一样,您可能希望使用特定的解决方案(例如,面向事件的处理)作为通用工具。 事实是,特定的解决方案通常可以解决特定的问题。 在某种情况下,它将被证明是一个强大的工具,但是如果将它拉到解决常见问题的耳朵旁,则会创建复杂而脆弱的架构。
(第135页,俄语翻译)
此外,非常感谢他提到使用FaaS时遇到的困难:
如上一节所述,使用FaaS方法进行系统开发会迫使您使系统组件松散耦合。 根据定义,每个功能都是独立的。 所有交互都通过网络进行。 函数实例没有自己的内存;因此,它们需要共享存储来存储状态。 强制削弱系统元素的连接性可以提高服务开发的灵活性和速度,但同时会使它的支持大大复杂化。
特别是,很难看到服务的全面结构,确定功能如何相互集成,了解发生故障时出错的原因和原因。 此外,函数的面向查询和无服务器性质意味着某些问题将很难发现。
(第136-137页,俄语翻译)
再次让我感到惊讶的是,大多数FaaS系统不能很好地解决需要主动处理的任务:
...此外,由于无服务器实现服务,通常会限制功能实例的执行时间。 这意味着FaaS方法通常不适用于需要长时间后台数据处理的应用程序。 (第138页,俄语翻译)
最后,令我感到欣慰的是,如果无法确保处理器长时间不间断地运行,则FaaS在经济上变得不合时宜:
但是,如果您有太多的请求以至于该功能一直处于活动状态,那么您可能会为处理的请求数量支付过多的费用。
...随着服务的增长,已处理请求的数量增长到了这样的水平:处理器不断忙于处理它们。 此时,请求数量的费用开始变得无利可图。 云虚拟机的每单位CPU时间成本随着核心的增加以及预留资源和长期使用的折扣而降低。 请求数量的支付成本通常随着请求数量的增加而增加。
(第139-140页,俄语翻译)
结果,我仍然不明白:什么时候使用“功能即服务”更好? 我注意到,伯恩斯(Burns)简要描述了处理面向事件的短期任务的工作,这些任务不会给处理器带来太多负担,例如两要素身份验证(2FA)。 但是,鉴于我们正在谈论的是低成本的小型短期任务,因此出现了一个问题:为什么应该独立扩展这些任务? 为什么不将这些功能仅包含在与第一个紧密相关的另一个容器服务中?
我希望在实践中使用FaaS技术时能更好地解决这些问题。
除了对FaaS感到困惑之外,我真的很喜欢这本书。 它读起来很快,很容易理解。 它再次提醒我们在应用程序开发的各个级别上削弱组件之间连接的巨大潜力。 最后,现在,与我的同事就“ Sidecar集装箱”这样的话题进行对话将变得更加容易。