点击围观!腾讯 TAPD 助力金融行业研发提效、敏捷转型最佳实践! 了解详情
写点什么

面向软件专业人员的现代化架构设计模式

  • 2020-11-30
  • 本文字数:2867 字

    阅读完需:约 9 分钟

面向软件专业人员的现代化架构设计模式

许多现代应用程序需要在企业规模上构建,有时甚至需要在互联网规模上构建。每个应用程序都需要满足可伸缩性、可用性、安全性、可靠性和弹性要求。在本文中,我将讨论一些可以帮助你轻松实现上述功能的设计模式。我将讨论每种模式,如何在云原生环境中使用该模式,以及何时使用何时不使用。其中一些模式并不新鲜,但在当前互联网规模的云计算世界中非常有用。


本文最初发布于 BetterProgramming,经原作者授权由 InfoQ 中文站翻译并分享。


图片来自:https://undraw.co/


以下是本文将要讨论的模式:

  1. 断路器

  2. 命令和查询职责分离(CQRS)

  3. 事件源

  4. 挎斗

  5. BFF(Backend-for-Frontend)

  6. Strangler


让我们开始吧。

断路器

分布式系统的设计应该考虑故障。如今,世界已经接纳了微服务,而这些服务大多依赖于其他远程服务。由于网络、应用程序负载等各种原因,这些远程服务可能无法及时响应。在大多数情况下,实现重试应该就能够解决问题。


但有时候,可能会出现诸如服务降级或服务本身完全失败等重大问题。在这种情况下,不断地重试是没有意义的。这就用到断路器模式了。


断路器,图片由作者提供。


上图展示了断路器模式的实现,其中,当服务 1 识别出服务 2 被调用时存在连续故障/超时时,服务 1 将自动断开服务 2 的调用并返回回退响应,而不是重试。


有一些流行的开源库,比如Netflix的Hystrix,可以用来非常轻松地实现这种模式。


如果你正在使用 API 网关或像 Envoy 这样的挎斗代理,那么这可以在代理层本身实现。


注意:非常重要的一点是,在断开时,要实现足够的日志记录和告警,以便跟踪在此期间收到的请求,并让运营团队知道。


你还可以实现一个半开断路器,继续使用降级服务为客户端提供服务。

什么时候使用这种模式

  • 当一个服务依赖于另一个远程服务,而该服务在某些情况下可能会失败时;

  • 当服务具有非常高的依赖性时(例如,主数据服务)。

什么时候不使用这种模式


  • 当处理本地依赖时——断路器会带来开销。

命令和查询职责分离(CQRS)


对于涉及数据存储的现代应用程序来说,CQRS 是一种非常有用的模式,其基本原则是将数据存储中的读(查询)和写/更新(命令)操作分开。


假设你正在构建一个应用程序,它需要你将数据存储在 MySQL/PostgreSQL 等数据库中。众所周知,在将数据写入数据存储时,一个操作需要几个步骤——比如验证、建模和持久化——因此,典型的写/更新操作要比简单的读操作花费更长的时间。


当你使用单个数据存储同时执行大规模的读取和写入操作时,可能会开始遇到性能问题。


在这种情况下,CQRS 模式可能很有用。CQRS 模式建议对读和写操作使用不同的数据模型。该模式的一些变体还建议为这些模型使用单独的数据存储。

CQRS,图片由作者提供


注意:目前大多数 PaaS 数据库都提供了创建数据存储读副本(Google Cloud SQLAzure SQL DBAmazon RDS等)的能力,这让数据复制更容易实现。


如果你正在使用本地数据库,那么许多企业级数据库也提供了这种功能。


注意:现在有些人也喜欢将读副本实现为速度快和性能高的 NoSQL 数据库,像 MongoDB 和 Elasticsearch。

什么时候使用这种模式


  • 当你考虑扩展一个需要大量读写操作的应用程序时;

  • 当你希望分别对读和写操作进行性能调优时;

  • 当你的读操作可以接受近实时或最终一致时。

什么时候不使用这种模式


  • 当你构建一个常规的 CRUD 应用程序,而它不需要同时进行大量的读写操作时。

事件源


事件源是一种有趣的设计模式,它将一系列域事件存储为日志,日志的聚合视图提供应用程序的当前状态。


