一个人写 Go 后端,该不该上微服务
去年我想给后台服务做拆分,方案画到第二版就停了。一笔账算下来:拆出去的那个服务需要独立部署、独立日志、独立监控,而干活的人还是我一个。从那以后,一个人用 Go 要不要上微服务这道题,我的答案就固定了。
结论放在前面:一个人的项目,默认单体,只有在「某个模块必须独立扩缩」或「它必须用另一种语言写」时才拆。为了结构好看去拆,是最亏的一种。
所以别人问我一个人用 Go 要不要上微服务,我的回答总是先反问一句:你现在是缺扩展性,还是缺时间?
一、四个维度上的真实差别
| 维度 | 单体 | 微服务 |
|---|---|---|
| 部署 | 一个进程,一次重启 | 每个服务各自一套部署和重启 |
| 排查问题 | 一个日志入口,链路在进程内 | 需要跨服务追调用,串起多个日志源 |
| 改动成本 | 改一处,编译一次就能验 | 接口变更要同步改调用方和版本 |
| 扩容 | 整个进程一起扩 | 能只扩压力大的那一个 |
| 上手 | 新人看一个仓库 | 先搞清服务边界和依赖关系 |
这张表里前两行是我的真实体验。部署和排查这两件事,在单人项目里的频率远高于扩容,所以它们的权重也更高。
二、拆开之后多出来的三份活
拆服务不是把代码分开放,是多出三件要长期维护的事。
第一件是部署。原来一次重启搞定的事,变成要有顺序地重启多个进程,还得处理其中一个起不来时怎么办。
第二件是日志。请求跨了两个服务,排查就得先知道它经过了哪几个,再去对时间。
第三件是版本。接口一改,调用方和提供方必须同时上线,中间不能有窗口期。这三件事不会因为项目小就变简单。
三、分别适合谁
微服务适合的是:有多个人同时改代码,且模块之间的发布节奏互相干扰。
代码冲突频繁、一个模块上线要等另一个模块的测试,这类问题靠拆服务能缓解。这也是它被发明出来要解决的问题。
单体适合的是:一个人或者两三个人,改动集中在同一块业务上。我现在的项目就属于这种,后台服务、内容生成、发布流程都在一个进程里,改一处能立刻看到整体效果。
四、一个人用 Go 要不要上微服务:我的判断标准
我选单体,理由不是微服务不好,是我缺的不是扩展性,是时间。
拆服务能解决扩容和团队协作,这两个问题我现在都没有。而它带来的成本是天天要付的。用天天付的成本换一个当前不存在的收益,不划算。
真到了要拆的那天,我的判断标准是这条:某一块的流量特征明显和其他部分不一样,比如它需要常驻长连接,或者 CPU 占用远高于其他模块。那时候拆是解决问题,不是整理结构。
在这之前,我会用别的方式控制单体的复杂度:把启动组装和业务逻辑分开,模块之间只用明确入口调用。这两条能撑很久。
常见问题
Q:一个人用 Go 要不要上微服务,什么时候该拆?
A:出现「某个模块必须独立扩缩容」或者「它只能用别的语言实现」时再拆。只是觉得代码有点乱,先整理目录和边界,别动部署结构。
Q:单体写久了会不会变成没法维护的一团?
A:会,但原因通常不是没拆服务,而是模块之间互相直接调。把调用入口收窄,单体能撑的时间比想象中长。
Q:先按单体写,以后再拆,代价大吗?
A:比一开始就拆小。只要你没把业务逻辑和启动组装混在一起,拆的时候是把目录挪出去,不是把代码重写一遍。
相关阅读
本文作者西米,37 岁程序员,一个人加五个 AI 员工在跑一家公司。踩过的坑和真实账本都写在公众号「西米分享」。
完整代码、踩坑清单与最新进展,都在公众号。
📱 关注公众号「西米分享」