尽可能编写库,而不是服务
“优先使用库而不是服务”的支持者认为,让用户自己运行代码能让他们掌控升级,避免远程 API 的意外破坏,并减少对第三方基础设施的依赖。反对者则指出,服务通常更容易在规模化场景下变现、观测和运维,尤其是在涉及共享状态、数据库或多语言支持时。许多人最终得出的务实结论是:把核心功能设计成可复用的库,在需要时再用薄服务或 CLI 工具包装它;具体选择取决于架构、组织结构和客户需求。
“库 vs 服务”的适用范围
- 许多人认同文章的直觉:默认优先使用库,只有在必要时才增加服务。
- 也有人认为这过于简化,具体要看上下文(规模、合规、数据本地性、团队规模、变现方式)。
故障、升级与控制
- 库的更新只会在用户选择升级时才会出问题;而且他们可以很容易回滚。
- 服务的变更可能会在提供方选择的时间破坏客户端;SLA 和合同能缓解,但无法消除这种风险。
- 有些人认为通过服务强制迁移对用户不友好;另一些人则说,协调升级正是共享开发成本和安全修复的代价。
- 两种模式都会面临版本管理的痛点:库要面对大量版本散落在外,服务则要面对兼容层和版本化 API。
数据存储与架构
- 一个关键反对点是:许多服务本质上依赖数据库和共享状态;把这些东西推到库里,会把复杂的运维负担转嫁给用户。
- 建议包括:定义 repository 接口,让用户“自带存储”;使用通用后端(Postgres、S3 API)或个人数据 pod。
- 反方观点:存储本来就很混乱(延迟、吞吐量、快照、加密、损坏处理);抽象总会泄漏,而且协调很差。
组织动态与规模
- 在许多企业里,新功能默认会做成微服务;库较少,而且更难跨团队、跨仓库协调。
- 单体仓库文化有时会把升级负担放在库维护者身上,这会抑制随意的破坏性改动,但也扩大了他们的责任范围。
- 有些人认为大量使用服务,是政治/协调问题的变通办法,而不是技术上的必然选择。
变现、控制与用户自主性
- 服务更容易变现、观测和控制;库更难销售和支持,但能给用户自主权,并避免锁定。
- 举例提到:本可以做成本地库的 IoT 设备和 SaaS 产品,却被做成了持续收费、成本不透明的服务。
实践建议与混合方案
- 常见倡导模式是:始终把核心逻辑设计成库,然后按需包装成:
- 一个薄服务(HTTP/gRPC 等)。
- 一个 Unix 风格的 CLI,读写结构化数据。
- 经验法则:纯函数/算法逻辑 → 库;绑定私有数据存储、重共享状态或专用基础设施的组件 → 服务。
术语混淆
- 一些评论者觉得文章对“库”的宽泛定义(任何用户可运行的软件)令人困惑,因为这与通常所说的“不可运行的依赖”含义不同。