NVIDIA 初创加速计划,免费加速您的创业启动 了解详情
写点什么

Shopify 是如何迁移到模块化单体架构的?

  • 2019-08-09
  • 本文字数:1323 字

    阅读完需:约 4 分钟

Shopify 是如何迁移到模块化单体架构的?

Shopify 高级工程师 Kirsten Westeinde 在 Shopify Unite 2019 大会上讨论了Shopify向模块化单体架构的演变。这包括使用设计收益线(design payoff line)来决定何时进行此更改,如何实现更改,以及为什么将微服务排除在目标架构之外。


一个关键的结论是,单体不一定是一个糟糕的架构,它具有许多优点,比如单个测试和部署管道。在项目开始时,当必须快速交付新特性时,这一点特别有用。只有在跨越了“设计收益线”时,也就是糟糕的设计阻碍特性开发的那一点,才应该开始改进架构。就 Shopify 而言,改进其架构并不意味着转向微服务,而是转向模块化单体架构。这结合了单体(例如单个测试和部署管道)和微服务(例如代码模块化和解耦)的优点。


Westeinde 认为,单体架构是一个很好的项目起点,他说:“其实,我建议新产品和新公司开始时使用单体架构。”她列举了其中的一些优点:


  • 一个项目包含所有代码;

  • 只有一个代码库,测试和部署都很简单;

  • 所有数据都可用,无需跨服务传递;

  • 一组基础设施。


由于这些优点,Shopify 一开始只是一个小型的 Ruby on Rails 单体,随着时间的推移,逐渐发展成为一个非常大的代码库。当这种情况发生时,它意味着 Shopify 开始变得不可维护,并且因此很难交付新特性。例如,更改一段代码会对看似无关的代码造成意想不到的副作用,并且构建和测试应用程序花费的时间太长。


Westeinde 援引 Martin Fowler 的设计耐力假说(design stamina hypothesis)解释说,是时候重构他们的架构了——一旦功能开发被糟糕的设计所阻碍,设计收益线就会被跨越,这意味着投入资源来修复它是有意义的。


最初,Shopify 将微服务视为一种可选的、更易于维护的架构。然而,由于分布式系统的复杂性,它被排除在外,取而代之的是更易于维护的单体架构:


我们意识到,我们喜欢单体所有的东西,代码都在一个地方,而且向一个地方部署。我们遇到的所有问题都是由代码中不同功能之间缺乏界限所直接导致的。


Westeinde 解释说,他们意识到他们的设计目标是提升系统的模块化,比如使用微服务,同时保持一个单一的可部署单元,像一个单体。为了实现这一点,Shopify 采用了模块化的单体模式。这使得代码之间有了边界,但要使代码都在同一个位置并且部署到同一个位置。迁移路径如下:


  • 代码重组:最初,代码的组织方式类似于典型的 Rails 应用程序,顶层部件以技术组件命名,如控制器。这被更改为基于业务功能进行组织,如“账单”和“订单”,从而更容易定位代码。

  • 隔离依赖关系:每个业务组件彼此隔离,然后通过公共 API 供外部使用。他们内部开发了一个名为 Wedge 的工具,它跟踪每个组件的隔离情况。它构建一个调用图,然后计算出哪些调用(比如跨组件的调用)违反了规则。

  • 强制边界:一旦每个组件都实现了 100%的隔离,它们之间就有了强制的边界。其思想是,当代码试图访问它没有显式依赖的组件的代码时,就会出现运行时错误。以这种方式声明依赖关系也将使它们在依赖关系图中可视化。


最后,Westeinde 解释说,这个例子很好地说明了架构如何根据业务需求发展:


良好的软件架构是一项不断演化的任务,而应用程序的恰当解决方案完全取决于你的操作规模。


完整的演讲可以在网上观看,也有相应的博客文章


原文链接:


How Shopify Migrated to a Modular Monolith


2019-08-09 08:002021
用户头像

发布了 690 篇内容, 共 399.7 次阅读, 收获喜欢 1498 次。

关注

评论

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

Js 异步处理演进,Callback=>Promise=>Observer

掘金安东尼

前端 异步 函数式 9月月更

测试驱动开发 (TDD) 在线练功房 | 12 月 17 日开课

ShineScrum捷行

Go 语言官方依赖注入工具 Wire 使用指北

Java-fenn

Java

Wallys/QCN9024/QCN9074/QCN6024 802.11ax 4x4 MU-MIMO 6GHz wifi6E//AR9582 2x 2 900M 802.11an

wallys-wifi6

QCN9074 QCN9024 QCN6024

小间距LED显示屏更受欢迎

Dylan

LED显示屏 led显示屏厂家

什么是跨域,后端工程师如何处理跨域

C++后台开发

后台开发 后端开发 跨域 C++开发 后端开发工程师

关于进阶这件事,这位 Python 大佬有话说

图灵社区

Python 程序员 进阶 计算机

【9.16-9.23】写作社区精彩技术博文回顾

InfoQ写作社区官方

优质创作周报

k8s 中 Pod 的深入了解

Java-fenn

Java

【建议收藏】17个XML布局小技巧

Java-fenn

Java

怎样体面地讲道理?

图灵教育

写作 表达 逻辑

揭秘 Jetpack Compose 快照系统 | 开发者说·DTalk

Java-fenn

Java

Kong重构了其事件通知机制

八苦-瞿昙

Event Gateway API Gateway

华为云GaussDB——打造金融行业坚实数据底座,共创数字金融新未来

Java-fenn

Java

智慧楼宇:东京建物引入“ZETA+AI”物联监测方案,实现楼宇预测性维护

ZETA开发者

人工智能 AWS 预测性维护 设备预测性维护 ZETA

关于进阶这件事,这位Python大佬有话说

图灵教育

Python 程序员 进阶 计算机

日系“怎样”系列新版升级,一本书讲透程序运行的方方面面

图灵社区

Python 程序员 C语言 计算机

聚焦金融行业未来,博睿数据亮相第五届中国银行CIO峰会

博睿数据

AIOPS 金融 银行 博睿数据 ONE平台

我所知道的webpack5那些不太一样的改变

Java-fenn

Java

工作笔记之 SELECT 语句在 SAP ABAP 中的用法总结(上)

宇宙之一粟

数据库 SAP abap select 9月月更

运维智能化的三大关键技术

穿过生命散发芬芳

9月月更 运维智能化

MyBatis批量插入几千条数据慎用foreach

Java-fenn

Java

J神出品!让 Compose 从此摆脱 ViewModel

Java-fenn

Java java;

软件测试 | 测试开发 | 该如何测客户端专项测试?

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

测试

GoLand 插件推荐

非晓为骁

插件 goland goland插件

图解 Kafka 源码实现机制之客户端缓存架构

Java-fenn

Java

怎样体面地讲道理?

图灵社区

写作 表达 逻辑

软件测试 | 测试开发 | 聊聊后端Web开发框架(Python)的简单使用

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

测试

CAT 认证敏捷团队教练工作坊 (Coaching Agile Teams) | 2023年1月 7 日开课

ShineScrum捷行

敏捷教练 专业教练

电商黄牛,你被小红书盯上了

小红书技术REDtech

算法 电商风控 黄牛治理

日系“怎样”系列新版升级,一本书讲透程序运行的方方面面

图灵教育

Python 程序员 C语言 计算机

Shopify 是如何迁移到模块化单体架构的?_架构_Andrew Morgan_InfoQ精选文章