企业架构实践(三):企业应用集成——从 Web Service 到消息队列
一、系统之间能够连接,不代表集成架构已经清晰
在前两篇文章中,我从企业现有的 IT 环境出发,整理了系统清单,并尝试把系统之间的关系表达出来。
梳理过程中,一个比较明显的感受是:企业里的应用系统通常不是独立运行的。
ERP 需要与其他业务系统交换数据,MES 需要接收生产相关信息,WMS 需要处理仓储业务。为了让这些系统协同工作,企业需要建立各种接口和数据交互机制。
在实际环境中,不同系统之间可能采用不同的集成方式。
例如,目前 ERP 与 WMS 通过 Web Service 进行集成;而 D365 Finance and Operations 与 MES 之间,则通过 ERP Sync Service 和 RabbitMQ 等组件完成相关集成。
这两种方式都能够实现系统间的数据交互,但它们的技术机制、处理流程和运维关注点并不相同。
如果只知道两个系统之间存在接口,还不足以完整理解集成架构。
我们还需要进一步了解:
- 系统之间通过什么方式交互?
- 调用方是否需要等待被调用方完成处理?
- 数据通过什么方式传递?
- 接口失败后如何处理?
- 是否存在独立的集成服务?
- 如何确认数据已经成功处理?
- 当业务量增加时,现有集成方式是否仍然适用?
这些问题既与具体的技术实现有关,也与业务流程和系统职责有关。
因此,这篇文章准备从日常 IT 管理中比较常见的集成场景出发,梳理 Web Service、消息队列和集成服务之间的关系,并尝试理解它们在企业应用架构中的作用。
二、先理解同步调用与异步消息
在分析具体的集成方式之前,我认为有必要先区分两个概念:同步调用和异步消息。
它们描述的是交互过程中的不同处理机制,并不完全等同于某一种具体协议或产品。
2.1 同步调用:调用方需要等待响应
假设 ERP 需要向 WMS 查询某项业务信息。
一种常见的方式是,ERP 调用 WMS 提供的 Web Service 接口,WMS 处理请求后返回结果。
整个过程可以简化为:
- ERP 发起请求。
- WMS 接收请求。
- WMS 执行相应处理。
- WMS 返回响应。
- ERP 根据响应结果继续处理。
在这种模式下,调用方通常需要等待被调用方返回响应,才能根据结果决定下一步操作。
这就是同步调用的基本思路。
这里需要注意,同步调用并不意味着整个业务流程一定在一次请求中全部完成。接口可能只完成查询、校验或接收请求等操作,后续业务处理仍然可能在后台执行。
同样,接口返回成功,也需要明确它所代表的成功含义。
例如,接口返回成功可能只表示请求已被接收,并不一定意味着所有后续业务处理都已完成。
因此,设计接口时,需要明确请求、响应和业务处理结果之间的关系。
2.2 异步消息:发送方与接收方可以分开处理
另一种方式是使用消息队列。
发送方将消息发送到消息中间件,接收方再从中获取消息并进行处理。
简化后的过程如下:
- 发送方准备业务消息。
- 消息被发送到 RabbitMQ。
- 消费方获取消息。
- 消费方执行相应业务处理。
- 根据实际设计,消费方确认消息处理状态。
这种方式允许发送方和接收方在一定程度上独立运行。
例如,发送方成功将消息交给消息中间件后,通常不需要等待接收方完成全部业务处理,便可以继续执行其他工作。
但这里同样需要注意:消息发送成功,不等于接收方已经完成业务处理。
如果业务要求确认最终处理结果,就需要进一步设计处理状态、结果反馈、异常记录等机制。
异步消息并不意味着可以不关心处理结果,只是把发送与处理分成了不同阶段。
2.3 两种方式有什么区别?
可以从以下几个方面进行比较。
| 比较维度 | 同步调用 | 异步消息 |
|---|---|---|
| 基本交互方式 | 请求后等待响应 | 发送消息,接收方后续处理 |
| 调用方是否需要等待业务处理结果 | 通常需要等待接口响应,具体取决于接口语义 | 通常不需要等待消费方完成业务处理 |
| 系统之间的时间耦合 | 较强,调用过程通常要求对方及时响应 | 可以降低发送方与接收方的时间耦合 |
| 处理结果 | 通常通过接口响应返回 | 通常需要结合消息确认、业务状态或结果反馈判断 |
| 典型关注点 | 超时、接口错误、请求失败 | 消息积压、重复处理、消费失败、消息恢复 |
| 常见技术形式 | Web Service、HTTP API | RabbitMQ 等消息中间件 |
这张表只是概括了两种模式的典型特征。
实际系统可能采用混合方式,例如通过同步接口提交请求,再通过消息队列处理后续业务。
因此,在分析企业应用集成时,不应该只根据接口名称判断系统采用了哪种机制,而应该结合实际交互流程进行确认。
三、结合实际环境理解 Web Service 集成
目前,企业 ERP 与 WMS 之间通过 Web Service 进行集成。
这是一种比较常见的企业应用集成方式。
但在架构分析中,我认为有必要区分两个问题:
第一,系统之间采用什么技术方式进行交互。
第二,这种交互方式具体支持什么业务流程。
Web Service 只是技术实现的一部分,真正需要理解的仍然是接口背后的业务含义。
3.1 先明确接口双方的职责
在 ERP 与 WMS 的集成中,ERP 和 WMS 分别承担不同的业务职责。
ERP 负责相关企业资源管理业务,WMS 负责仓储管理。
系统之间需要交换哪些数据,应该由实际业务流程和接口设计决定,而不能仅凭系统名称推断。
在梳理这类集成时,可以先整理一份接口清单。
| 信息项 | 需要记录的内容 |
|---|---|
| 接口名称 | 接口的正式名称或业务用途 |
| 调用方 | 哪个系统发起请求 |
| 被调用方 | 哪个系统提供接口 |
| 交互方式 | Web Service、HTTP API 或其他方式 |
| 业务用途 | 接口解决什么业务问题 |
| 数据内容 | 请求和响应包含哪些主要数据 |
| 调用方向 | 数据从哪个系统流向哪个系统 |
| 异常处理 | 请求失败或处理异常时如何处理 |
| 业务结果 | 如何确认相关业务处理已经完成 |
这份清单不需要一开始就非常复杂。
先把接口名称、调用方、被调用方、业务用途和数据方向整理清楚,就可以帮助我们建立基本认识。
之后再逐步补充超时设置、错误码、重试策略和业务确认机制。
3.2 接口成功,不一定代表业务成功
这是接口设计中容易被忽略的问题。
假设 ERP 调用 WMS 接口,接口返回了成功响应。
这个响应究竟代表什么?
可能是:
- 请求已经成功接收。
- 请求参数已经通过校验。
- 业务数据已经保存。
- 相关业务操作已经全部完成。
这些含义并不相同。
如果接口只是接收了请求,而后续处理仍然在后台进行,那么调用方就不能把接口返回成功直接理解为业务流程已经完成。
因此,在接口设计中,需要明确响应语义。
对于重要业务,还需要考虑如何查询处理状态、识别失败记录,以及在必要时重新发起处理。
这些设计不仅影响接口开发,也会直接影响后续的运维和故障排查。
3.3 需要关注哪些运行问题?
对于 Web Service 集成,可以重点关注以下几个方面。
第一,超时。
如果被调用方处理较慢,调用方可能在等待一段时间后超时。
超时并不一定意味着被调用方没有执行操作。有时请求已经被处理,只是响应没有及时返回。
因此,发生超时后,不能不加判断地直接重复提交可能产生业务副作用的请求。
第二,重试。
对于临时网络异常或短暂服务不可用,可以考虑重试机制。
但重试必须结合业务操作的性质设计。
例如,同一笔业务请求如果被重复执行,可能导致重复创建记录或重复处理业务。
因此,需要考虑请求唯一标识、幂等处理或业务状态校验等机制。
第三,异常记录。
接口调用失败时,应该能够记录必要的请求信息、错误原因和处理状态。
记录内容还需要遵守企业的数据安全要求,避免在日志中不必要地保存敏感信息。
第四,数据一致性。
两个系统可能分别保存自己的业务数据。
当接口调用失败、数据校验不通过或后续处理异常时,需要明确如何发现和处理不一致的情况。
这些问题不是 Web Service 特有的,但在同步调用模式下,通常需要结合请求与响应机制进行设计。
四、结合实际环境理解 RabbitMQ 消息集成
与 ERP 和 WMS 的 Web Service 集成不同,目前 D365 F&O 与 MES 之间的集成涉及 ERP Sync Service 和 RabbitMQ。
实际链路为:
D365 F&O ↔ ERP Sync Service ↔ RabbitMQ ↔ MES
这条链路中,D365 F&O 并不是直接与 RabbitMQ 交互。
ERP Sync Service 是独立的集成服务,RabbitMQ 则为相关系统之间的消息传递提供支持。
在理解这条链路时,需要把集成服务、消息中间件和业务应用区分开来。
4.1 为什么需要消息中间件?
消息中间件的价值之一,是帮助发送方与接收方在时间上解耦。
假设某项业务需要把数据从 ERP 侧传递给 MES。
如果采用直接调用方式,调用方通常需要等待接收方响应。如果接收方暂时不可用,调用方可能需要面对超时或调用失败等情况。
使用消息中间件后,可以将消息传递与后续业务处理分开。
在符合具体消息投递和确认配置的前提下,发送方可以先将消息交给 RabbitMQ,由后续消费者获取并处理。
这样,发送方与接收方就不一定需要同时完成整个业务过程。
不过,这并不意味着消息中间件可以自动解决所有集成问题。
消息能够被保存和传递,不代表业务数据一定正确,也不代表消费者一定能够成功完成处理。
消息中间件提供的是一种通信和解耦能力,业务处理结果仍然需要由相关应用负责。
4.2 ERP Sync Service 为什么需要单独考虑?
在实际架构中,ERP Sync Service 是连接 ERP 侧与后续集成环节的独立组件。
如果只关注 D365 F&O、RabbitMQ 和 MES,就容易忽略集成服务承担的工作。
在应用关系图中,将 ERP Sync Service 单独画出来,可以更准确地表达真实架构:
D365 F&O ↔ ERP Sync Service ↔ RabbitMQ ↔ MES
这样做至少有三个好处。
首先,可以明确集成服务的职责边界。
其次,可以在发生异常时,根据实际处理流程进一步分析问题位置。
最后,可以在调整集成服务时,识别与它相关的接口、消息和业务流程。
至于 ERP Sync Service 内部如何组织业务逻辑、是否采用特定的重试策略,以及如何处理消息确认等细节,需要结合实际代码、接口文档和运行配置进一步确认。
在没有充分依据之前,不应该仅凭架构图推断这些实现细节。
4.3 使用消息队列后,需要关注哪些问题?
消息队列引入了新的处理机制,也带来了相应的设计和运维要求。
消息是否能够可靠地保存?
需要了解消息持久化、队列配置、消息确认以及相关恢复机制。
RabbitMQ 是否能够在特定故障场景下保留消息,取决于具体配置和运行环境,不能仅凭使用了 RabbitMQ 就认定消息一定不会丢失。
消息是否可能被重复处理?
在分布式系统中,消息重投、消费者异常和处理结果确认之间可能存在复杂情况。
因此,不能假设每条消息只会被处理一次。
对于重要业务,需要结合业务唯一标识、幂等处理和数据状态校验等机制,降低重复处理带来的影响。
消费者处理失败后怎么办?
如果 MES 获取消息后,在处理业务数据时发生异常,需要明确相应的错误处理方式。
可能需要记录失败信息、重新处理,或者通过人工介入完成恢复。
具体方案取决于业务要求和实际实现。
消息积压如何发现?
如果消息产生速度持续高于消费速度,队列中的待处理消息可能逐渐增加。
因此,需要根据实际业务情况,关注消息积压、消费速度和处理失败等指标。
这些信息有助于发现系统处理能力与业务负载之间的差距。
消息中间件不可用时怎么办?
目前 RabbitMQ 在 Kubernetes 中采用单实例部署。
这意味着需要结合实际部署和恢复机制,评估 RabbitMQ 不可用时可能产生的业务影响。
例如,相关消息是否暂时无法发送或消费,恢复后能否继续处理,是否存在需要人工介入的情况。
是否需要调整部署方式,应该根据业务重要性、可接受的中断时间、恢复目标和运维成本综合判断。
不能只因为采用单实例部署,就直接认定整个集成架构一定不可靠;但也不能忽略它所带来的可用性评估需求。
五、同步调用与异步消息,应该如何选择?
在了解两种集成方式后,一个自然的问题是:企业是不是应该尽可能把接口都改成消息队列?
我认为不能这样理解。
同步调用和异步消息各有适用场景,选择哪一种方式,应该从业务需求出发。
5.1 适合采用同步调用的场景
如果业务操作需要立即获得明确响应,同步调用通常比较直接。
例如:
- 查询某项业务信息。
- 提交请求后,需要立即进行参数校验。
- 调用方需要根据返回结果决定下一步操作。
- 交互过程相对简单,且能够接受相应的等待时间。
这些场景可以考虑通过 Web Service 或 HTTP API 实现。
当然,具体是否适合,还需要考虑调用频率、响应时间、系统可用性和异常处理要求。
5.2 适合采用异步消息的场景
如果业务流程允许发送与处理分开进行,并且需要在不同系统之间传递待处理的业务消息,就可以考虑异步消息。
例如:
- 生产相关业务数据的传递。
- 不需要在同一次请求中等待接收方完成全部处理的业务流程。
- 需要缓冲短时流量波动的场景。
- 希望降低发送方与接收方之间时间耦合的场景。
但异步消息并不适合所有业务。
如果业务必须立即知道操作最终是否成功,就需要设计额外的结果查询、状态反馈或确认机制。
因此,采用消息队列之前,需要先明确业务到底需要什么样的交互语义。
5.3 也可以采用混合方式
实际系统中,同步调用和异步消息并不一定互相排斥。
例如,一个业务系统可以先通过 HTTP API 提交请求,接收方完成基本校验后返回请求编号,再由后台通过消息队列处理后续工作。
调用方之后可以查询请求状态,了解业务是否完成。
这种设计同时使用了同步调用和异步处理,但也需要额外设计状态管理、异常处理和结果查询机制。
它是否值得采用,取决于业务复杂度和实际需求。
对于简单的接口,如果同步调用已经能够满足业务要求,就没有必要为了使用消息队列而增加系统复杂度。
架构设计的重点不是采用更多技术,而是选择适合业务需求的技术,并明确其边界和代价。
六、从接口集成进一步考虑企业应用架构
到这里,我们讨论了 Web Service、RabbitMQ 和 ERP Sync Service 的作用。
如果只从技术角度看,这些内容属于应用集成设计。
但从企业架构的角度来看,它们还涉及业务、数据和技术等不同层面。
6.1 业务层面:为什么需要集成?
首先,需要明确系统之间交换数据的业务原因。
例如,ERP 与 MES 之间为什么需要交换生产相关数据?ERP 与 WMS 之间为什么需要建立接口?
这些问题应该结合实际业务流程回答。
如果没有明确业务目的,就很难判断接口是否必要,也很难评估接口发生异常时对业务的实际影响。
6.2 数据层面:交换的是什么?
其次,需要明确交换的数据及其业务含义。
例如,生产订单、物料、BOM、库存和生产报工等数据,在不同系统中可能承担不同的业务职责。
接口能够传递数据,不代表两个系统对数据的理解完全一致。
因此,还需要明确数据定义、数据来源、编码规则和业务校验要求。
6.3 应用层面:哪些系统参与处理?
接下来,需要明确参与业务流程的应用和服务。
以 D365 F&O 与 MES 的集成为例,除了两个业务系统本身,还需要考虑 ERP Sync Service 和 RabbitMQ。
将这些组件纳入应用架构,可以更准确地表达真实的集成关系。
6.4 技术层面:这些组件如何运行?
最后,还需要考虑相关组件的运行环境、监控、备份和恢复机制。
例如,ERP Sync Service 和 RabbitMQ 都部署在 Kubernetes 中,但它们的职责不同,运行方式和保障要求也可能不同。
因此,不能仅仅因为它们都部署在同一个平台上,就认为它们具有相同的可用性特征。
通过这四个层面的分析,可以逐步把一条接口链路从简单的技术连接,扩展为对业务目的、数据内容、应用职责和技术依赖的完整理解。
七、实践中可以从哪些文档开始?
对于已经运行的企业 IT 环境,我认为不一定需要一开始就建立复杂的架构管理体系。
可以先从几份简单、实用的文档开始。
7.1 系统清单
记录系统名称、主要职责、业务负责人、技术负责人和运行状态等信息。
这份文档用于了解企业有哪些系统。
7.2 接口清单
记录接口名称、调用方、被调用方、交互方式、业务用途和数据方向。
这份文档用于了解系统之间如何交互。
7.3 应用关系图
把主要应用、集成服务和公共服务放在同一张图中,展示已经确认的主要关系。
这份图用于快速理解应用之间的联系。
7.4 关键集成流程说明
针对重要业务链路,进一步记录处理过程、主要数据、异常场景和恢复方式。
例如,可以单独整理 D365 F&O、ERP Sync Service、RabbitMQ 与 MES 之间的集成流程。
这些文档不一定需要彼此独立,也可以根据企业实际情况合并管理。
重要的是,信息应当能够被相关人员理解、验证和维护。
如果文档只记录技术名称,却没有说明实际用途和关系,就很难在日常工作中发挥作用。
八、这一阶段的实践总结
通过梳理企业现有的集成方式,我对应用之间的关系有了进一步的认识。
Web Service 和 RabbitMQ 都可以用于支持系统之间的数据交互,但它们的处理机制不同,适用场景也不完全相同。
ERP Sync Service 则说明,企业应用集成不一定只是两个业务系统之间建立一条接口。实际架构中可能存在独立的集成服务、消息中间件和其他公共组件。
这些组件都应该有清晰的职责,并纳入系统关系和依赖分析。
对于同步调用,需要关注接口响应、超时、重试和业务结果;对于异步消息,则需要进一步关注消息保存、重复处理、消费失败、积压和恢复机制。
这些问题看起来属于技术实现,但最终都与业务连续性、数据一致性和系统维护成本有关。
从 TOGAF 的角度来看,这些实践可以帮助我们逐步理解应用架构与技术架构之间的联系。
当然,了解几种集成方式,并不意味着已经完成企业应用架构设计。后续还需要结合业务流程、数据定义、系统职责和实际运行情况继续分析。
对我来说,目前更重要的是先把现有系统的关系和关键机制理解清楚,再考虑哪些地方值得改进。
下一篇,我准备继续从企业系统之间的数据交互出发,讨论数据架构中的一个基础问题:当多个系统都在使用同一类业务数据时,如何理解数据来源、数据流向,以及不同系统之间的数据一致性?
