全文共3050字,预计学习时长8分钟
图源:unsplash
许多现代应用程序需要在企业级规模上构建,有时甚至需要在Internet规模上构建。每个应用程序都需要满足可扩展性、可用性、安全性、可靠性和弹性要求。
本文中笔者将讨论一些能够轻松实现上述功能的设计模式。笔者将讨论每种模式,如何在云原生环境中使用以及该何时使用。其中一些模式并不是那么新颖,但是在当前互联网规模的云世界中非常有用。
断路器
设计分布式系统时应考虑故障问题。现在全球已普遍采用了微服务,这些服务主要依赖于其他远程服务。由于网络、应用程序负载等各种原因,这些远程服务可能无法及时响应。在大多数情况下,重试能解决问题。
但有时可能会出现一些重大问题,例如服务降级或完全服务失败。在这种情况下继续重试毫无意义。这就是断路器模式发挥作用的地方。
上图展示了熔断是如何实现的,其中当服务1发现在调用服务2时存在连续的故障/超时,服务1不会重试,而是会将跳转到服务2并返回回退响应。流行的开源库,例如Netflix’s Hystrix,可以很容易地实现这种模式。如果您使用的是API网关或Envoy等Sidecar代理,则可以在代理级别本身实现。
注意,在电路断开时要进行足够的日志记录和警报,以便跟踪在此期间内收到的请求。这一点十分重要,操作团队应该意识到这一点。还可以在电路半开路状态下采用断路器模式,从而为服务质量下降的客户继续提供服务。
何时使用此模式:
· 当服务依赖于另一个远程服务,并且在某些情况下可能会失败时。
· 当服务具有很高的依赖性时(例如,主数据服务)。
何时不使用此模式:
· 处理本地依赖项时——断路器可能会增加开销。
命令查询职责分离模式(CQRS)
对于涉及数据存储的现代应用程序,CQRS是非常有用的模式。它基于将数据存储区中的读取(查询)和写入/更新(命令)操作分开的原则。
假设你正在构建一个应用程序,该应用程序需要将数据存储在MySQL / PostgreSQL等数据库中。众所周知,将数据写入数据存储区时,操作需要经过多个步骤——验证、建模和维持——因此,典型的写入/更新操作要比简单的读取操作花费更长的时间。
当你使用单个数据存储并同时执行大量读写操作时,可能会出现性能问题。在这种情况下,CQRS模式也许会大有用处。CQRS模式建议对读取和写入操作使用单独的数据存储。
如今大多数PaaS数据库都具有创建数据存储的只读副本(Google Cloud SQL,Azure SQL DB,Amazon RDS等)的能力,这有助于更轻松地实现CQRS。如果需要处理本地数据库,许多企业数据库也提供此功能。有些人还喜欢将只读副本实现为快速、高性能的NoSQL数据库,例如MongoDB和Elasticsearch。
何时使用此模式:
· 打算扩展一个需要大量读写的应用程序时。
· 想分别调整读写操作的性能时。
· 读取操作正常且接近实时或最终一致时。
何时不使用此模式:
· 在构建常规CRUD应用程序时,该应用程序一次不会进行大量读写操作。
事件溯源(Event Sourcing)
事件溯源是一种有趣的设计模式。其中一系列域事件被存储为日志,日志的聚合视图给出了应用程序的当前状态。此模式通常用于无法负担数据库锁且需要维护事件审核和历史记录的系统,例如,酒店/会议/座位预订之类的应用程序。
假设有一个酒店客房预订系统,用户需要在系统中预订或取消预订。这需要将预订和取消作为一系列事件进行存储。在每次预订之前,查看活动日志就能显示可订的房间。
大多数云服务提供商支持消息传递服务,如GooglePub/Sub、Azure Service Bus、AWS SQS等。这些服务结合了强大的一致数据库,可用于实现此模式。
何时使用此模式:
· 当常规CRUD操作不足以满足要求时。
· 通常适用于座位预订系统(如公共汽车、火车、会议、电影厅等)或由购物车、支付等活动组成的电子商务系统。
· 当创建应用程序的当前和过去状态,需要强大的审核和事件回放能力时。
何时不使用此模式:
· 当常规CRUD操作足以满足用户需求时。
绞杀者模式(Strangler)
如果想在组织中实现应用程序现代化,那么Strangler重写设计模式是必须的。Strangler设计模式主张在遗留部分和和新应用程序之上创建外观,为消费者提供抽象的视图。
这种模式使消费者与迁移活动脱钩。在典型的IT组织中,如果要从一个ERP迁移到另一个ERP,这种模式将非常有用。如果使用的是API网关,在网关代理本身中实现此功能则更加容易。你需要决定的是,在迁移结束时要保留该外观还是将其删除。
何时使用此模式:
· 在迁移或更新一个高依赖性的复杂应用程序时,例如ERP迁移。
何时不使用此模式:
· 若迁移简易,直接替换是更好的选择时。
随航模式(Sidecar)
随着微服务的兴起,Sidecar模式开始流行。这种模式将应用程序的组件部署到单独的进程或容器中。这有助于实现抽象和封装。
Envoy Proxy是最流行的Sidecar代理之一,被广泛使用。它通过使用Sidecar隔离网络、可观察性和安全性等常用功能,从而帮助你使应用程序的核心功能保持独立。
这种类型的Sidecar可以帮助抽象L4 / L7类型的通信。像Envoy Proxies这样的Sidecar甚至通过实现双向TLS来提高安全性。你可以将其与服务网格结合使用,以在各种微服务之间实现更好的通信和安全性。
何时使用此模式:
· 在产品范围内处理多种异构微服务时。
· 处理无法应对新时代的通信和安全挑战的传统应用程序时。
何时不使用此模式:
· 当处理有限数量的相互通信服务时。
· 小型应用,在这种应用中,sidecar部署可能不经济或不便于运营。
服务于前端的后端(BFF)
在典型的产品开发周期中,后端工程师负责创建与数据存储交互的服务,而前端工程师则负责构建用户界面。如今,应用程序的构建需要考虑到移动端和桌面端的使用情况。
尽管就硬件而言,移动设备和台式设备之间的差距越来越小;但对于移动设备而言,连接性和使用率仍然是挑战。在这种情况下,BFF模式变得非常方便,可以为特定的前端构建/自定义后端服务。
为了优化移动客户端的性能,需要构建一个以轻量级和分页式响应进行响应的单独后端服务。你可能还希望将此模式用于各种服务的聚合,以减少闲聊式的交流。
如果你使用的是API网关,则可以在网关本身中轻松实现BFF模式,而无需维护单独的服务。
何时使用此模式:
· 当需要为不同的客户端(例如台式机和移动客户端)提供产品/服务时。
· 当要针对特定类型的客户端优化响应时。
· 当希望减少移动客户端与各种服务之间的聊天通信时。
何时不使用此模式:
· 当应用程序用户应使用单个用户界面时。
· 移动和桌面应用程序将展示相似的信息并提供相似的功能时。
这些经典模式,你掌握了嘛?
推荐阅读专题
留言点赞发个朋友圈
我们一起分享AI学习与发展的干货
编译组:何婧璇、邓嘉玲
相关链接:
https://medium.com/better-programming/modern-day-architecture-design-patterns-for-software-professionals-9056ee1ed977
如转载,请后台留言,遵守转载规范
推荐文章阅读
长按识别二维码可添加关注
读芯君爱你