这种模式通常用于无法提供数据存储锁并且需要维护事件的审计和历史记录的系统——例如,酒店/会议/座位预订之类的应用程序。


事件源,图片由作者提供。


考虑用户预订或取消预订的酒店房间预订系统。在这里,你需要将预订和取消存储为一系列事件。在每次预订之前,聚合视图通过查看事件日志显示可用房间。


注意:大多数云服务提供商支持像谷歌 Pub/Sub、Azure 服务总线、AWS SQS 这样的消息传递服务。这些服务,结合强一致性数据存储,可实现此模式。

什么时候使用这种模式


  • 当常规的 CRUD 操作不足以满足需求时;

  • 通常适用于座位预订系统——如公交、火车、会议、电影院等——或包含购物车操作、付款等事件的电子商务系统;

  • 当需要通过强审计和事件回放以创建应用程的当前和历史状态时。

什么时候不使用这种模式


  • 当常规的 CRUD 操作足够满足用户的需求时。

挎斗


挎斗模式随着微服务的兴起而流行开来。在此模式中,应用程序的组件被部署到单独的流程或容器中。这有助于实现抽象和封装。


Envoy Proxy是最常用的挎斗代理之一,应用非常广泛。它有助于保持应用程序核心功能的独立性,使用挎斗来分离网络、可观察性和安全性等常见特性。


挎斗,图片由作者提供。


这种挎斗可以帮助抽象 L4/L7 层通信。像 Envoy Proxies 这样的挎斗甚至通过实现 Mutual TLS 来帮助实现更高的安全性。


你可以将其与服务网格结合使用,在各种微服务之间实现更好的通信和安全性。要想了解更多内容,可以阅读我之前的文章

什么时候使用这种模式


  • 当你在产品范围内面对多个异构微服务时;

  • 当你处理遗留应用程序时,这些应用程序通常无法应对新时代的通信和安全挑战。

什么时候不使用这种模式


  • 当你处理数量有限但需要相互通信的服务时;

  • 小型应用程序,在这种情况下,挎斗部署可能不经济或不便于运维。

BFF(Backend-for-Frontend)


在传统的产品开发周期中,后端工程师负责创建与数据存储交互的服务,前端工程师负责构建用户界面。现在,应用程序在构建时需要同时考虑到移动端和桌面端的使用。


尽管在硬件方面移动设备和桌面设备的差距越来越小,但对于移动设备而言,连接和使用仍然是其面临的挑战。


在这种情况下,BFF 模式变得非常方便。在这种模式下,你需要为特定的前端构建/定制后端服务。


Backend-for-Frontend,图片由作者提供。


为了优化移动客户端的性能,你可能需要构建一个单独的后端服务,它使用轻量级的分页响应进行应答。


你可能还希望将此模式用于各种服务的聚合,以减少通信量。


注意:如果你现在使用了 API 网关,那么 BFF 模式可以很容易地在网关中实现,你不需要维护单独的服务。

什么时候使用这种模式


  • 当你想为不同的客户端(比如桌面和移动客户端)提供产品/服务时;

  • 当你想为特定类型的客户端优化响应时;

  • 当你想减少移动客户端和各种服务之间的通信时。

什么时候不使用这种模式


  • 当应用程序用户希望使用单个用户界面时;

  • 当移动和桌面应用程序需要展示相似的信息并提供相似的功能。

Strangler


如果你所在的组织正在走向应用程序现代化,则必须使用 Strangler 设计模式。Strangler 设计模式主张在遗留应用程序和新应用程序之上创建一个 Facade,为用户提供一个抽象的视图。

Strangler,图片由作者提供。


此模式将用户与迁移活动解耦。


注意:在传统的 IT 组织中,如果要从一个 ERP 迁移到另一个 ERP,这种模式会非常有用。如果你使用的是 API 网关,那么在网关代理中实现它就更容易了。


你需要决定是在迁移结束时保留 Facade 还是删除它。

什么时候使用这种模式


  • 当你迁移或更新一个复杂的、依赖度高的应用程序(如 ERP 迁移)时。

什么时候不使用这种模式


  • 如果迁移很简单,那么直接替换是更好的选择。


英文原文链接:Modern-Day Architecture Design Patterns for Software Professionals

