SOA 面向服务架构
2006 年,某国有银行启动了一个大型 IT 改造项目:把分散在各省份的核心系统整合成全国统一的平台。项目预算 3 个亿,历时 5 年。
技术方案是当时最流行的 SOA(Service-Oriented Architecture,面向服务架构)。IBM 和 Oracle 作为总集成商,引入了企业服务总线(ESB),把所有系统连接在一起。
2011 年项目上线。但上线后的第一年,光是解决 ESB 性能问题就花了 8 个月。项目后来成为业界「SOA 失败」的经典案例。
SOA 为什么会失败?是技术不对,还是方法错了?
SOA 的核心思想
SOA 诞生于 1990 年代末期,在 2000 年代初达到巅峰。它的核心理念是:把业务功能封装成可复用的服务,通过标准化的接口和服务总线实现系统间通信。
服务重用
SOA 之前,企业信息系统是烟囱式的:财务系统、人力资源系统、供应链系统各自独立,数据不互通。如果要在新系统中用到某个功能,往往是复制代码而不是复用。
SOA 的思路是:把通用的业务能力抽取成「服务」,任何系统需要时通过接口调用。
分布式计算
SOA 把系统从单机进程拆分成多个分布式服务,服务之间通过网络通信。技术上,SOA 主要基于 SOAP 协议(基于 XML 的 Web Service)和 WSDL(Web Service Description Language)来定义和描述服务。
企业服务总线(ESB)
ESB 是 SOA 的核心组件,它扮演着「服务中介」的角色:所有服务之间的调用不直接通信,而是通过 ESB 路由。
ESB 提供的核心能力:
SOA 与单体的核心差异
服务粒度
单体架构的服务粒度是「模块」,模块之间通过方法调用通信。SOA 的服务粒度是「业务能力」,服务之间通过网络协议通信。
通信协议
单体使用进程内调用(Java 里的方法调用),几乎没有序列化开销。SOA 使用网络协议(SOAP over HTTP、JMS、REST),每次调用都有网络延迟和序列化开销。
数据管理
单体共享同一个数据库实例,通过事务保证一致性。SOA 中每个服务可能有自己独立的数据库,服务间通过消息或 API 调用协调数据一致性。
ESB 的作用与局限
ESB 解决了什么问题
异构系统集成:很多企业有几十年前的老系统,协议和数据格式各不相同。ESB 通过协议转换和消息转换,让这些系统可以互相通信。
服务复用:把通用能力抽取成服务,通过 ESB 暴露给其他系统复用。
集中监控:所有服务调用都经过 ESB,可以统一监控、审计、限流。
ESB 的局限
中心化瓶颈:所有流量都经过 ESB,ESB 成为新的单点。一旦 ESB 性能出问题,所有服务都受影响。
总线成为故障中心:ESB 的监控和告警非常重要,但当 ESB 出现故障时,排查链路非常复杂。请求经过 ESB 后路由到哪个服务、超时时间是多少、是否有消息堆积,都需要专门的知识才能排查。
过度设计:很多 SOA 项目死于过度设计。为了追求「完美」的服务抽象,花了半年设计服务边界,结果业务逻辑变了,之前的设计全部推翻。
SOA 失败的常见原因
过度设计
SOA 鼓励服务抽象,但很多团队把这个理念发挥过头了。简单的一个 CRUD 操作,被包装成复杂的服务调用链。
服务粒度不合理
服务划分有两个极端:服务太粗(和单体没区别)和服务太细(过度拆分导致调用链路爆炸)。
SOA 早期普遍存在「服务太粗」的问题。很多 SOA 项目只是把单体拆成了几个大服务,粒度和单体模块差不多,没有享受到服务化的好处。
后来微服务吸取了这个教训,强调「服务要小」,但又带来了新问题。
ESB 滥用
很多企业把 ESB 当成万能解决方案:性能问题靠 ESB 解决,安全问题靠 ESB 解决,可靠性问题也靠 ESB 解决。结果 ESB 承担了太多职责,变成一个臃肿的中心化组件。
SOA 的教训是:架构要去中心化,不要把所有鸡蛋放在一个篮子里。这一点后来被微服务彻底贯彻。
技术背景:CORBA、Web Services、SOAP
CORBA
CORBA(Common Object Request Broker Architecture)是 1990 年代的对象中间件标准。它允许不同语言、不同平台的对象互相通信。
CORBA 的失败在于:标准太复杂,实现之间不兼容,安全模型不完善。在企业市场的竞争中,被微软的 DCOM 和后来Sun的 RMI 击败。
Web Services
Web Services 是 2000 年代初的企业集成标准,包括:
- SOAP:Simple Object Access Protocol,基于 XML 的消息协议
- WSDL:Web Services Description Language,描述服务接口
- UDDI:Universal Description, Discovery and Integration,服务注册发现
Web Services 比 CORBA 更简单,获得了更广泛的支持。但 SOAP 消息的 XML 序列化开销大,解析速度慢,在性能敏感的场景下表现不佳。
REST 的崛起
2000 年代末,REST 风格的 API 开始流行。相比 SOAP,REST 更简单、性能更好,逐渐成为 Web API 的主流。
SOA 与微服务的本质差异
很多人以为微服务就是「把 SOA 的名字换了一下」。实际上,两者有本质差异:
关键差异:数据管理
SOA 的 ESB 编排往往意味着服务间共享数据,或者通过 ESB 做数据聚合。这导致服务之间紧耦合,修改一个服务可能影响其他服务。
微服务强调「每个服务有自己的数据库」,服务之间通过 API 通信,数据完全隔离。这种设计让服务可以独立修改、独立部署。
关键差异:治理理念
SOA 强调「企业级标准」,所有服务必须遵循统一的技术规范、命名规范、安全规范。这保证了系统的一致性,但也限制了灵活性。
微服务强调「团队自治」,每个团队可以自主选择技术栈、发布节奏、数据库类型。只要服务对外暴露的 API 不变,内部实现可以自由改变。
真实案例:某银行 ESB 项目的教训
以下案例来自 2011 年某国有银行的真实项目(已脱敏):
背景:银行有 20 多个省份的核心系统,数据格式、通信协议各异。项目目标是整合成全国统一的平台。
方案:IBM 提供 ESB 平台,Oracle 提供数据库,整合所有系统。
问题:
-
性能瓶颈。ESB 每秒处理 5000 笔交易,而业务高峰需要 20000 笔。扩容 ESB 需要采购更贵的服务器,一台 ESB 服务器的价格是普通应用服务器的 10 倍。
-
协议转换复杂。有些老系统用的是专有协议,ESB 支持得不好,导致集成花了大量时间。
-
维护成本高。ESB 的配置非常复杂,每次业务变更都需要修改 ESB 配置。维护 ESB 需要专门的团队,人员成本很高。
-
故障排查困难。当一笔交易失败时,需要查看 ESB 日志才能知道调用链路。ESB 日志格式不友好,排查一次问题可能需要几天。
教训:银行后来反思,这次项目的失败不是 ESB 技术不对,而是「用 ESB 解决所有问题」的想法本身就是错的。ESB 适合做协议转换和路由,但不适合做高性能的交易处理。
SOA 的适用场景
虽然 SOA 有很多失败案例,但它在某些场景下仍然有价值:
异构系统集成
当企业有大量历史遗留系统,技术栈各异,需要互相通信时,ESB 的协议转换能力非常有用。
强流程编排需求
当业务流程需要跨多个系统、涉及复杂的状态机时,ESB 的服务编排能力可以统一管理流程。
强合规要求
金融、医疗等行业有严格的审计要求。ESB 的集中日志和监控能力可以满足合规需求。
总结
SOA 是企业级架构的第一次大规模实践,它的核心理念(服务复用、标准化接口)影响了后来整个行业。但 SOA 的失败也留下了宝贵的教训:
- 去中心化:不要把所有能力集中在 ESB,让服务自主管理自己的数据和业务逻辑
- 服务粒度:服务要足够小,才能独立部署和扩展
- 轻量级通信:过度设计的协议会增加复杂度,性能也会受影响
微服务诞生于对 SOA 失败的反思,它继承了好理念,抛弃了坏实践。下一节,我们来详细讲解微服务时代。
思考题
问题 1:某企业有 10 个历史遗留系统,用的协议和数据格式都不一样。是否应该引入 ESB 来做集成?
参考答案
需要看具体情况。如果这 10 个系统之间的调用频率很高,而且业务逻辑需要强一致性,可以考虑引入 ESB。但如果大部分系统是「只读」调用,更好的方案是:直接点对点集成,或者用一个简单的 API 网关来统一入口,不要让 ESB 成为中心化瓶颈。另外,也可以考虑逐步迁移到 RESTful API,统一协议后再简化集成架构。
问题 2:SOA 强调服务复用,但很多 SOA 项目最后变成了「服务复制」,如何避免这个问题?
参考答案
服务复用的前提是服务边界划分合理。如果边界划错了,服务就不是复用而是重复建设。几个建议:
- 先做领域建模(DDD),确定服务边界后再抽象接口
- 服务设计要稳定,避免频繁修改导致消费方需要同步更新
- 建立服务治理机制,鼓励复用而不是重新开发
- 衡量复用的收益,如果服务改造频率很高,复用成本可能超过收益
问题 3:微服务声称「每个服务独立数据库」,但这会导致数据一致性问题。SOA 的共享数据库是否反而更简单?
参考答案
这是一个权衡问题。共享数据库确实简化了事务一致性,但引入了紧耦合:修改表结构需要协调所有使用方。独立数据库让服务解耦了,但需要引入分布式事务或最终一致性方案。对于强一致性要求的业务(如金融转账),可以采用「共享数据库 + 独立服务」的方式,或者引入 Saga 模式来处理分布式事务。没有绝对的对错,只有场景的适配。