写点什么

微服务开发的 10 个最佳实践

  • 2020-01-01
  • 本文字数:4710 字

    阅读完需:约 15 分钟

微服务开发的10个最佳实践

在文章《微服务架构概览》中,我详细讨论了微服务架构以及在现代软件开发中使用它的优缺点。那么,什么是微服务架构呢?我给出的定义是:


微服务架构是将软件系统分解成可独立部署的自治模块,这些模块通过轻量级的、语言无关的方式进行通信,共同实现业务目标。


软件系统是复杂的。由于人脑只能处理一定程度内的复杂性,大型软件系统的高复杂性导致了许多问题。大型复杂的软件系统难于开发、增强、维护、现代化和规模化。多年来,为解决软件系统的复杂性做过许多尝试。在上世纪 70 年代,David ParnasEdsger W. Dijkstra引入了模块化软件开发,以解决软件系统的复杂性。在上世纪 90 年代,引入了分层软件架构来处理业务应用程序的复杂性。自本世纪初以来,面向服务的架构(Service Oriented Architecture, SOA)成为开发复杂业务应用程序的主流。微服务架构是处理现代软件应用复杂性的最新方法。此时,大家可能会提出一个问题:为什么我们突然需要一个新的软件开发方法?简而言之,与软件开发相关的整个生态系统在过去十年中发生了巨大的变化。如今,软件使用敏捷方法开发,使用 CI/CD 在容器+云上部署,在 NoSQL 数据库上持久化,在现代浏览器或智能手机上展现,机器通过高速网络连接。由于这些因素的出现,在 2012 年诞生了微服务架构。

微服务还是单体架构

主要有两类人对微服务和单体架构持相反的观点。对于一群人来说,微服务架构完全是关于货物崇拜或炒作驱动的开发,这只是痴迷于技术的开发人员的游乐场。对于另一群人来说,微服务架构是“一个管控所有的架构”,它可以消除软件系统的任何复杂性。在我看来,微服务和单体架构是互补的。如果从长远来看,这个应用程序仍然会较小,则单体架构是适合的方法。另一方面,对于大型而复杂的应用程序或有潜力变得大型而复杂的应用程序,微服务架构是正确的解决方案。现代软件开发是如此庞大,以至于微服务架构和单体架构将像 SQL 和 NoSQL 一样的方式共存。

微服务的最佳实践

正确设计微服务架构非常具有挑战性和困难。与单体架构为所有问题提供一个解决方案相反,微服务架构为不同的问题提供不同的解决方案。如果选择了错误的解决方案,那么微服务架构就是一个注定要爆炸的定时炸弹。一个设计糟糕的微服务架构比一个单体架构还要糟糕。为微服务架构定义一组最佳实践也很有挑战性。我曾在一些会议上看到一些著名的、受人尊敬的软件工程师提出了微服务架构的最佳实践,但这些实践却适得其反。


在这里,我提出了一些最佳实践,这些实践将有助于开发有效的微服务应用程序,在这些应用程序中,目标项目应该存在超过 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 of Microservices )》。

1.领域驱动设计

开发微服务的首要挑战是将大型、复杂的应用程序分割成小型、自主、独立的可部署模块。如果微服务没有以正确的方式进行分割,将会出现紧耦合的微服务,这些微服务将具有单体架构的所有缺点,并具有分布式单体架构的所有复杂性。幸运的是,已经有一个解决方案可以在这方面提供很大的帮助。Eric Evans 当时是一名软件工程顾问,他在不同公司的业务应用程序中遇到了关于软件复杂性的反复出现的问题,于是在 2004 年出版的《领域驱动设计:处理软件核心的复杂性》一书中总结了他的宝贵见解。该书概述了三个核心概念:


  • 软件开发团队应该与业务部门或领域专家密切合作。

  • 架构师/开发人员和领域专家应该首先进行战略设计:找到有界的上下文和相关的核心域以及普遍存在的语言、子域、上下文映射。

  • 然后,架构师/开发人员应该进行战术设计,将核心域分解为细粒度的构建块:实体、值对象、聚合、聚合根。


领域驱动设计的详细讨论超出了这篇文章的讨论范围,但是你应该读一下起初的 DDD 书籍 Eric Evans 的《领域驱动设计:处理复杂的软件(蓝皮书)(Domain Driven Design: Tackling Complexity in the Heart of Software (Blue Book))》,或者更现代一点儿的 DDD 书籍 Vaughn Vernon的《实现领域驱动设计(红皮书)(Implementing Domain Driven 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),不如使用框架(如服务网格、API 网关)。

10.组织考虑

