公司发展到一定阶段,到底要不要封装中间件?

这个问题其实困扰过很多技术团队,尤其是那些从一条业务线慢慢长成多条业务线的公司。我们自己也走过这条路,从"啥都自己包"到"出了事故赶紧拆",算是把封装中间件这件事从头到尾经历了一遍。今天就把这些经历和思考整理一下,也算给同行一个参考。

这里说的"封装中间件",大致分两类东西。一类是 SDK 型的,比如阿里云的文件上传、短信发送这些第三方服务,你给它包一层统一的 API,让业务方调用起来更简单。另一类是中间服务型的,比如公司内部抽出来的用户中心、权限服务、消息中心,本来是各业务线各写各的,后来统一成一个独立部署的服务,大家都来调它。

这两类东西封装的初衷都一样:别让大家重复造轮子。但当公司从一两条业务线发展到十几条、几十条的时候,这个问题就变得没那么简单了。

封装的好处,确实很明显。 最开始决定封装,是因为痛点太明显了。同一个短信服务,A 团队用这种方式对接,B 团队用那种方式对接,日志格式不一样,异常处理不一样,重试策略也不一样。出了问题去排查,光看各家写的代码就得花半天时间。

封装之后立竿见影。小团队人员少,新人来了,看一个 demo 就知道怎么接入,不用再去啃第三方几十页的文档,不用单独找个同事抽精力来手把手教。安全漏洞也不用挨个服务去修了,中间件修一次,升级一下版本就完事。最关键的是编程风格统一了,代码审查的成本降下来了,各团队之间的代码可读性也提高了。

还有一个好处是当时没太意识到,后来才发现很重要的------可观测性。所有调用都走统一的入口,你想看调用量、成功率、平均耗时,加个埋点就行了。想做限流、熔断、降级,也只需要在中间件层统一配置。这些能力如果分散在各个服务里,你根本没法统一管理。

成本方面也是有好处的。比如短信通道,统一封装之后可以对接好几家供应商,哪家便宜切哪家,甚至可以做自动切换。各种第三方 API 的密钥也不用散落在各个服务的配置文件里了,集中管理,安全很多。

但问题也真不少。 说完好处,该说痛了。封装中间件最大的问题,其实不是技术层面的,而是组织层面的。

升级是个大工程。 你可能只是修了一个小 Bug,改了一行代码,但这一行代码影响的是几百个服务。你得协调所有业务线一起升级、一起测试、一起发布。如果哪个团队正好在赶需求排不进来,你这版本就推不下去。而如果不推,那个安全漏洞就一直存在。这种"牵一发而动全身"的感觉,做过几次之后真的会心累。

中间件很容易成为瓶颈。 特别是那种中间服务型的,比如用户中心,几乎所有服务都要调它。一旦它的响应变慢了,或者流量上来了扛不住了,全公司的服务都跟着受影响。我们经历过好几次这种事------一个中间服务的数据库查询慢了 200ms,结果全链路超时,各业务线互相踩踏,雪崩一样倒了一大片。

最致命的是 Bug 引发的大面积事故。 中间件团队改了一个自以为很小的逻辑,测试环境也跑通了,结果上线之后发现有个边界条件没覆盖到。这一出问题就不是一个服务的事,是所有依赖它的服务全部中招。而且因为影响面广,修复起来也特别麻烦------你要同时安排几百个服务的回滚或者升级,那种感觉就像同时给几百辆车换轮胎,车还不能停。

过度封装也是个坑。 有时候封装着封装着就变厚了,业务方提了个特殊需求,你说"我加个参数支持一下",加着加着,中间件变得比底层 SDK 还复杂。结果业务方发现官方 SDK 里一个很简单的功能,在你封装的 API 里居然不支持,要么等你排期,要么绕过你直接用原生 SDK。这就很尴尬了,封装本来是为了提效的,结果反而变成了阻碍。

还有一个容易被忽略的问题:调试变复杂了。 出了 Bug,业务方排查到自己调中间件那一层就停了,剩下的得找中间件团队来看。中间件团队再往下查到第三方 SDK,一来一回,一个简单的 Bug 可能要好几个团队协同排查。中间件加了各种代理、拦截、切面之后,堆栈信息也不直观了,debug 的时候经常看得人一头雾水。

小公司的特殊困境。 上面说的这些问题,对大公司来说可能还能扛,毕竟有人有资源。但对小公司来说,情况就更难了。

小公司通常没有专职的中间件团队,往往是某个技术不错的人兼着做。这个人既要写自己的业务需求,又要维护中间件,精力根本不够。更难受的是,中间件这个东西,做好了没人夸你------"这不是应该的嘛";出了问题全公司骂你------"怎么搞的,又崩了"。在绩效考核上也很难体现价值,毕竟你不是在直接产出业务功能。

人员流动也是个问题。当初封装中间件的那个人一旦离职,后面接手的人大概率不敢动这块代码。时间一长,中间件就变成了一个谁都不敢碰的"黑盒",只能往上堆功能,越堆越臃肿,越臃肿越没人敢动。

来说说我们的真实经历。说了这么多理论,聊聊我们自己是怎么一步步走过来的。

最开始就一条业务线,十来个人,各服务直接对接第三方 SDK,虽然写法五花八门的,但因为服务少、人少,沟通成本低,出了什么问题吼一嗓子就解决了。这个阶段其实完全没必要封装,硬封装反而是给自己找事。

