资源预览内容
第1页 / 共6页
第2页 / 共6页
第3页 / 共6页
亲,该文档总共6页,到这儿已超出免费预览范围,如果喜欢就下载吧!
资源描述
微效劳开发 10 个最正确实践微效劳架构是将软件系统分解成可独立部署的自治模块,这些模块通过轻量级的、语言无关的方式进展通信,共同实现业务目标。软件系统是简单的。由于人脑只能处理肯定程度内的简单性,大型软件系统的高简单性导致了很多问题。大型简单的软件系统难于开发、增加、维护、现代化和规模化。多年来,为解决软件系统的简单性做过很多尝试。在上世纪 70 年月, David Parnas 和 Edsger W. Dijkstra 引入了模块化软件开发,以解决软件系统的简单性。在上世纪 90 年月,引入了分层软件架构来处理业务应用程序的简单性。自本世纪初以来,面对效劳的架构Service Oriented Architecture, SOA成为开发简单业务应用程序的主流。微效劳架构是处理现代软件应用简单性的最新方法。此时,大家可能会提出一个问题:为什么我们突然需要一个新的软件开发方法?简而言之,与软件开发相关的整个生态系统在过去十年中发生了巨大的变化。如今,软件使用灵敏方法开发,使用 CI/CD 在容器 + 云上部署,在 NoSQL 数据库上长久化,在现代扫瞄器或智能手机上呈现, 机器通过高速网络连接。由于这些因素的消灭,在 2021 年诞生了微效劳架构。微效劳还是单体架构主要有两类人对微效劳和单体架构持相反的观点。对于一群人来说,微效劳架构完全是关于货物崇拜或炒作驱动的开发,这只是痴迷于技术的开发人员的游乐场。对于另一群人来说,微效劳架构是“一个管控全部的架构”,它可以消退软件系统的任何简单性。在我看来,微效劳和单体架构是互补的。假设从长远来看,这个应用程序仍旧会较小,那么单体架构是适合的方法。另一方面,对于大型而简单的应用程序或有潜力变得大型而简单的应用程序,微效劳架构是正确的解决方案。现代软件开发是如此浩大,以至于微效劳架构和单体架构将像 SQL 和 NoSQL 一样的方式共存。微效劳的最正确实践正确设计微效劳架构格外具有挑战性和困难。与单体架构为全部问题供给一个解决方案相 反,微效劳架构为不同的问题供给不同的解决方案。假设选择了错误的解决方案,那么微效劳架构就是一个注定要爆炸的定时炸弹。一个设计糟糕的微效劳架构比一个单体架构还要糟糕。为微效劳架构定义一组最正确实践也很有挑战性。我曾在一些会议上看到一些有名的、受人敬重的软件工程师提出了微效劳架构的最正确实践,但这些实践却适得其反。6在这里,我提出了一些最正确实践,这些实践将有助于开发有效的微效劳应用程序,在这些应用程序中,目标工程应当存在超过 6 个月的时间,并且团队规模从中等到大型6+ 开发人员。另外,还有一些关于微效劳架构最正确实践的文章,例如 Martin Fowler的微效劳架构的特征 Characteristics of a Microservice Architecture 、Chris Richardson 的微效劳模式 Microservices Patterns 、以及 Tony Mauro 的在 Netflix 承受微效劳:架构设计的教训 Microservices at Netflix: Lessons for Architectural Design 。也有一些很棒的演讲,例如 Stefan Tilkov 的微效劳模式和反模式 Microservices Patterns and Antipatterns ,David Schmitz 的微效劳严峻失败的 10 个技巧 10 Tips for failing badly at Microservices ,Sam Newman 的微效劳原理 Principles ofMicroservices 。1 领域驱动设计开发微效劳的首要挑战是将大型、简单的应用程序分割成小型、自主、独立的可部署模块。假设微效劳没有以正确的方式进展分割,将会消灭紧耦合的微效劳,这些微效劳将具有单体架构的全部缺点,并具有分布式单体架构的全部简单性。幸运的是,已经有一个解决方案可以在这方面供给很大的挂念。Eric Evans 当时是一名软件工程参谋,他在不同公司的业务应用程序中遇到了关于软件简单性的反复消灭的问题,于是在 2004 年出版的领域驱动设计:处理软件核心的简单性一书中总结了他的贵重见解。该书概述了三个核心概念:软件开发团队应当与业务部门或领域专家亲热合作。架构师/开发人员和领域专家应当首先进展战略设计:找到有界的上下文和相关的核心域以及普遍存在的语言、子域、上下文映射。然后,架构师/开发人员应当进展战术设计,将核心域分解为细粒度的构建块:实体、值对象、聚合、聚合根。领域驱动设计的具体争辩超出了这篇文章的争辩范围,但是你应当读一下起初的 DDD 书籍Eric Evans 的领域驱动设计:处理简单的软件蓝皮书 Domain Driven Design: Tackling Complexity in the Heart of Software Blue Book,或者更现代一点儿的DDD 书籍 Vaughn Vernon 的实现领域驱动设计红皮书 Implementing DomainDriven Design Red Book。假设将一个大型系统划分为核心域和子域,然后将核心域和子域映射到一个或多个微效劳,那么我们将得到抱负的松耦合微效劳。2 每个微效劳一个数据库在将简单的应用程序拆分为多个微效劳模块之后,下一个挑战消灭了,如何处理数据库?我们是否应当在微效劳之间共享数据库?这个问题的答案是一把双刃剑。一方面,在微效劳之间共享数据库将导致微效劳之间的强耦合,这与微效劳架构的目标正好相反。即使是数据库中的一个小更改也需要团队之间的协调同步。此外,在一个效劳中治理数据库的事务和锁就已经足够具有挑战性了。而在多个分布式微效劳之间治理事务和锁更是一项困难的任务。另一方面,假设每个微效劳都有自己的数据库或私有表,那么在微效劳之间交换数据就翻开了挑战的潘多拉盒子。因此,很多有名的软件工程师都提倡在微效劳之间共享数据库,将其作为一种有用的解决方案。然而,在我看来,微效劳是关于可持续和长期的软件开发的。因此,每个微效劳都应当有自己的数据库或者私有表。3 微前端不幸的是,大多数的后端开发人员对前端开发有一种过时的看法,认为前端开发很简洁。由于大多数软件架构师都是后端开发人员,他们很少关注前端,而前端在架构设计中往往被无视。通常在微效劳工程中,后端与它们的数据库被很好地模块化,但只有一个整体前端。在最好的状况下,他们考虑用最热门的单页面应用React、 Angular、Vue其中之一来开发独体前端。这种方法的主要问题是,前端的单体架构和后端单体架构一样糟糕,正如我前一篇文章所述。另外,当前端由于扫瞄器的变化而需要更新时,它就需要一个大的更新这就是为什么那么多公司仍旧使用过时的 Angular 1 框架的缘由。网络是简洁的,但格外强大,并天生供给了穿透力。开发基于单页面应用的微前端有很多方法:使用 iFrame、Web 组件或借助于Angular/React元素。4 持续交付微效劳架构的关键卖点之一是每个微效劳都可以独立部署。假设你有一个系统,例如 100 个微效劳,并且只需要更改一个微效劳,那么你可以只更新一个微效劳,而不需要修改其他 99 个微效劳。但是,在没有自动化的状况下独立部署 100 个微效劳DevOps、CI/CD是一项困难的任务。要充分利用微效劳的这一特性,需要 CI/CD 和 DevOps。使用没有 CI/CD、DevOps 的微效劳架构,自动化就像购置最新的保时捷,然后用手刹去驾驶它。难怪微效劳专家 Martin Fowler 将 CI/CD 列为使用微效劳架构的三个先决条件之一。5 可观看性微效劳架构的主要缺点之一是,软件开发变得简洁,而牺牲了运维。使用单体架构,监视应用程序要简洁得多。但是很多微效劳在容器上运行,整个系统的可观看性变得格外重要和简单。甚至日志记录也变得很简单,要将来自很多容器 / 机器的日志聚拢到一个中心位置。幸运的是, 市场上已经有很多企业级的解决方案了。例如,ELK/Splunk 供给微效劳的日志记录。Prometheus/App Dynamics 供给工业级监控。微效劳世界中另一个格外重要的可观看性工具是Tracing。通常,对一个微效劳的一个 API 恳求会导致对其他微效劳的几个级联调用。要分析微效劳系统的延迟,需要测量每个微效劳的延迟。Zipkin/Jaeger 为微效劳供给了精彩的跟踪支持。6 统一技术栈微效劳架构告知我们,对于一个微效劳,承受最适合该微效劳的编程语言和框架。这种说法不能照字面理解。有时,一个微效劳可能需要一个新的技术栈,例如 CPU 密集 / 高性能任务, 可能会选择如 c+ /Rust 之类的编程语言。假设微效劳与机器学习一起工作,那么 Python 可能是更好的选择。但是在没有任何理由的状况下使用不同的编程语言 / 框架会导致过多的编程语言和框架而没有任何实际的好处。思考这么一个应用场景,一个微效劳是使用 Spring Boot + Kotlin+ React + MySQL 开发的,另一个用的是 JakartaEE + Java + Angular + PostgreSQL,下一个是 Scala + Play Framework + VueJS + Oracle,那么需要大量的工作去维持这些不同的编程语言、数据库、框架,而没有太多的收益。7 异步通信微效劳架构中最具挑战性的设计决策之一是效劳之间如何通信和共享数据。当每个微效劳都有自己的数据存储时,这一点就更为重要了。通常,一个微效劳可以单独存在,但是它不能单独实现全部的业务目标。全部微效劳为了实现业务目标而在一起工作,为了在一起工作,它们需要交换数据或触发其他微效劳来执行任务。在微效劳之间进展通信的最简洁和最常见的方式是通过同步的 REST API,这是一种有用但临时的解决方案。假设效劳 A 同步调用效劳 B,效劳 B 同步调用效劳 C,效劳 C 同步调用效劳 D,那么延迟就会增加。此外,由于微效劳主要是分布式系统,它们有可能会失败。通常,同步微效劳会导致级联失败,即一个效劳的失败会导致其他效劳的失败。微效劳之间的同步通信也导致了微效劳之间的严密耦合。对于长期解决方案,微效劳应当异步通信。微效劳之间的异步通信有很多方式:通过消息队列,例如 Kafka,通过异步的REST ATOM或 CQRS。8 微效劳优先很多专家认为,对于新工程,最好从松耦合的单体架构开头,由于微效劳架构需要大量的初始工作来设置运维。在他们看来,一旦工程变得足够成熟,“秀丽的”设计就可以很简洁地转化为微效劳。然而,在我看来,这种方法在大多数状况下都会失败。实际上,实体内部的模块将是紧耦合的,这将使其很难转换成微效劳。而且,一旦应用程序投入生产,在不破坏应用程序的状况下将其转换为微效劳将变得更加困难。因此,我的建议是,假设最终有使用微效劳架构的计 划,那么就从微效劳开头。9 根底设施优于类库在微效劳软件开发的早期,Netflix 主要使用 Java 编程来开发微效劳。他们还开发了很多类库Netflix 的 OSS 栈,包括 Hystrix、Zuul。很多公司通过 Netflix 跟进并开头使用 Netflix OSS。后来,很多公司包括 Netflix觉察,Java 实际上并不是开发微效劳的语言,由于它体积浩大,而且冷启动问题严峻。Netflix 后来转向 Polyglot 微效劳范式,并打算不再进一步开发Netflix OSS,这导致了追随者公司陷入逆境。因此,与其大量投资于特定语言的类库如基于Java 的 Netflix OSS,不如使
收藏 下载该资源
网站客服QQ:2055934822
金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号