找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

2843

积分

0

好友

379

主题
发表于 昨天 08:24 | 查看: 4| 回复: 0

你正在启动一个新项目,并且已经了解Netflix、亚马逊和Uber如何使用微服务来处理数百万个请求。

你想从一开始就构建一个可扩展的系统。因此,你开始设计系统,为用户、订单、支付、通知和库存分别构建独立的服务。每个服务都有自己的数据库、部署流程和监控机制。

六个月后,你拥有15项服务,一个由3名开发人员组成的团队,但你80%的时间都花在调试分布式系统问题上,而非功能开发。这就是微服务陷阱,而且它比你想象得更容易让团队掉进去。

本文将解释:

  • 为何微服务对新项目而言诱人但又充满风险
  • 无人提及的隐性成本
  • 微服务真正发挥作用的时机
  • “单体优先”方法及其有效性
  • 为什么微服务在系统设计面试中很重要

一、微服务热潮

微服务不仅听起来极具吸引力,在系统设计面试中也往往能成为加分项,给面试官留下深刻印象。能够独立开发、部署和扩展的小型独立服务的想法,听起来就像是工程领域的理想境界。

Microservices Architecture 示意图:三个独立服务 User Service, Order Service, Payment Service 分别连接各自的数据库 User DB, Order DB, Payment DB

当你阅读有关微服务的资料时,你会了解到:

  • 独立部署:部署一项服务而不影响其他服务;
  • 技术灵活性:针对每项服务使用最合适的语言或者框架;
  • 团队自主性:小型团队对其服务拥有端到端的所有权;
  • 可扩展性:仅扩展需要扩展的服务;
  • 故障隔离:一项服务故障不会导致系统崩溃。

这些好处确实存在,但也伴随着陷阱。这些优势只有在流量和团队都达到一定规模时才能显现。对于初创公司或小型团队而言,微服务不仅无法提供这些好处,反而会适得其反。

让我来解释一下原因。

二、微服务的隐性成本

1、分布式系统复杂性

当你把应用程序拆分成多个服务时,就创建了一个分布式系统,而分布式系统很难构建。原本在单一环境中不存在的问题,如今变成了你的日常挑战:

  • 网络故障:服务A无法连接到服务B,现在该怎么办?
  • 延迟:原本只需几微秒的函数调用,现在变成了需要几毫秒的网络调用。
  • 数据一致性:如何维护多个数据库中的数据一致性?
  • 调试噩梦:一个请求可能涉及10个服务。

祝你好运,希望你能追踪到这个错误。

在单体架构中,调用函数要么保证成功,要么保证抛出异常。在微服务架构中,服务调用可以:

  • 成功;
  • 失败并出现错误;
  • 超时(但它真的成功了吗?);
  • 成功但返回的数据已过时;
  • 重试成功,但导致重复操作。

每种情况都需要不同的处理方法,而这样的处理要覆盖到系统内的每一次服务间调用

那调试方面呢?

在单体架构中,你会得到堆栈跟踪信息。在微服务架构中,单个用户请求可能会调用10个不同的服务。当出现问题时,需要追踪所有服务的日志,关联时间戳,并找出导致故障的服务。

但分布式复杂性仅仅只是开始,你究竟该如何管理所有这些服务呢?

2、运营费用

单体架构意味着只需部署、监控和维护一个系统。有了微服务,一切都成倍增长:

单体与10+微服务架构对比表格:展示部署管道、需管理的数据库/服务、日志聚合复杂度、API版本维护难度等指标

你还需要一些单体架构不需要的额外基础设施:

  • 服务发现:服务之间如何相互发现?
  • API网关:外部客户端如何访问你的服务?
  • 分布式追踪:如何跨服务进行调试?
  • 断路器:如何处理级联故障?
  • 消息队列:服务如何进行异步通信?

这些因素都会增加复杂性、成本和潜在的故障点。一个小团队在基础设施管理上耗费的时间往往比在功能开发上更多。

说到性能成本,我们来看看应用程序的速度会发生什么变化。

3、网络现在是你的瓶颈

在单体架构中,数据访问速度很快(约1微秒)。对象要么存储在内存中,要么只需一次数据库调用即可访问。

在微服务中,曾经的方法调用现在变成了:

1. Serialize request to JSON           ~0.5ms
2. DNS lookup                          ~1-10ms
3. TCP connection                      ~1-5ms
4. TLS handshake                       ~5-30ms
5. Send HTTP request                   ~1-5ms
6. Service B processes                 ~varies
7. Serialize response                  ~0.5ms
8. Network transfer back               ~1-5ms
9. Deserialize response                ~0.5ms