后来业务扩张,从一条线变成好几条线,每条线有自己的团队。这时候问题就来了:同一个短信服务,三个团队写了三套对接代码,配置管理方式都不一样。有个服务用的 SDK 版本还是两年前的,有个已知安全漏洞都没人知道。于是我们决定封装,抽出了一个人来统一做这件事。

刚开始确实尝到了甜头。新业务线接入很快,代码风格统一了,版本管理也规范了。但好景不长,随着服务数量越来越多,中间服务开始扛不住了。用户中心、权限服务、消息中心,这些处在调用链路核心位置的中间服务,高峰期响应明显变慢。更要命的是,有几次中间件升级引入了 Bug,影响了几百个服务,全公司停下手里的活来配合回滚和修复。

那几次事故之后,业务线团队对中间件的信任基本就崩了。为了稳定性,有团队开始转向引入原生 SDK,绕过中间件直接对接。大家嘴上不说,但行动上已经在"用脚投票"了。

后来我们就开始做"去中间件"。不是说完全不用中间件了,而是回归理性。SDK 类的不做深度封装了,阿里云 OSS 的官方 SDK 已经很好用了,你包一层的意义不大。我们把精力放在了配置管控上------密钥集中管理、环境隔离配置统一,这些才是真正需要统一的东西。中间服务类的,能合并回业务线的就合并回去,减少不必要的网络调用。真正需要保留独立部署的,比如网关、认证中心这些,重点做好高可用和降级方案。

做完这一轮之后,调用链路明显变短了,性能上去了。更关键的是故障影响面缩小了,一个服务出了问题不会拖垮一大片。各业务线也有了更大的自主权,迭代速度提了上来。

当然上面也只是举个栗子,也只是公司其中一个中间件的情况。每个公司不同的领导有不同的风格,有些偏向于效率,就喜欢什么都封装一下。有些领导偏向于稳定,每个地方都来一遍 麻烦就麻烦点 真出问题也只会炸一处。

几点掏心窝的建议。经历了这一轮完整的"封装---膨胀---事故---拆分",我有几点比较深的感触。

封装不要太早。 服务不到 20 个、团队不到 50 人的时候,直接用官方 SDK 就好。这个阶段沟通和协调的成本远低于封装和维护的成本。

封装不要太厚。 如果一定要封装,做薄薄一层 Facade 就够了,把复杂的配置管理、密钥管理、监控埋点做掉就行。底层的能力尽量透传出去,不要试图把第三方 SDK 重新设计一遍。

没有兜底的人就不要封装。 中间件这个东西,不是写完了就完了,它需要长期维护、长期投入。如果你团队里没有技术过硬且愿意长期扛这个事的人,那还不如不封装。

保留逃生通道。 任何中间件都得有降级方案。中间服务挂了,业务方至少能降级处理,不能因为你的东西挂了就全线瘫痪。熔断、降级、限流,这些不是可选项,是必选项。

灰度发布是生命线。 中间件的任何变更,一定要先在非核心服务上跑一段时间,观察指标没问题了再推全量。不要再搞"一夜之间全公司升级"这种事了。

接受轮回。 封装、膨胀、出事故、拆分、再封装------这不是什么失败,这是技术演进的正常规律。关键是在每一轮里面吸取教训,下一轮比上一轮做得更好。

说到底,封装中间件这件事,不是"要不要做"的问题,而是"做到什么程度"的问题。我们不是否定封装的价值,而是用真金白银的事故成本证明了一件事:封装要适度,组织要匹配,容灾要到位。与其追求大而全的统一平台,不如做小而美的薄封装加配置管控,把选择权还给业务线。中间件也是要经历分久必合,合久必分的阶段,就像中台一样 分分合合,业务每发展到一定阶段就有适合各阶段的使命,也并没有什么对对错错的。

毕竟,最好的中间件是让你感觉不到它存在的中间件。

相关推荐
爱上纯净的蓝天12 小时前
只输出选项和概率的模型:判别层的接口契约与阈值工程
人工智能·大模型·llm·模型评估·架构设计
doiito11 天前
【Agent Harness】Gliding Horse 最新进化:从“能学习”到“可验证的自主进化”
ai·rust·架构设计·ai agent
記億揺晃着的那天12 天前
Amazon Ads API 实战:如何高精度关联广告活动(Campaign)与 ASIN 及 ERP 产品主数据
软件工程·amazon·架构设计·系统设计·亚马逊·sp-api·amazon ads api
福兮说13 天前
Gin 项目里的错误处理:让 Controller 不必知道错误是怎么来的
后端·go·gin·架构设计
欢醉14 天前
一次RabbitMQ重启引发的网关雪崩复盘
springcloud·架构设计
刘广睿17 天前
衍生素材链怎么设计?截帧、音频与子素材的关联管理复盘
客户端·短视频·效率工具·架构设计·素材管理
递归尽头是星辰20 天前
软件架构风格:范式、落地形态与选型权衡
微服务架构·架构设计·软件架构风格·系统架构师考试·架构落地
刘广睿23 天前
素材库智能集合怎么设计?把多维筛选存成动态收藏的功能复盘
客户端·架构设计·产品设计·素材管理
Patrick在香港24 天前
模型路由器实测:12 个任务省 77%,旗舰过载时的降级要打出显式标记
python·llm·智能路由器·api·架构设计·成本优化