2020-11-30 12:002586
用户头像
蔡芳芳 InfoQ主编

发布了 737 篇内容, 共 426.0 次阅读, 收获喜欢 2627 次。

关注

评论

发布
暂无评论
发现更多内容

QEMU线程模型

Linux内核拾遗

线程模型 Linux Kenel 虚拟化 qemu kvm

区分List中 remove(index)/remove(Object)

Joseph295

SQLChat 的 RBAC 之旅

天黑黑

AI sql 数据库· ChatGPT

Mac高质量图像浏览处理:GraphicConverter 12中文版

魔仙苹果mac堡

图片浏览软件Mac版 GraphicConverter 12 GraphicConverter中文版

在报告原型或早期个人版本的程序错误之前,要先征得同意

测吧(北京)科技有限公司

测试

JS引擎(2):Java平台上JavaScript引擎—Rhino/Nashorn概述

zhoulujun

JavaScript引擎 Nashorn Rhino

JetBrains AppCode 2023 for Mac(高效iOS代码编写工具) v2023.1中文特别版

魔仙苹果mac堡

AppCode 2023 AppCode中文 AppCode 2023破解 Mac版iOS开发

推荐算法在商城系统实践

越长大越悲伤

推荐系统 推荐算法 #java

不要强求100%的自动化

测吧(北京)科技有限公司

测试

JS引擎(1):JS引擎擂台赛,JavaScript引擎的特征比较及术语科普

zhoulujun

JavaScript JavaScript引擎 引擎擂台赛

post-css/less/sass样式嵌套与命令之"&"符号—BEM

zhoulujun

less SASS bem post-css

LeetCode 精粹

Joseph295

【异常解决】postman请求提示Full authentication is required to access this resource

No8g攻城狮

测试 Postman

工赋开发者社区 | MES与ERP/APS/PLM等的系统集成技术

工赋开发者社区

深度学习基础入门篇[三]:优化策略梯度下降算法:SGD、MBGD、Momentum、Adam、AdamW

汀丶

人工智能 机器学习 深度学习 梯度下降算法

AICopy探狐文案 for Mac(写作笔记改写和论文翻译查重)中文版

魔仙苹果mac堡

论文撰写 AICopy探狐文案 论文查重 Mac写作笔记软件

css过去及未来展望—分析css演进及排版布局的考量

zhoulujun

CSS

chrome对页面重绘和回流以及优化进行优化

zhoulujun

chrome 重绘 回流

JS引擎(0):JavaScript引擎群雄演义—起底JavaScript引擎

zhoulujun

JavaScript mocha JavaScript引擎 SpiderMonkey Nashorn

浏览器史话中chrome霸主地位的奠定与国产浏览器的割据混战

zhoulujun

chrome 浏览器霸主 国产浏览器

浏览器层面优化前端性能(2):Reader引擎线程与模块分析优化点

zhoulujun

前端性能 Reader引擎线程

性能最快的代码分析工具,Ruff 正在席卷 Python 圈!

Python猫

Python

差的自动化测试的问题是没有人注意

测吧(北京)科技有限公司

测试

Vue3 Transition 踩坑记

控心つcrazy

踩坑 Vue 踩坑经历 vue cli VUE 3.0 源码解析

Go 语言切片是如何扩容的?

AlwaysBeta

Go 源码 面试题 切片

保持住你写代码的姿势,你就是黑带了

Bruce Talk

敏捷开发 TDD Agile

Infuse for Mac(多媒体播放器)v7.5.1激活版

魔仙苹果mac堡

Infuse下载 苹果视频播放器 Mac版Infuse下载 Infuse 中文

【Spring专题】「技术原理」从源码角度去深入分析关于Spring的异常处理ExceptionHandler的实现原理

洛神灬殇

spring 源码分析 4月日更 ExceptionHandler 异常处理器

如何为基于规格说明的测试创建可跟踪性矩阵

测吧(北京)科技有限公司

测试

软件测试捕获回放失败

测吧(北京)科技有限公司

测试

软件测试 | 可测试性是可视性和控制

测吧(北京)科技有限公司

测试

面向软件专业人员的现代化架构设计模式_云计算_Tanmay Deshpande_InfoQ精选文章