Time: 10-50+ milliseconds (10,000x slower!)

这种开销会迅速累积,原本只需要5次内部方法调用的单体应用页面,现在可能需要5次网络调用,每次调用都会增加10-50毫秒的延迟。

4、数据管理变成一场噩梦

微服务的优势之一是每个服务都拥有独立的数据,但同时带来严峻的挑战。

1)连接问题

在单体架构中,你可以轻松地通过单个SQL查询将用户、订单和产品关联起来:

SELECT u.name, o.total, p.title
FROM users u
JOIN orders o ON u.id = o.user_id
JOIN order_items oi ON o.id = oi.order_id
JOIN products p ON oi.product_id = p.id
WHERE u.id = 123;

在微服务架构中,相同的数据存储在不同的数据库中:

微服务数据流图:Application 分别调用 User Service, Order Service, Product Service,每个服务连接其独立数据库

要获取用户、订单和产品信息,你需要:

  • 致电用户服务
  • 致电订单服务
  • 致电产品服务部
  • 在应用程序代码中合并数据

2)交易问题

在单体架构中,可以将多个操作封装在一个数据库事务中:

单体架构下 ACID 事务示例代码:在一个事务中执行扣库存、扣款、创建订单三个操作

在微服务架构中,每个服务都有独立的数据库,事务无法跨多个服务运行。因此,需要采用分布式事务或Saga模式,但这两种模式都很复杂且容易出错。

5、测试难度呈指数级增长

测试单体应用很简单:启动应用程序,运行测试。微服务测试需要多个环节:

  • 服务之间的合同测试
  • 启动多个服务的集成测试
  • 对整个系统进行端到端测试
  • 利用混沌工程验证容错性。

你的 CI/CD 流水线会变成一个复杂的编排流程,需要按正确的顺序构建、部署和测试多个服务,对共享API的任何更改都需要更新和测试所有依赖服务。

6、你还不了解你的领域

这或许是最重要的一点。在启动新项目时,你可能对你的领域并不完全了解。 需求会发生变化,你会发现那些原本以为相互独立的问题,实际上存在紧密的内在关联。

在单体架构中,重构主要指代代码包间的迁移。而在微服务架构中,重构是指重新设计API、迁移数据以及协调跨团队的部署。

马丁·福勒称之为 “单体优先” 方法:

“几乎所有成功的微服务案例都是从过于庞大的单体应用开始,然后被拆分的。”
——马丁·福勒

项目初期采用微服务,意味着你要在尚未明确服务边界的前提下强行划分,而错误的边界划分会带来极其高昂的修复成本。

那么,微服务究竟在什么情况下才真正有意义呢?

三、微服务何时真正适用

微服务本身并无不妥,它是针对大多数项目所缺乏的特定问题而提出的解决方案。考虑采用微服务时,你需要有:

1、多个需要独立运作的团队

如果你有50多个开发人员,且在单体架构中频繁产生协作冲突时,微服务可以有效保障团队自主权。

经验法则:要让微服务在组织架构中合理运作,每个服务至少需要一个团队(5-8 名开发人员)。

2、不同的扩展需求

Traffic Distribution:
Search Service    ████████████████████████████████ 90%
User Service      ███                                8%
Admin Service     █                                  2%

如果90%的流量流向搜索服务,而用户服务只占10%,并且需要支付更高的费用才能将所有内容扩展时,采用微服务架构或许能成为解决方案。

但请扪心自问:你的公司真的存在这个问题吗?还是说一个优化过的单体架构就能解决所有问题?

3、清晰、稳定的领域边界

如果你的单体架构已经运行多年,并且清楚地了解系统中哪些部分是独立的,很少同时发生变化,便可放心地进行服务拆分。

4、基础设施和专业技术

微服务正常运行需要成熟的基础设施:

  • 成熟的 CI/CD 管道
  • 容器编排(Kubernetes 或类似平台)
  • 服务网格或 API 网关
  • 分布式追踪和日志记录
  • 多个部门的轮值待命

如果缺乏这些条件,你会把更多时间耗费在基础设施建设上,而非功能开发。

四、单体优先方法

以下是推荐的做法:

1、从结构良好的整体式系统开始

构建单体架构,但要确保内部结构合理。采用清晰的模块边界,分离关注点,并在组件之间编写简洁的接口。

