微服务架构及其最重要的 10 个设计模式!
逆锋起笔
关注后回复编程pdf
微服务架构的设计模式
独享数据库(Database per Microservice)
数据由服务完全所有。
服务的开发团队之间耦合度降低。
服务间的数据共享变得更有挑战性。
在应用范围的保证 ACID 事务变得困难许多。
细心设计如何拆分单体数据库是一项极具挑战的任务。
在大型企业应用程序中。
当团队需要完全把控微服务以实现开发规模扩展和速度提升。
在小规模应用中。
如果是单个团队开发所有微服务。
微服务模式:独享数据库
https://microservices.io/patterns/data/database-per-service.html
分布式数据存储
https://docs.microsoft.com/en-us/dotnet/architecture/cloud-native/distributed-data
事件源(Event Sourcing)
为高可伸缩系统提供原子性操作。
自动记录实体变更历史,包括时序回溯功能。
松耦合和事件驱动的微服务。
从事件存储中读取实体成为新的挑战,通常需要额外的数据存储(CQRS 模式)。
系统整体复杂性增加了,通常需要领域驱动设计。
系统需要处理事件重复(幂等)或丢失。
变更事件结构成为新的挑战。
使用关系数据库的、高可伸缩的事务型系统。
使用 NoSQL 数据库的事务型系统。
弹性高可伸缩微服务架构。
典型的消息驱动或事件驱动系统(电子商务、预订和预约系统)。
使用 SQL 数据库的低可伸缩性事务型系统
在服务可以同步交换数据(例如,通过 API)的简单微服务架构中。
事件驱动
https://martinfowler.com/eaaDev/EventSourcing.html
事件驱动模式-云设计模式
https://docs.microsoft.com/en-us/azure/architecture/patterns/event-sourcing
微服务模式:事件驱动
https://microservices.io/patterns/data/event-sourcing.html
命令和查询职责分离(CQRS)
在事件驱动的微服务中数据读取速度更快。
数据的高可用性。
读写系统可独立扩展。
读数据存储是弱一致性的(最终一致性)。
整个系统的复杂性增加了,混乱的 CQRS 会显着危害整个项目。
在高可扩展的微服务架构中使用事件源。
在复杂领域模型中,读操作需要同时查询多个数据存储。
在读写操作负载差异明显的系统中。
在没有必要存储大量事件的微服务架构中,用事件存储快照来计算实体状态是一个更好的选择。
在读写操作负载相近的系统中。
写存储:EventStoreDB, Apache Kafka, Confluent Cloud, AWS Kinesis, Azure Event Hub, GCP Pub/Sub, Azure Cosmos DB, MongoDB, Cassandra. Amazon DynamoDB
读存储: Elastic Search, Solr, Cloud Spanner, Amazon Aurora, Azure Cosmos DB, Neo4j
框架: Lagom, Akka, Spring, akkatecture, Axon, Eventuate
bliki:CQRS
https://martinfowler.com/bliki/CQRS.html
CQRS模式 - Azure 架构中心
https://docs.microsoft.com/en-us/azure/architecture/patterns/cqrs
微服务模式:命令和查询职责分离(CQRS)
https://microservices.io/patterns/data/cqrs.html
Saga
事件编排 Choreography:分散协调,每个微服务生产并监听其他微服务的事件或消息然后决定是否执行某个动作。
命令编排 Orchestration:集中协调,由一个协调器告诉参与的微服务哪个本地事务需要执行。
为高可伸缩或松耦合的、事件驱动的微服务架构提供一致性事务。
为使用了不支持 2PC 的非关系数据库的微服务架构提供一致性事务。
需要处理瞬时故障,并且提供等幂性。
难以调试,而且复杂性随着微服务数量增加而增加。
在使用了事件源的高可伸缩、松耦合的微服务中。
在使用了分布式非关系数据库的系统中。
使用关系数据库的低可伸缩性事务型系统。
在服务间存在循环依赖的系统中。
Saga分布式事务-Azure设计模式
https://docs.microsoft.com/en-us/azure/architecture/reference-architectures/saga/saga
微服务模式:Sagas
https://microservices.io/patterns/data/saga.html
Saga 模式:微服务中的应用程序事务
https://blog.couchbase.com/saga-pattern-implement-business-transactions-using-microservices-part/
面向前端的后端 (BFF)
分离 BFF 之间的关注点,使得我们可以为具体的 UI 优化他们。
提供更高的安全性。
减少 UI 和下游微服务之间频繁的通信。
BFF 之间代码重复。
大量的 BFF 用于其他用户界面(例如,智能电视,Web,移动端,PC 桌面版)。
需要仔细的设计和实现,BFF 不应该包含任何业务逻辑,而应只包含特定客户端逻辑和行为。
如果应用程序有多个含不同 API 需求的 UI。
出于安全需要,UI 和下游微服务之间需要额外的层。
如果在 UI 开发中使用微前端。
如果应用程序虽有多个 UI,但使用的 API 相同。
如果核心微服务不是部署在 DMZ 网络中。
Sam Newman - 面向前端的后端
https://samnewman.io/patterns/architectural/bff/
面向前端的后端模式 - 云设计模式
https://docs.microsoft.com/en-us/azure/architecture/patterns/backends-for-frontends
微服务模式:API 网关模式
https://microservices.io/patterns/apigateway.html
API 网关
在前端和后端服务之间提供松耦合。
减少客户端和微服务之间的调用次数。
通过 SSL 终端、身份验证和授权实现高安全性。
集中管理的横切关注点,例如,日志记录和监视、节流、负载平衡。
可能导致微服务架构中的单点故障。
额外的网络调用带来的延迟增加。
如果不进行扩展,它们很容易成为整个企业应用的瓶颈。
额外的维护和开发费用。
在复杂的微服务架构中,它几乎是必须的。
在大型企业中,API 网关是中心化安全性和横切关注点的必要工具。
在安全和集中管理不是最优先要素的私人项目或小公司中。
如果微服务的数量相当少。
微服务模式:API 网关模式
https://microservices.io/patterns/apigateway.html
API 网关-Azure 架构中心
https://docs.microsoft.com/en-us/azure/architecture/microservices/design/gateway
Strangler
安全的迁移单体应用程序到微服务。
可以并行地迁移已有功能和开发新功能。
迁移过程可以更好把控节奏。
在现有的单体应用服务和新的微服务之间共享数据存储变得具有挑战性。
添加 Facade (API 网关)将增加系统延迟。
端到端测试变得困难。
将大型后端单体应用程序的增量迁移到微服务。
如果后端单体应用很小,那么全量替换会更好。
如果无法拦截客户端对遗留的单体应用程序的请求。
bliki:StranglerFig 应用程序
https://martinfowler.com/bliki/StranglerFigApplication.html
Strangler 模式 - 云设计模式
https://docs.microsoft.com/en-us/azure/architecture/patterns/strangler-fig
微服务模式:Strangler 应用程序
https://microservices.io/patterns/refactoring/strangler-application.html
断路器
关闭:断路器将请求路由到微服务,并统计给定时段内的故障数量,如果超过阈值,它就会触发并进入打开状态。
打开:来自微服务的请求会快速失败并返回异常。在超时后,断路器进入半开启状态。
半开:只有有限数量的微服务请求被允许通过并进行调用。如果这些请求成功,断路器将进入闭合状态。如果任何请求失败,断路器则会进入开启状态。
提高微服务架构的容错性和弹性。
阻止引发其他微服务的级联故障。
需要复杂的异常处理。
日志和监控。
应该支持人工复位。
在微服务间使用同步通信的紧耦合的微服务架构中。
如果微服务依赖多个其他微服务。
松耦合、事件驱动的微服务架构。
如果微服务不依赖于其他微服务。
bliki:断路器
https://martinfowler.com/bliki/CircuitBreaker.html
断路器模式 - 云设计模式
https://docs.microsoft.com/en-us/azure/architecture/patterns/circuit-breaker
微型服务模式:断路器
https://microservices.io/patterns/reliability/circuit-breaker.html
外部化配置
生产配置不属于代码库,因而最小化了安全漏洞。
修改配置参数不需要重新构建应用程序。
我们需要选择一个支持外部化配置的框架。
任何重要的生产应用程序都必须使用外部化配置。
在验证概念的开发中。
微服务模式:外部化配置
https://microservices.io/patterns/externalized-configuration.html
一次构建,到处运行:外部化你的配置
https://reflectoring.io/externalize-configuration/
消费端驱动的契约测试
如果提供程序意外更改 API 或消息,可以被快速的自动发现。
更少意外、更健壮,特别是包含大量微服务的企业应用程序。
改善团队自主性。
需要额外的工作来开发和集成微服务服务端的契约测试,因为他们可能使用完全不同的测试工具。
如果契约测试与真实服务情况不匹配,将可能导致生产故障。
在大型企业业务应用程序中,通常由不同的团队开发不同服务。
所有微服务由同一团队负责开发的小型简单的应用程序。
如果服务端微服务是相对稳定的,并且不处在活跃的开发状态。
需求驱动契约:一种服务演进模式
https://martinfowler.com/articles/consumerDrivenContracts.html
微服务模式:服务集成契约测试
https://microservices.io/patterns/testing/service-integration-contract-test.html
什么是消费端驱动的契约测试?
https://pactflow.io/what-is-consumer-driven-contract-testing/
总结
逆锋起笔
是一个专注于程序员圈子的技术平台,你可以收获最新技术动态
、最新内测资格
、BAT等大厂大佬的经验
、增长自身
、学习资料
、职业路线
、赚钱思维
,微信搜索逆锋起笔
关注!
项目实战 Spring Boot视频教程 微服务整合Mybatis