《TOGAF学习之路》企业架构实践(三):企业应用集成——从 Web Service 到消息队列

企业架构实践(三):企业应用集成——从 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 处理请求后返回结果。

整个过程可以简化为:

  1. ERP 发起请求。
  2. WMS 接收请求。
  3. WMS 执行相应处理。
  4. WMS 返回响应。
  5. ERP 根据响应结果继续处理。

在这种模式下,调用方通常需要等待被调用方返回响应,才能根据结果决定下一步操作。

这就是同步调用的基本思路。

这里需要注意,同步调用并不意味着整个业务流程一定在一次请求中全部完成。接口可能只完成查询、校验或接收请求等操作,后续业务处理仍然可能在后台执行。

同样,接口返回成功,也需要明确它所代表的成功含义。

例如,接口返回成功可能只表示请求已被接收,并不一定意味着所有后续业务处理都已完成。

因此,设计接口时,需要明确请求、响应和业务处理结果之间的关系。

2.2 异步消息:发送方与接收方可以分开处理

另一种方式是使用消息队列。

发送方将消息发送到消息中间件,接收方再从中获取消息并进行处理。

简化后的过程如下:

  1. 发送方准备业务消息。
  2. 消息被发送到 RabbitMQ。
  3. 消费方获取消息。
  4. 消费方执行相应业务处理。
  5. 根据实际设计,消费方确认消息处理状态。

这种方式允许发送方和接收方在一定程度上独立运行。

例如,发送方成功将消息交给消息中间件后,通常不需要等待接收方完成全部业务处理,便可以继续执行其他工作。

但这里同样需要注意:消息发送成功,不等于接收方已经完成业务处理。

如果业务要求确认最终处理结果,就需要进一步设计处理状态、结果反馈、异常记录等机制。

异步消息并不意味着可以不关心处理结果,只是把发送与处理分成了不同阶段。

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 的角度来看,这些实践可以帮助我们逐步理解应用架构与技术架构之间的联系。

当然,了解几种集成方式,并不意味着已经完成企业应用架构设计。后续还需要结合业务流程、数据定义、系统职责和实际运行情况继续分析。

对我来说,目前更重要的是先把现有系统的关系和关键机制理解清楚,再考虑哪些地方值得改进。

下一篇,我准备继续从企业系统之间的数据交互出发,讨论数据架构中的一个基础问题:当多个系统都在使用同一类业务数据时,如何理解数据来源、数据流向,以及不同系统之间的数据一致性?

Leave a Reply

Your email address will not be published. Required fields are marked *