腾讯亿级用户规模自研业务的上云实践解读,立即报名 了解详情
写点什么

从微服务开始 vs 不从微服务开始

  • 2021-11-05
  • 本文字数:3382 字

    阅读完需:约 11 分钟

从微服务开始 vs 不从微服务开始

本文最初发表于 Medium 博客,经原作者 Chris 授权,InfoQ 中文站翻译并分享。


本文的题目看似自相矛盾,实则不然。


我想讲两个故事。一个是不从微服务开始,一个是从微服务开始。我认为,通过观察事物的两面,我们将对微服务的实际好处有更多的了解。


闲话少叙,言归正题。

不从微服务开始


假设你正在一个大型电子商务平台上工作。和所有电子商务平台一样,都有一个产品列表页面,显示所有的产品。同时,也有一个处理购物车和结账流程的结账页面。




很久以前,这家公司的 CTO,John 读到了关于微服务方面的一些内容。他觉得微服务是个好主意。于是,他决定创建一个微服务来管理产品列表域和购物车域。


微服务架构允许 John 拥有一个产品清单团队和一个结账团队。他们有各自的业务目标、指标、KPI、SLA 等等。这两个团队都是跨职能的团队,负责产品列表面以及端到端的结账流程。


他们每一个人都可以随心所欲地做他们想做的任何事。举例来说,结账团队可以实施他们自己的 AB 测试,并在上面设置多个本地化和一个漂亮的节日主题。产品团队可以专注于通过建议相关项目来优化产品列表。他们可以把精力集中在自己的领域,而不必担心会对其他领域做出破坏性的改变,只需保持域间 API 通信的向后兼容性。


此外,我们还可以对系统进行扩展。假设我们周五有一个大型促销活动,客户将会看到更多的产品和促销活动。在需要一个大点的结账页面的同时,我们可能需要更大的产品列表后端。


完美听起来不错。生活美好!


第二年,CEO Jane 想要搞一个促销活动。Jane 也从一些研究中发现,如果在登陆页面和结账流程中展示相关的产品,能够显著提高销售额。




存在着特定的定价方案、相关性(消费者购买大量 IT 相关产品在 IT 产品上会获得更多折扣)和客户特权等级。这些应该由产品列表团队进行管理,因为他们已经进行了大量关于如何显示吸引人的产品的研究。此外,产品列表团队也知道如何用吸引人的方式来展示产品。他们很清楚什么颜色、字体、图像大小和边距能够产生最佳的转换率。


不过,改变将会很艰难。


因为结账流程和产品页面的前端和后端都属于不同的微服务,因此需要两个团队共享代码、设计、逻辑等。能够进行简单的复制粘贴,我们可以创建一个共享库,并且可以公开某种 API。


尽管它们在技术上都是可能的,但是在这种微服务架构中执行这种类型的改变需要比单体架构更加复杂。


那么如果我们需要迭代设计、数据和推广中的所有东西呢?每次迭代的每一个改变都必须反映在结账页面和产品列表页面上。假如我们做得不够好,我们就需要把所有的工作翻倍,或者在这两个团队之间一次又一次地将 API 重新设计。


使用微服务架构后,我们就可以在很大程度上使 服务内部的任何改变变得更容易,并使跨服务的改变更加困难。



因为人类并不擅长预测未来,所以我们永远不应该从微服务开始。我们不知道 6~12 个月后会有什么业务。不管我们怎样拆分微服务,它都有可能是错误的。


让我们永远不要从微服务开始。

从微服务开始


让我们倒回去,看看事情的发展会有什么不同。


这家公司的 CTO,John 读到了关于微服务方面的内容。John 认为这微服务是个灾难性的想法。微服务在技术上所解决的所有问题都可以用单体来完成,那么为什么要把分布式部分加入到方程中呢?我们的大多数程序员都会受到分布式计算谬误的影响。


John 坚持使用单体架构。


John 有一个由 30 名开发者组成的团队。按照这个规模,John 是无法审查他那庞大的单体的每一个改变的。因此他偶尔会检查一下代码。


该公司走了了相反的方向。他们希望实现一个单一的“立即购买”(Buy Now!)按钮,它基本上是一个单步结账。



由于这明显位于产品列表页面,因此利益相关者要求产品列表团队来开发。其中一个开发者看了这个需求。他们认为,既然这个页面都是关于产品的,我们应该像这样在一个产品类中实现它。


