小团队要不要上微服务?6人团队拆了3个月又合回单体,我的真实踩坑记录
先说结论,有点反潮流: 如果你团队不到10个开发,日活不到50万,没有专职SRE,也没有至少2个以上需要独立扩缩容的模块,那我不建议一上来就拆微服务。我们6个人,2023年Q2把Go单体拆成5个服务,跑了11个月,2024年Q1又合回“模块化单体”。不是微服务没用,是我们把组织问题误当成架构问题。
我们当时的原始架构和数字
- 单体:Go 1.20 + Gin,PostgreSQL 14,Redis 6.2,部署在1台4C8G阿里云ECS + RDS 2C4G + Redis 1G,月成本约2600元。
- 构建:GitHub Actions,每次全量构建6分20秒,镜像180MB,发布一次平均9分钟。
- 团队:2后端、1前端、1测试、1运维兼DBA、1产品,共6人。日订单峰值3.2万,QPS峰值约480。
- 故障:2023年1月到3月,P1故障2次,平均MTTR 36分钟。这个数不算漂亮,但还能接受。
拆完之后的账单:每月多2400,MTTR涨到58分钟
我们拆了 user、order、payment、inventory、notification 五个服务,K8s 1.24,3个4C8G节点,RDS升到4C8G,Redis 2G,RabbitMQ 2C4G,Prometheus + Grafana + Loki 单独2C4G。月成本从2600涨到5000左右,多出2400。更难受的是排障:一次下单失败,要查网关、order、payment、inventory 四个服务的日志,TraceID 还因为 MQ 异步丢了一段。P1故障平均MTTR从36分钟涨到58分钟,按每月4次P1算,多烧22分钟*4=88分钟,还没算开发和测试环境的心智负担。发布频率从每月12次掉到4次,因为跨服务改一个字段要走3个仓库、2次联调、1次全链路回归。
微服务和单体真正该比的不是“先进”,是这7个维度
| 维度 | 单体(模块化) | 微服务 | 小团队建议 |
|---|---|---|---|
| 团队规模 | 1-15人 | 15人以上才划算 | 6人别拆 |
| 独立扩缩容 | 整体扩,浪费20-30% | 按服务扩,省资源 | 日活50万以下先别 |
| 数据一致性 | 本地事务,ACID | Saga/Outbox/最终一致 | 财务强一致慎拆 |
| 故障定位 | 1个日志流 | 需要Trace+日志+指标 | 没SRE别碰 |
| 部署 | 1个流水线 | N个流水线+契约 | 发布<2次/周别拆 |
| 成本 | 2600元/月 | 5000元/月 | 先算钱 |
| 认知负载 | 6人共享1个模型 | 每人背1-2个服务 | 招聘跟不上会崩 |
我们怎么合回去的:7步,能照抄
- 先不拆进程,只拆包。Go 用
internal/user、internal/order、internal/payment,每个包只暴露Service接口。 - 用
go-arch-lint加 CI 规则,禁止order直接 importpayment的 repository。跨模块只能走接口或事件。这个检查跑了2周,抓出17处越界。 - 数据库还是1个 PostgreSQL 实例,但按模块建 schema:
user_schema、order_schema、payment_schema。禁止跨 schema join,报表用单独只读视图。 - 领域事件先走进程内 event bus,接口不变。等哪天真的需要跨进程,再把实现换成 RabbitMQ/Kafka。我们后来换过一版,业务代码没动。
- 支付回调这种必须可靠的,用本地事务+outbox表,后台任务每500ms扫一次,最多重试8次,指数退避。
- 部署回到1个镜像、1个流水线。构建6分20秒,发布9分钟。水平扩展先加Pod,4C8G最高扛到QPS 1200。
- 设拆分阈值:团队>10人、单个模块QPS>800、独立发布冲突>2次/周、合规要求物理隔离。四个满足两个,再拆。
最后说点得罪人的
微服务不是技术升级,是组织放大镜。你团队里如果连代码评审都做不齐,拆成微服务只会把混乱复制5份。我们合回单体后,月成本降回2800,MTTR回到36分钟,发布频率回到每月11次。不是我们退步,是我们终于承认:6个人的公司,先让业务活下来,比让架构图好看重要。你要真问我什么时候拆?等运维开始抱怨“只能整体扩容”,等两个团队为了同一个数据库锁吵架,再拆也不迟。