一个人写 Go 后端,该不该上微服务

去年我想给后台服务做拆分,方案画到第二版就停了。一笔账算下来:拆出去的那个服务需要独立部署、独立日志、独立监控,而干活的人还是我一个。从那以后,一个人用 Go 要不要上微服务这道题,我的答案就固定了。

结论放在前面:一个人的项目,默认单体,只有在「某个模块必须独立扩缩」或「它必须用另一种语言写」时才拆。为了结构好看去拆,是最亏的一种。

所以别人问我一个人用 Go 要不要上微服务,我的回答总是先反问一句:你现在是缺扩展性,还是缺时间?

一、四个维度上的真实差别

| 维度 | 单体 | 微服务 |

|---|---|---|

| 部署 | 一个进程,一次重启 | 每个服务各自一套部署和重启 |

| 排查问题 | 一个日志入口,链路在进程内 | 需要跨服务追调用,串起多个日志源 |

| 改动成本 | 改一处,编译一次就能验 | 接口变更要同步改调用方和版本 |

| 扩容 | 整个进程一起扩 | 能只扩压力大的那一个 |

| 上手 | 新人看一个仓库 | 先搞清服务边界和依赖关系 |

这张表里前两行是我的真实体验。部署和排查这两件事,在单人项目里的频率远高于扩容,所以它们的权重也更高。

二、拆开之后多出来的三份活

拆服务不是把代码分开放,是多出三件要长期维护的事。

第一件是部署。原来一次重启搞定的事,变成要有顺序地重启多个进程,还得处理其中一个起不来时怎么办。

第二件是日志。请求跨了两个服务,排查就得先知道它经过了哪几个,再去对时间。

第三件是版本。接口一改,调用方和提供方必须同时上线,中间不能有窗口期。这三件事不会因为项目小就变简单。

三、分别适合谁

微服务适合的是:有多个人同时改代码,且模块之间的发布节奏互相干扰。

代码冲突频繁、一个模块上线要等另一个模块的测试,这类问题靠拆服务能缓解。这也是它被发明出来要解决的问题。

单体适合的是:一个人或者两三个人,改动集中在同一块业务上。我现在的项目就属于这种,后台服务、内容生成、发布流程都在一个进程里,改一处能立刻看到整体效果。

四、一个人用 Go 要不要上微服务:我的判断标准

我选单体,理由不是微服务不好,是我缺的不是扩展性,是时间。

拆服务能解决扩容和团队协作,这两个问题我现在都没有。而它带来的成本是天天要付的。用天天付的成本换一个当前不存在的收益,不划算。

真到了要拆的那天,我的判断标准是这条:某一块的流量特征明显和其他部分不一样,比如它需要常驻长连接,或者 CPU 占用远高于其他模块。那时候拆是解决问题,不是整理结构。

在这之前,我会用别的方式控制单体的复杂度:把启动组装和业务逻辑分开,模块之间只用明确入口调用。这两条能撑很久。

常见问题

Q:一个人用 Go 要不要上微服务,什么时候该拆?

A:出现「某个模块必须独立扩缩容」或者「它只能用别的语言实现」时再拆。只是觉得代码有点乱,先整理目录和边界,别动部署结构。

Q:单体写久了会不会变成没法维护的一团?

A:会,但原因通常不是没拆服务,而是模块之间互相直接调。把调用入口收窄,单体能撑的时间比想象中长。

Q:先按单体写,以后再拆,代价大吗?

A:比一开始就拆小。只要你没把业务逻辑和启动组装混在一起,拆的时候是把目录挪出去,不是把代码重写一遍。

相关阅读


本文作者西米,37 岁程序员,一个人加五个 AI 员工在跑一家公司。踩过的坑和真实账本都写在公众号「西米分享」。

完整代码、踩坑清单与最新进展,都在公众号。

📱 关注公众号「西米分享」