大约 50 年前(1967 年),Melvin Conway 观察到公司的软件架构受到组织结构的限制(Conway 定律)。尽管这一观察发现已有 50 年历史,但麻省理工学院(MIT)和哈佛商学院(Harvard Business School)最近发现,这一法则在当今仍然有效。如果一个组织计划开发微服务架构,那么它应该使团队规模更为恰当(两个“美国”比萨团队:7±2 人)。此外,团队应该是跨职能的,最好有前端/后端开发人员、运维工程师和测试人员。微服务架构只有在高层管理者也相应地改变他们的观点和愿景的情况下才能发挥作用。


作者介绍:


Md Kamaruzzaman,热情的软件架构师,终身学习者,热心的读者,偶尔也写写文章。


原文链接:


Effective Microservices: 10 Best Practices


2020-01-01 13:2113813

评论 2 条评论

发布
用户头像
1、2、3 的标题字号和后面的标题字号不一样吧?
2020-01-10 19:22
回复
感谢指正,已修改。
2020-01-16 10:03
回复
没有更多了
发现更多内容

MarsEdit for Mac v5.1.4激活版 博客写作软件

iMac小白

淘系接口推荐:淘宝天猫实时商品详情页面数据采集接口

tbapi

数据挖掘 淘宝商品详情数据接口 淘宝API接口 天猫商品详情数据接口

全方位解析ChatGPT:如何培养 AI 智能对话技能?

霍格沃兹测试开发学社

MES定制开发/云MES制造执行系统解决方案

万界星空科技

制造业 生产管理系统 mes 云mes 万界星空科技

容器中的大模型(三)| 利用大语言模型:容器化高效地部署 PDF 解析器实践

智领云科技

容器 PDF 大模型 AI大语言模型

基于Sermant的全链路灰度发布在汽车行业DMS系统的应用

华为云开发者联盟

云原生 华为云 汽车 华为云开发者联盟 企业号2024年4月PK榜

如何选择合适的系统?MES系统和MOM系统的区别

万界星空科技

制造业 mes 万界星空科技 生产管理 MOM

全面了解龙蜥衍生版 KeyarchOS 在安全、机密计算等方面的实践 | 龙蜥大讲堂浪潮信息专场

OpenAnolis小助手

开源 操作系统 龙蜥社区 龙蜥大讲堂

免费延期一年!Alibaba Cloud Linux 2 EOL 延保支持计划

OpenAnolis小助手

阿里云 操作系统 Alibaba Cloud Linux

容器中的大模型(二) | 利用大模型,使用自然语言查询SQL数据库

智领云科技

数据库 sql 容器 AI大模型 大模型

AnyRec Screen Recorder for Mac(Mac专业的屏幕录制软件)v1.1.22激活版

iMac小白

IM技术干货:假如你来设计微信的群聊,你该怎么设计?

JackJiang

即时通讯;IM;网络编程

通过淘宝开放平台API接口获取商品信息:标题、分类与店铺名称的新方法

技术冰糖葫芦

API 接口 API 文档

ChatGPT全方位解析:如何培养 AI 智能对话技能?

测试人

软件测试

高柔性第二代扁线定子量产线正式上市

财见

如何提升 API 的性能水平

Apifox

程序员 接口 API 开放 API API 性能

解锁AI Studio:玩转大模型应用,开启智能新时代

百度开发者中心

人工智能 深度学习 大模型

Advanced RAG 01:讨论未经优化的 RAG 系统存在的问题与挑战

Baihai IDP

AI LLM 企业号 4 月 PK 榜 rag 检索增强生成

开源流量回放平台 AREX 在携程的大规模落地实践

AREX 中文社区

Java 开源 测试 流量回放

Bigasoft Audio Converter for Mac(音频转换器)v5.8.0.8857中文激活版

iMac小白

京东中台化底层支撑框架技术分析及随想

京东科技开发者

月之暗面Kimi智能助手实现200万字长上下文,火山引擎提供云服务支持

新消费日报

QLab Pro for Mac(音频剪辑软件)v5.3.7激活版

iMac小白

向量数据库落地实践

京东科技开发者

Linux中的conntrack命令深入解析

GousterCloud

Linux 运维

Final Draft for Mac 剧本文字处理软件

iMac小白

开发者手机AI来袭

Laval小助手

Web Components实践:如何搭建一个框架无关的AI组件库

京东科技开发者

首个镜像服务商奖项公布!「Alinux 伙伴招募计划」最佳服务商名单来了

OpenAnolis小助手

镜像 操作系统 龙蜥社区 Alibaba Cloud Linux

中小型工厂应如何选择生产管理mes系统

万界星空科技

制造业 生产管理系统 mes 云mes 制造业工厂

中软协AI沙龙热议:智领云CEO彭锋解读AI大模型技术的应用前景与趋势

智领云科技

容器 AI大模型 大模型 中软协

微服务开发的10个最佳实践_云原生_Md Kamaruzzaman_InfoQ精选文章