2月5-7日QCon全球软件开发大会携手100+位大咖讲师落定北京,点击查看完整日程>> 了解详情
写点什么

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

  • 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:002535
用户头像
蔡芳芳 InfoQ主编

发布了 722 篇内容, 共 406.0 次阅读, 收获喜欢 2591 次。

关注

评论

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

架构实战营模块6作业

技术是伙伴

架构实战营

认认真真的聊聊"软"中断

编程 架构 后端 计算机

基于Netty,20分钟手撸一个RPC框架

码农参上

netty 8月日更

☕【Java技术指南】「TestNG专题」单元测试框架之TestNG使用教程指南(下)

洛神灬殇

Java JUnit 8月日更 testNG

架构实战营模块 6 作业指导

华仔

#架构实战营

模块六作业

俊杰

架构实战营

华为18级工程师耗时三年才总结出这份Java亿级高并发核心编程手册

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

新书介绍 -- 《Redis核心原理与实践》

binecy

redis cluster 书籍 redis sentinel Redis Stream

教你一招疯狂拿Offer!用微服务设计一个超大型分布式电商平台

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

我说想去京东面架构师,阿里表哥手甩我Java大厂技术题,让我滚蛋

Java~~~

Java spring 架构 面试 Spring Cloud

GitHub程序调优「黑马」!阿里大牛的Java性能优化实战笔记已上线

Java~~~

Java 架构 面试 JVM 性能调优

爱了!阿里巴巴内部出品“SpringBoot+微服务指南”,理论与实战

Java~~~

Java spring 架构 面试 微服务

阿里二面:怎么解决MySQL死锁问题的?

Java MySQL 架构 面试 后端

业界良心啊!第五次更新的Spring Cloud Alibaba升级太多内容

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

阿里P8整理的《百亿级并发系统设计》实战教程,实在是太香了

Java 架构 后端 高并发

Golang:并发操作中常见的读写锁

Regan Yue

读写锁 Go 语言 8月日更

Vue进阶(八十二):updated 应用详解

No Silver Bullet

Vue 8月日更

清华毕业20年从业经验马士兵建议所有Java高工必看的高并发编程

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

八位阿里大牛耗时三年总结出Java面试复盘手册!带你实现逆风翻盘

公众号_愿天堂没有BUG

Java 编程 程序员 架构 面试

面试进阶双飞!Alibaba新产SpringBoot深度历险(嵩山版)开源

Java~~~

Java spring 架构 面试 JVM

无意发现,某东买来的Redis核心实践PDF,竟在GitHub数据库榜第一

Java~~~

Java redis 架构 面试 架构师

关于我尝试抓包微信失败后想到的新方法居然和奥特曼有关~

4ye

Python TCP 爬虫 后端 8月日更

架构实战营 - 模块六作业

思梦乐

详解Java方法句柄MethodHandle

Java 方法句柄

Scrum Patterns:持续改进脉冲(Kaizen Pulse)(译)

Bruce Talk

敏捷开发 译文 Agile Scrum Patterns

PM2实用指南及容器Docker部署

devpoint

Docker Node 8月日更

系统对接阿里云短信接口(Java开发实践)

Python研究者

8月日更

难以置信!阿里新产微服务架构进阶笔记我粉了!理论实战齐飞

Java 编程 架构 面试 架构师

难以置信!网易首席架构师竟用了500页笔记,把网络协议给趣谈了

Java~~~

Java 架构 面试 TCP 网络

集字节大神面试经验诚意出品:微服务(耀世版),助你向大厂迈进

Java~~~

Java 架构 面试 分布式 微服务

架构实战营 - 模块六作业

Julian Chu

架构实战营

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