class Product {    public void CheckoutWithOneClick() {      this.PaymentService.Pay(this.Price);    }}
复制代码


在经验丰富的开发者看来,这是一种非常非常强烈的代码异味。不知何故,它通过了代码审查,被签入(check in)并成为单体的主要部分。


六个月之后,所有结账相关的事情都变得非常难以实现,而且漏洞百出。如果我们希望应用促销代码,我们需要记住在产品类别中实现了一键结账。如果我们希望为一个特殊类别的客户提供折扣,我们也需要记住这一点。在许多情况下,结账团队被要求实现一些复杂的结账方案,但这和这种一键按钮的效果并不理想。


特性开发、错误修复以及所有与结账流程相关的内容都是单独实施的。由于产品团队拥有 Product 类,而结账团队拥有 CheckoutService,每个团队对需求的解释各不相同,业务逻辑的实现也各不相同。一种方法是首先检查促销代码,另一种方法是检查客户特权,等等。


当 John 一旦看到这一切的时候,就太迟了。CheckoutWithOneClick 与常规结账流程之间存在许多代码重复和独立的逻辑分支。要重构这段代码需要大量的投资。


在某个时候,John 被解雇了,而 Jane 聘请了一名新的 CTO。


Jane 问的第一个问题是:为什么我们在结账流程中做任何事情都这么难?


新 CTO:嗯,一键结账和普通结账有不同的逻辑实现。这样就很难在结账流程中做任何事。


Jane :怎么会这样?


团队中的随机工程师:每个人都知道这件事。它由一位开发者开发,他决定为一键签入提供单独的逻辑。那太糟糕了,但我不知道 John 怎么能做得更好。他不可能检查每一段代码。


新 CTO:好吧, John 应该从微服务开始。这样的话,产品列表团队将不会想到这样的设计。他们会被结账团队的服务所有权所阻止。

微服务的价值


嗯, John 处于一个奇怪的境地。如果他使用微服务,就会有厄运;但如果他不使用微服务,也会有厄运。


因为微服务在本质上讲是一种管理工具。


微服务可阻止某些类型的改变,并且使得某些类型的改变更加容易。


在第一个故事中,微服务架构阻止了所需的改变。在第二个故事中,由于缺乏微服务架构,导致了一系列不希望出现的改变。


这就是为什么 John 无论如何都注定要失败。问题不在于单体与微服务。而是问题在于架构选择与业务的增长不一致。


你可以争辩说,在第二个故事中, John 可以更加努力工作,确保所有的代码都经过了设计审查和整个审计等等。但这才是重点。这种管理方案的成本可能会很高,并在开发过程中会增加大量的开销。


微服务能够降低这一成本,因为它本身很难让设计混乱,所以我们不需要所有这些繁重的流程。但当我们真的想要把这个设计搞得乱七八糟的时候,好的,你已经从第一个故事里学到了。


最后,架构必须与业务增长保持一致。这就是我要讲的全部。


在使用微服务时,你会让某些增长变得更加容易,同时也会让某些类型的增长更加困难。


如果你有一个结账的微服务,结账团队就能更快地推出新功能。他们自己可以发布,能够使用自己喜欢的编程语言,不依赖其他团队,能够独立管理其服务的可扩展性。


这就是我认为的,微服务架构的核心优势。


微服务的每一个技术方面,例如独立扩展系统的某些部分或使用多语言实现,都可以用单体来解决。你可以使用一个构建,并将其配置为某些容器打开特定的端点,然后你就可以独立地扩展系统的某一部分了。


你可以在操作系统级别上使用跨进程通信,并管理二进制分布,这样就能用多语言实现了。也许延迟比网络更好。


单体不能解决的问题在于,当你希望拥有某种类型的管理结构,并且通过给予自主权和频繁的独立发布周期,从而激励某个领域的发展和创造力。这就是在单体架构中,真的非常难以做到的。


所以我想说的是微服务实施的决定性因素。它是否与你的组织想要发展的方式相一致?


由于类似地,微服务从本质上说是对管理问题的一种技术解决方案。这个问题确实存在,需要很好的解决方案。


如果你觉得这是个愚蠢的管理问题,那么我会邀请你来解决它。如果你能以可扩展和可重复的方式解决“如何使程序员有效协作?”这样一个简单的问题,我相信你有可能比杰夫·贝佐斯(Jeff Bezos)更富有。