my-app/
├── modules/
│   ├── users/
│   │   ├── api/
│   │   ├── service/
│   │   └── repository/
│   ├── orders/
│   │   ├── api/
│   │   ├── service/
│   │   └── repository/
│   └── products/
│       ├── api/
│       ├── service/
│       └── repository/
├── shared/
└── infrastructure/

这有时被称为 “模块化单体”

2、明确内部界限

即使在单体架构中,模块之间也应该通过明确定义的接口进行通信。不要让订单模块直接访问用户数据库表,而应该让它调用用户模块的公共接口。

代码示例对比:错误做法(直接跨模块查询数据库)与正确做法(通过模块接口访问)

这样既能简化当前的开发过程,又能方便以后的拆分工作。

3、当痛苦真正来临时,拆分服务

只有当遇到微服务能够解决的实际痛点时,再考虑拆分服务:

  • “我们无法部署,因为另一个团队正在使用相同的代码库。”
  • “我们需要将这个组件的规模扩大100倍,但其他组件不需要这样做。”
  • “这个组件需要不同的技术栈”
  • “由于代码库非常庞大,部署需要2个小时。”

当提取数据时,你已经明确领域,边界已经确定,并且有实际的需求作为指引。

五、真实案例

一些最成功的科技公司最初都是从单体架构起家的:

亚马逊

亚马逊在转型为服务型企业之前,多年来一直采用单体架构。他们并非一开始就使用微服务,而是在单体架构无法进一步扩展且组织瓶颈日益凸显时才逐步演进。

Shopify

Shopify以 “模块化单体” 架构而闻名。即使规模庞大,他们也选择优化单体架构,而不是将其拆分为微服务。他们的单体架构处理着数十亿美元的交易。

Etsy

Etsy坚持使用单体架构,并投资开发工具以优化性能,而不是拆分成微服务。在竞争对手苦苦挣扎于微服务复杂性时,Etsy 已经实现了盈利并取得成功。

六、决策框架

使用以下框架来确定你的架构:

决策流程表格:通过回答是否有50+开发者、稳定领域边界、分布式系统运维经验、特定扩展需求、项目年限等问题,决定是否采用微服务

如果你对以上大多数问题的回答是“否”,那么几乎可以确定单体架构是正确的选择。

七、等等:系统设计面试呢?

事情到这里就变得复杂起来了。我前面所说的这些都是适用于实际的架构决策,但系统设计面试则另当别论。

面试时,你应该谈谈微服务,原因如下:

面试考察的是知识,而不仅仅是判断力

面试官希望你掌握分布式系统的概念,即使你不会立即用到它们。他们正在评估:

  • 你能否将一个系统分解成逻辑组件?
  • 你了解服务边界和API吗?
  • 你能谈谈不同方法之间的优缺点吗?
  • 你知道如何扩展单个组件吗?

制胜面试策略

最优秀的候选人会展现出进化论思维,具体思路如下:

1)明确起点
“对于早期产品,我会从模块化单体架构入手。这样开发、部署和调试都更简单。”

2)展示缩放后的架构
“随着系统用户增长到数百万,我们将根据扩展需求和团队结构提取服务。”

3)明确讨论权衡取舍
“拆分成微服务会增加网络延迟和运维复杂性,但可以实现独立的扩展和部署。”

这种方法既体现了实践判断力(从简单入手),又体现了技术深度(懂得如何扩展)。

八、结语

微服务听起来很有吸引力,这并非没有道理。它们在理论层面颇具研究价值,在架构图上呈现得清晰美观,同时也是一些优秀企业的主流选择。

但那些优秀的公司并非一开始就采用微服务架构,而是在多年的发展之后才逐渐转型的。作为一名工程师,你的职责不是使用最花哨的架构,而是用最简单有效的方案解决问题。对于大多数项目而言,这种解决方案是结构良好的单体架构。

开始时平淡无奇,需要的时候会变得精彩纷呈。

希望这份关于架构选型的思考能为你带来启发。更多关于系统设计、开发实践的深度讨论,欢迎在云栈社区与同行们交流。当你需要准备下一次技术面试,或者面临真实的架构抉择时,这份从“差点被优化”到审慎思考的经历,或许能帮你避开那些华丽的陷阱。


原文:https://blog.algomaster.io/p/why-you-should-never-start-with-microservices?utm_source=profile&utm_medium=reader2




上一篇:五年踩坑复盘:过度设计如何让系统架构在凌晨崩盘
下一篇:架构设计全景解析:从业务到微服务,核心原则与演进实践
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-4-7 18:38 , Processed in 0.899770 second(s), 41 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表