微服务架构的实践技巧有哪些
本篇内容介绍了"微服务架构的实践技巧有哪些"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
1. 微前端
不幸的是,大多数后端开发人员对前端开发的看法比较落后,认为前端开发很简单。由于大多数软件架构师都是后端开发人员,因此几乎不关心前端,并且前端通常在架构设计中被忽略。在微服务项目中,后端数据库常常会高度模块化,但是有一个Monolith前端。在合适的情况下,开发人员会考虑使用最热门的SPA(React,Angular,Vue)之一来开发Monolith 前端。
但主要问题在于,前端Monolith与笔者在文章《微服务架构:简介与在项目中应用的必要性》(MicroserviceArchitecture: A brief overview and why you should use it in your next project)描述的后端Monolith一样糟糕。
此外,由于更改浏览器也要保持前端的同步,就需要进行大爆炸式的现代化(这就是许多公司仍在使用过时的Angular 1框架的原因)。网络简单但功能强大,并本身提供嵌入。基于微前端开发SPA有很多方法:使用iFrame、Web组件或通过Elements(Angular / React)。
2. 连续交付
微服务架构的一个关键USP是每个微服务都可以独立部署。如果系统有100个微服务,要求更改一个微服务,那么可以仅更新一个微服务,而无需更改其他99个微服务。
但是,在没有自动化的情况下独立部署100个微服务(DevOps,CI / CD)是一项艰巨的任务。要充分利用此微服务功能,需要CI / CD和DevOps法。使用不带CI / CD,DevOps的微服务架构,自动化就像购买最新的保时捷,然后手动刹车驾驶。不足为奇的是,CI / CD被微服务专家马丁·福勒(Martin Fowler)列为使用微服务架构的三个先决条件之一。
3. 微服务优先
许多专家认为,对于未开发的(新的)项目,最好从松耦合的单片架构开始,因为微服务架构需要大量的初始工作来设置操作。
专家认为,一旦该项目变得足够成熟,就可以将"精巧"设计的Monolith轻松地转换为微服务。但是,笔者认为这种方法在大多数情况下将以失败告终。实际上,Monolith内部的模块紧密耦合,这使其难以转换为微服务。同样,一旦应用程序正式投入生产,要在不中断应用程序的情况下转换为微服务将变得更加困难。因此,如果最终有计划使用微服务架构,建议一开始就使用微服务。
4. 库的基础设施。
在微服务软件开发的早期,Netflix主要使用Java编程来开发微服务。Netflix还开发了许多库(包括Hystrix,Zuul的Netflix OSS Stack)。许多公司效仿Netflix,并开始使用Netflix OSS库。后来,许多公司(包括Netflix)发现Java并不是开发微服务的事实语言,因为Java体积庞大且存在冷启动问题。
Netflix后来转向Polyglot微服务范式,并决定不再进一步开发Netflix OSS,这导致追随Netflix的公司陷入困境。因此,与其大量投资于特定语言的库(例如基于Java的Netflix OSS),使用框架(例如服务网格,API网关)更为明智。
5. 域驱动设计
开发微服务较大的挑战是将大型、复杂的应用程序拆分为小型、可管理且可独立部署的模块。如果微服务没有以正确的方式对应用程序进行拆分,那么将存在紧密耦合的微服务,这些微服务将具有Monolith的所有缺点以及微服务(又名分布式Monolith)的所有复杂性。
幸运的是,在这方面已经有一个可以提供许多帮助的解决方案。埃里克·埃文斯(Eric Evans)是一名软件工程顾问,曾在不同公司中多次遇到有关业务应用程序中复杂性的问题,并在2004年出版的书籍《域驱动设计:解决软件核心中的复杂性》中总结了很有价值的见解。该书的核心概念可分为以下三类:
软件开发团队应与业务部门或领域专家紧密合作。
架构师或开发人员和领域专家应首先进行战略设计:查找有界上下文以及相关的核心域、通用语言、子域、上下文映射图。
然后,架构师或开发人员应进行战术设计,将核心领域分解为细粒度的构建基块:实体、值对象、聚合、聚合根。
域驱动设计的详细讨论超出了本文的范围,但是大家应该读读原书埃里克·埃文斯(Eric Evans)《域驱动设计:解决软件核心中的复杂性》(蓝皮书)或沃恩·弗农(Vaughn Vernon)所著书籍《实施域驱动设计》(红皮书)。如果将一个大型系统分为核心域和子域,再将核心域和子域映射到一个或多个微服务,那么可以获得理想的松耦合微服务。
6. 可观察性
微服务架构的一个主要缺点在于以运营为代价使软件开发变得简单。使用Monolith监视应用程序要更为简单。但是,由于许多微服务在容器上运行,因此整个系统的可观察性变得非常关键和复杂。甚至日志记录也变得很复杂,无法将来自许多容器或机器的日志聚合到一个中心位置上。
幸运的是,市场上已经有许多企业级的解决方案。例如,ELK / Splunk提供微服务的日志记录。Prometheus / AppDynamics提供行业级的监视。在微服务领域,另一个非常重要的可观察性工具是Tracing。通常,微服务的一个API请求会导致对其他微服务的多次级联调用。要分析微服务系统的延迟,有必要测量每个微服务上的延迟度。Zipkin / Jaeger为微服务提供了出色的跟踪支持。
7. 统一技术栈
微服务架构表明,需要采用对于微服务最适合的编程语言和框架。这不应从字面上理解。有时,微服务可能需要新的技术栈,例如对于CPU繁重或高性能的任务,可以选择C ++ / Rust之类的编程语言。如果微服务可与机器学习一起使用,也许Python是更好的选择。
但是,在没有任何充分理由的情况下,使用不同的编程语言或框架可能会出现太多的编程语言和框架,而没有带来任何真正的好处。想象一个这样的场景:使用Spring Boot + Kotlin + React + MySQL开发一种微服务,使用JakartaEE + Java + Angular + PostgreSQL开发另一种微服务,再使用Scala + Play Framework + VueJS + Oracle开发其他一种微服务,那么需要付出很多努力维护不同的编程语言、数据库和框架,但收获会很少。
8. 每个微服务的数据库
将复杂应用程序拆分为微服务模块后,接下来的挑战出现了——如何处理数据库?
是否应该在微服务之间共享数据库。这个问题的答案是双刃剑,有利有弊。
一方面,在微服务之间共享数据库将带来强大耦合,这与微服务架构的目标恰恰相反。即使数据库中出现微小变化,也需要团队之间的同步操作。同样,在一项服务中,管理事务和锁定数据库也具有挑战性。但是在多个分布式微服务之间管理事务或锁定数据库是一项艰巨的任务。
另一方面,如果每个微服务都有自己的数据库或专用表,则在微服务之间交换数据就会带来会打开潘多拉魔盒式的挑战。因此,许多杰出的软件工程师都提倡在微服务之间共享一个实用的解决方案。但是,笔者认为,微服务完全是一个可持续和长期的软件开发过程。因此,每个微服务都应具有自己的数据库(或专用表)。
9. 异步通讯
微服务架构中很具挑战性的一个设计决策是服务之间如何进行通信和共享数据。当每个微服务都有自己的数据存储时,这一点尤为重要。
通常,一个微服务可以单独存在,但不能单独满足所有业务目标。所有微服务一起工作,实现业务目标,并继续一起工作,这些微服务需要交换数据或触发其他微服务来完成任务。微服务之间最简单且最常见的通信方式是通过Synchronous REST API,这很实用,但不是长久之计。如果服务A调用服务B,服务B调用服务C,服务C同步调用服务D,那延迟就会叠加。
另外,由于微服务主要是分布式系统,因此可能会有故障。同步微服务通常会导致失败的级联,即一个服务中的故障可能导致其他服务出现故障。微服务之间的同步通信还导致微服务之间的紧密耦合。想要有个长久的解决方案,则微服务应该异步通信。微服务之间的异步通信有很多方法:例如,通过Message QueueKafka,通过异步REST(ATOM)或CQRS。
10. 组织注意事项
大约50年前(1967年),梅尔文·康威(Melvin Conway)观察到,公司的软件架构受组织结构(康威法则)的限制。尽管这一发现已有50年历史,但麻省理工大学和哈佛商学院最近发现该法律在现代仍然有效。如果某个组织计划开发微服务架构,则应相应地扩大团队规模(两个"美式"比萨团队:5人或9人)。此外,团队应是跨职能的,并且理想情况下拥有前端或后端开发人员、Ops工程和测试人员。微服务架构仅在高级管理层也相应地改变观点和愿景的情况下才起作用。
"微服务架构的实践技巧有哪些"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!