亚马逊(Amazon)一直在做这方面的工作。谷歌、Facebook 也一直在做这个工作。现有的每一家巨无霸科技公司都已经在这方面工作了几十年,并提出了多个独立的服务产品(后来工业化成为微服务)。


如果你有更好的答案,那么请继续,让我和所有这些人知道。他们已经准备好投资了。


作者介绍:


Chris,专门从事编程的产品开发者。坚信人文主义。


原文链接:


https://medium.com/chris-dialogue/start-with-microservices-dont-start-with-microservices-db6cff6adb90

2021-11-05 10:343179

评论 2 条评论

发布
用户头像
第一个案例,结账和产品的前端应该合并,结账和产品微服务只提供数据。而前端团队负责数据整合,这样是否对?
2021-11-05 15:31
回复
我觉得是给用户看到的金额是前端计算得来的,实际支付的金额是后端计算得来的
2021-11-15 09:50
回复
没有更多了
发现更多内容

科创人·酷渲科技创始人华少:用双赢思维做产品、连生态,实现规模化发展

科创人

个推CTO趣谈元宇宙:从概念、成因到核心技术

个推

数据智能 元宇宙

系统困境与软件复杂度,为什么我们的系统会如此复杂

阿里巴巴终端技术

软件 系统设计 软件开发

云安全是什么样子的?其工作原理是什么?

wljslmz

云安全 6月月更

图搜的应用场景

Geek_e369a5

图像检测 图像搜索 图搜的应用场景

鲲鹏云开发者分论坛:发挥鲲鹏的潜力,加速云上创新

科技热闻

Vue-12-条件渲染(可重复元素)

Python研究所

6月月更

【LeetCode】多个数组求交集Java题解

Albert

LeetCode 6月月更

编程技巧│浏览器 Notification 桌面推送通知

极客飞兔

可视化 6月月更 Notification 实时通知

网络安全实战从0到1彻底掌握XXE

网络安全学海

黑客 网络安全 安全 渗透测试 WEB安全

BI与SaaS碰撞,让数据处理更加轻松(下)

葡萄城技术团队

数据分析 SaaS BI

易观分析《计算机视觉市场研究,2022》研究报告正式启动

易观分析

人工智能

探索质量外延 - 质量安全故事

QualityFocus

质量管理 软件质量与安全

IntelliJ IDEA常见快捷键

龙空白白

IntelliJ IDEA

科创人·数智未来私董会第4期:转型的实证-幸存者偏差与盲人摸象

科创人

智慧园区效果不满意?请收下ThingJS这份秘籍

森友小锘

智慧园区 数字孪生

JMeter集成底座项目压测心得

agileai

压力测试 集成底座 企业服务总线 统一身份管理平台 主数据管理平台

2023年广州美博会-2023年春季广州美博会

展览通

美博会 2023年广州美博会 春季广州美博会 3月份广州美博会

java就业培训 | 面试官如何判断应聘者能力的,这一篇就够了

@零度

JAVA开发

Mysql数据库查询好慢,除了索引,还能因为什么?

C++后台开发

MySQL 数据库 中间件 后端开发 C++后台开发

Linux系统与Windows系统之间的文件上传与下载

龙空白白

Linux Windows系统

特定MPC问题包含哪些常见技术,有什么作用,什么场景需要用到?

数牍科技

隐私计算 安全多方计算 特定mpc问题

帮助中心应该怎样设计?

小炮

InfoQ 极客传媒 15 周年庆征文|跨平台应用开发进阶(二十二) :uni-app Android APP上线准备工作汇总

No Silver Bullet

前端 签名 安全检测 6月月更 InfoQ极客传媒15周年庆

5月券商App行情刷新及交易体验评测报告,四家券商综合评级上升

博睿数据

智能运维 博睿数据 券商排行

阿里云CIPU下笔惊雷,方寸间书写中国算力故事

脑极体

转转统一权限系统的设计与实现(前端实现篇)

转转技术团队

前端开发 umijs 权限设计

个推TechDay直播预告 | 6月22日,开启大数据降本提效的破局之道!

个推

大数据 分布式计算 分布式存储 标签

web前端培训如何提高React界面性能

@零度

前端开发 React

【6.10-6.16】写作社区精彩技术博文回顾

InfoQ写作社区官方

优质创作周报

java程序员培训 | 10年后程序员的薪资会怎么样

@零度

JAVA开发

从微服务开始 vs 不从微服务开始_架构_Chris_InfoQ精选文章