去年公司搞技术升级,把单体应用拆成了微服务。拆之前接口平均响应80ms,拆完之后变成了240ms。老板拿着监控截图问我:这就是你说的"技术先进性"?

我哑口无言。今天把这段"翻车"经历写出来,给正在考虑微服务化的团队提个醒。

问题出在哪?不是微服务不好,是我们拆得太细了。

原来一个下单接口,内部调用就是几个方法跳转,内存里的指针传递,纳秒级。拆成微服务后,同样的流程变成了6次HTTP调用,加上序列化、网络传输、连接池等待,每次调用至少多出来5ms开销。6次就是30ms,再加上服务发现、负载均衡、熔断判断这些基础设施的损耗,80ms变240ms太正常了。

更隐蔽的问题是:我们为了"纯"而牺牲了性能。

有个接口需要查用户信息和订单信息。原来一个SQL join就搞定。拆成微服务后,用户服务一个接口,订单服务一个接口,前端调两次。后来我们加了BFF层做聚合,但BFF本身又多了一层网络调用。

直到有个老同事提醒:你们为什么不把读操作直接走数据库,绕过服务间调用?我们这才反应过来,微服务拆分的是"写操作"的边界,不是"读操作"的边界。读操作完全可以反规范化,用物化视图或者宽表来扛。

另一个坑:本地缓存变成了分布式缓存,复杂度飙升

单体时代,热点数据直接本地缓存,命中率99%,响应时间忽略不计。拆成微服务后,每个服务实例都要同步缓存状态,引入了Redis集群、缓存一致性、缓存穿透等一系列问题。有一次缓存同步延迟,导致用户刚下的单在查询时显示"未支付",客服电话被打爆。

后来我们的做法是:读多写少的数据,允许一定延迟的,用本地缓存加短TTL;要求强一致的,才走分布式缓存。不是什么东西都必须"分布式"。

现在我们的架构

保留了微服务的核心边界:用户、订单、支付三个服务独立部署、独立迭代。但读操作做了聚合层,用宽表扛查询。服务间调用从6次降到了2次,接口延迟回到了100ms左右。虽然比单体时代还是慢,但换来了独立部署的灵活性,这个trade-off我们认了。

最后说点个人感受:

微服务不是银弹,它解决的是"团队规模"和"迭代速度"的问题,不是"性能"问题。如果你的团队不到20人,单体应用完全够用,别为了追技术潮流而拆。

你们团队做过微服务化吗?有没有遇到过拆分后性能下降的问题?最后是怎么解决的?


玩篮球的绿茶
1 声望0 粉丝