企业集成模式:Spring Integration 和 Apache Camel

前段时间写了一个功能,MQTT 消息转发给 gRPC 服务端,
换成 Camel 实现,试通了感觉 Camel 挺不错。

想着以前写的 Spring 集成 MQTT 用的 Spring Integration,正好对比一下。
阅读 Spring Integration 文档,说灵感来源于《企业集成模式》这本书。
搜索发现 Spring Integration 和 Apache Camel 都属于 “集成框架”,还有一个 Mule
尝试搜集资料,总结对比一下。

《企业集成模式》

作者网站

https://www.enterpriseintegrationpatterns.com/patterns/messaging/

有内容介绍,不过还是看图比较直观

PDF【金山文档】 企业集成模式
https://kdocs.cn/l/cfbM5BO6gyYj

书第10页

书上的图不清晰,重画了一下

Spring Integration

官网

https://docs.spring.io/spring-integration/reference/index.html

Spring Integration 的简单介绍,感觉了解有一些名词即可。真正体会还是需要看图和看代码

Spring Integration 是一个基于 Spring 框架的企业集成解决方案,旨在简化不同应用程序之间消息传递通信系统集成
它提供了一种声明性的方式来定义和组织消息驱动的应用程序,通过一系列的消息通道消息处理器转换器过滤器组件来构建集成流程。

其核心思想是将应用程序拆分成可重用的消息处理模块,这些模块通过消息通道进行通信。

Spring Integration 支持多种消息传递方式,包括基于消息队列、文件、HTTP、WebSocket 等,同时也提供了与外部系统集成的能力。
通过 Spring Integration,开发者可以轻松地构建复杂的集成流程,处理不同来源和形式的消息,并能够在这些消息之间进行路由、转换、过滤、聚合等操作,以满足不同场景下的集成需求。
整合了 Spring 生态的优势,让开发者能够更加方便地在 Spring 应用中实现消息驱动的集成解决方案。

Spring 集成框架概述

这段话来自 Spring 集成框架概述

作为 Spring 编程模型的延伸,Spring Integration 提供了各种配置选项,包括注解、带有命名空间支持的 XML、带有通用“bean”元素的 XML 以及直接使用底层 API。
该 API 基于明确定义的策略接口和非侵入式的委托适配器。
Spring Integration 的设计灵感来自于 Spring 中常见模式与 Gregor Hohpe 和 Bobby Woolf 在《企业集成模式》(Addison Wesley,2004)一书中描述的知名模式之间的强烈关联。
已经阅读过该书的开发人员应该能够立即理解 Spring Integration 的概念和术语。

消息

消息通道

消息路由器

服务激活器

一个入站通道适配器端点,连接一个源系统到一个消息通道

一个出站通道适配器端点,连接一个消息通道到一个目标系统

集成 MQTT

简单的示例,介绍一下用法

Java DSL(Domain Specific Language,领域特定语言)是 Spring Integration 提供的一种编程方式,用于以流畅的方式配置消息通道、消息处理器、消息端点等集成组件。
它提供了一种直观、流畅的方法来定义整个集成流程,使得代码更易读、更易维护。

使用 Java DSL 配置 Spring Integration 可以让你通过编写代码来定义整个消息通道、消息处理器和消息端点之间的流程。
这种方式相比于 XML 配置更加灵活,并且可以利用 Java 的编程能力来完成集成流程的定义。

pom.xml 里的依赖

<!-- MQTT -->
<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-mqtt</artifactId>
</dependency>

<!-- Spring Integration Stream -->
<dependency>
    <groupId>org.springframework.integration</groupId>
    <artifactId>spring-integration-stream</artifactId>
</dependency>

使用 IntegrationFlow

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.integration.dsl.IntegrationFlow;
import org.springframework.integration.dsl.IntegrationFlows;
import org.springframework.integration.mqtt.inbound.MqttPahoMessageDrivenChannelAdapter;

@Configuration
public class MqttIntegrationConfig {

    @Bean
    public IntegrationFlow mqttInbound() {
        MqttPahoMessageDrivenChannelAdapter adapter = new MqttPahoMessageDrivenChannelAdapter(
                "tcp://localhost:1883",
                "My-ClientID-ioufev",
                "topic1", "topic2");
        adapter.setBeanName("myIntegrationFlowMqttPahoAdapter");

        return IntegrationFlows.from(adapter)
                .handle(message -> {
                    // 处理收到的 MQTT 消息
                    String payload = message.getPayload().toString();
                    System.out.println("Received message: " + payload);
                    // 在这里添加你的处理逻辑
                })
                .get();
    }
}

说明

1、MQTT 底层实现肯定是 Eclipse Paho,Spring Integration 只是封装了一层方便调用。
2、使用 Java DSL 配置的写法确实比较直观

Apache Camel

官网

https://camel.apache.org/
https://github.com/apache/camel/
https://zh.wikipedia.org/zh-cn/Apache_Camel

Camel is an Open Source integration framework that empowers you to quickly and easily integrate various systems consuming or producing data.
Camel 是一个开源集成框架,使您能够快速轻松地集成各种消费或生产数据的系统。

Apache Camel 是一个基于规则路由和中介引擎,提供企业集成模式的 Java 对象(POJO)的实现,通过应用程序接口(或称为陈述式的 Java 领域特定语言(DSL))来配置路由和中介的规则。
领域特定语言意味着 Apache Camel 支持你在的集成开发工具中使用平常的,类型安全的,可自动补全的 Java 代码来编写路由规则,而不需要大量的 XML 配置文件。
同时,也支持在 Spring 中使用 XML 配置定义路由和中介规则。

文章

Apache Camel 调研

Camel 实战第二版 第一章 初识 Camel

复制文件的例子,很好的切入点,路由的功能很好的描述了

Apache Camel 教程

这个入门介绍简洁直接有条理。

概念

以下是 Apache Camel 的一些概念:

  1. 路由(Route)- Camel 中的核心概念,它描述了如何将消息从一个端点(endpoint)传输到另一个端点,并应用一系列的转换和处理。
  2. 组件(Component)- Camel 中的组件是一组用于连接到不同数据源或目标的预定义端点。例如,JMS 组件用于连接到 JMS 队列或主题,HTTP 组件用于连接到 HTTP 服务器等。
  3. 处理器(Processor)- Camel 中的处理器用于对消息进行转换和处理。例如,过滤器、转换器、聚合器等等。
  4. 谓词(Predicate)- Camel 中的谓词是一个用于测试消息是否满足某些条件的函数。例如,判断消息是否为空,或者是否满足某些标准。
  5. 消息(Message)- Camel 中的消息是路由中的基本单元。消息通常包含一些元数据和有效负载数据。
  6. Exchange - Exchange 是在 Camel 路由中传递的消息容器。Exchange 包含消息、消息头和其他元数据。它还提供了一个机制,用于在处理器之间传递附加信息。
  7. 聚合器(Aggregator)- Camel 中的聚合器用于合并一组相关的消息。例如,将一组相关的订单合并为单个订单。
  8. 路由策略(Routing Policy)- Camel 中的路由策略用于控制路由中消息的流动。例如,从一组路由中选择一个,或者使用负载均衡策略。
  9. 触发器(Trigger)- Camel 中的触发器用于触发路由中的操作。例如,基于时间的触发器可用于定期执行某些任务。
  10. 转换器(Type Converter)- Camel 中的转换器用于将一种类型的消息转换为另一种类型。例如,将字符串转换为数字。

Camel 架构图

图片来源

在高层次上看 Camel 的架构非常简单。

CamelContext 表示 Camel 运行时系统,它连接不同的概念,如路由、组件或端点。

在此之下,处理器处理端点之间的路由和交换,而端点则集成不同的系统。

  1. CamelContext:它是 Camel 运行时的核心部分,负责管理和运行路由。在图中,它连接了不同的路由(如 Route 1、Route 2 等),并通过 DSL(领域特定语言)定义路由的行为。
  2. 路由 (Routes)路由定义了消息从一个端点流向另一个端点的路径,并且可以包含不同的处理器来操作消息。在图中,路由通过 DSL 描述,例如 .from().filter().xpath().to(),用于定义从哪里接收消息、如何处理消息以及将消息发送到哪里。
  3. 处理器 (Processors)处理器用于在端点之间对消息进行处理。图中显示了两个处理器示例:Message filter processor(消息过滤处理器)和 Content-based router processor(基于内容的路由处理器)。它们分别用于根据条件过滤消息或根据消息内容进行路由。
  4. 端点 (Endpoints)端点代表消息的源或目的地,可能是文件系统、JMS(Java 消息服务)、HTTP 等。它们通过组件来抽象实现,组件为各种技术提供了统一的接口,便于与不同系统集成。
  5. 组件 (Components)组件负责创建端点,用于处理不同的协议或技术。在图中,File、JMS、HTTP 都是组件的例子。

集成 MQTT

简单的示例,介绍一下用法

Apache Camel 是一个开源的集成框架,它提供了多种 DSL(领域特定语言)来简化集成开发。
Camel 提供了多种 DSL,其中包括 Java DSL、Spring DSL、Blueprint DSL 等,用于配置和定义路由规则、消息转换、数据路由等。

Camel 的 DSL 是为了简化和表达集成模式而设计的,让开发者能够以一种更加直观和易于理解的方式来定义路由和处理数据。
它支持不同级别的抽象,允许使用不同的语法风格来表达路由规则。

pom.xml 里的依赖

<dependency>
    <groupId>org.apache.camel.springboot</groupId>
    <artifactId>camel-spring-boot-starter</artifactId>
    <version>3.20.6</version>
</dependency>

<dependency>
    <groupId>org.apache.camel.springboot</groupId>
    <artifactId>camel-paho-starter</artifactId>
    <version>3.20.6</version>
</dependency>

配置文件 application.yml

camel:
  springboot:
    main-run-controller: true
  component:
    direct:
      enabled: true
    paho:
      broker-url: tcp://127.0.0.1
      qos: 0
      user-name: 
      password: 

示例代码

import org.apache.camel.builder.RouteBuilder;
import org.springframework.stereotype.Component;

@Component
public class MqttToFileRoute extends RouteBuilder {
    @Override
    public void configure() throws Exception {

        // 创建一个从 MQTT 主题接收消息的路由
        // paho 指的是 Paho MQTT 组件,要在配置文件中配置相关参数
        from("paho:topic1")
                .log("Received message: ${body}")
                .process(exchange -> {
                    // 处理消息
                });

        // 转发主题到另一个主题
        from("paho:topic2")
                .to("paho:topic3");

        // 将收到的消息写入到文本文件
        from("paho:topic4")
                .convertBodyTo(String.class)
                .to("file:E:\\Data\\Camel?fileName=mqtt_messages.txt");

    }
}

说明

1、MQTT 底层实现肯定是 Eclipse Paho,Apache Camel 只是封装了一层方便调用。
2、路由配置简单直接,from 和 to 方法简单直接到你觉得本来就应该是这样子。

Camel 组件

Camel 组件,真是非常多,我看到的感兴趣的有

  • 实现 MQTT 的 Paho
  • 实现 OPC UA 的 OPC UA CLIENT,当然底层驱动是 Eclipse milo
  • KAFKA
  • gRPC
  • PLC4X,PLC4X 是 Apache 的开源下项目,号称“通用协议适配器”,感觉和 OPC 的面向对象映射的思路是一致的,想通过增加一层统一的接口或者模型,来调用不同的工业协议驱动来连接 PLC
  • COAP

组织方式差异

Spring Integration:以消息通道为核心

  • Spring Integration 的核心抽象是消息通道(Message Channels)。开发者需要显式地定义这些通道,用于在系统中发送和接收消息。
  • 消息通道连接了各种端点(比如过滤器、路由器等),通过这些通道,消息得以在系统中流动和处理。
  • 这种设计的好处在于,它提供了对消息流的细粒度控制,但同时也要求开发者对通道的概念和实现有较深入的理解。

Apache Camel:以路由为核心

  • Apache Camel 的核心概念是路由(Routes)。它使用内部的交换(Exchanges)来处理消息的流动和逻辑,开发者通过定义路由来指定消息的路径。
  • 在这种方式下,消息通道的复杂性被隐藏了起来,开发者无需直接操作通道,而是专注于路由的定义和业务逻辑的实现。
  • 这使得 Camel 在快速开发和处理复杂集成场景时更加简便。

Spring 官方文档的说明

根据 Spring Integration Reference: Camel 的内容:

  • 关于 Spring Integration
    • 文档中写道:“Spring Integration fully relies on a dependency injection container from Spring Core... It also uses the MessageChannel abstraction as a first class citizen of which developers need to be aware of, when composing their integration flows.”
    • 翻译过来就是:“Spring Integration 完全依赖 Spring Core 的依赖注入容器……它将消息通道作为首要抽象,开发者在构建集成流程时需要明确了解这一点。”
  • 关于 Apache Camel
    • 文档中写道:“Apache Camel, on the other hand, does not provide a first class citizen abstraction of a message channel and proposes to compose its routes via internal exchanges, hidden from the API.”
    • 翻译过来就是:“另一方面,Apache Camel 并未将消息通道作为首要抽象,而是通过内部的交换机制来组成其路由,这些细节对 API 用户是隐藏的。”

这些描述直接表明了观点:Spring Integration 强调消息通道,而 Apache Camel 强调路由

组织方式驱动的实现思路

Spring Integration 的组织方式与实现思路

Spring Integration 的核心组织方式是消息通道(Message Channels),它的实现思路是通过通道解耦消息的生产者和消费者,实现异步、灵活的消息传递和处理。

为什么要有消息通道(Message Channels)?

  • 作用:消息通道是消息传输的媒介,负责将消息从生产者传递到消费者。
  • 原因:通过通道,生产者和消费者无需直接依赖对方,实现了逻辑上的解耦。这种设计支持异步处理,生产者可以将消息发送到通道后立即返回,而消费者可以在合适的时间从通道获取消息。
  • 类型:支持多种通道类型,例如点对点(DirectChannel)和发布-订阅(PublishSubscribeChannel),满足不同场景需求。

为什么要有入站适配器(Inbound Adapters)?

  • 作用:入站适配器从外部系统(如 JMS 队列、文件、HTTP 请求)接收数据,转换为 Spring Integration 的消息格式,并发送到消息通道。
  • 原因:外部系统的数据格式和协议各异,入站适配器作为桥梁,将这些数据适配到框架内部,保持与外部系统的解耦。

为什么要有出站适配器(Outbound Adapters)?

  • 作用:出站适配器将 Spring Integration 的消息发送到外部系统(如数据库、文件、邮件服务器)。
  • 原因:与入站适配器类似,出站适配器负责将内部消息适配到外部系统,确保消息能够正确输出,同时保持解耦。

为什么要有服务激活器(@ServiceActivator 注解)?

  • 作用@ServiceActivator 标记一个方法,使其成为消息处理的服务激活器,当消息到达指定通道时自动调用该方法。
  • 原因:通过注解驱动的方式,开发者无需手动配置消息处理逻辑,简化开发流程,提高效率,同时保持代码的可读性。

消息流动特性与流程

  • 流程
    1. 消息通过入站适配器从外部系统进入某个消息通道。
    2. 消息在通道中流动,可能经过转换器、过滤器等组件处理。
    3. 消息到达指定通道后,触发服务激活器处理,或通过出站适配器发送到外部系统。
  • 特性
    • 解耦:生产者和消费者通过通道隔离。
    • 异步:消息传递无需同步等待。
    • 可控:支持多种通道和组件,开发者可以精确控制消息流。

Apache Camel 的组织方式与实现思路

Apache Camel 的核心组织方式是路由(Routes),它的实现思路是通过简洁的路由定义来管理消息的流动路径和处理逻辑。

为什么要有路由(Routes)?

  • 作用:路由定义了消息的流动路径,从来源(from)到目的地(to),并指定中间的处理步骤。
  • 原因:路由提供了一种直观的方式来描述消息流,开发者通过 DSL(领域特定语言)就能快速定义复杂的集成逻辑,简化配置。

为什么要有端点(Endpoints)?

  • 作用:端点是消息的来源或目的地,支持多种技术(如文件、JMS、HTTP),通过 URI 配置。
  • 原因:端点抽象了外部系统的接入方式,使得 Camel 能够无缝集成不同技术,同时保持与外部系统的解耦。

为什么要有处理器(Processors)?

  • 作用:处理器在路由中对消息进行转换、过滤或自定义处理。
  • 原因:消息在流动中往往需要加工,处理器提供了灵活的扩展点,开发者可以插入自定义逻辑,满足复杂需求。

为什么要有过滤器(Filters)?

  • 作用:过滤器根据条件决定消息是否继续在路由中流动。
  • 原因:通过条件判断,过滤器支持动态路由,增强了消息处理的灵活性,例如只处理符合条件的消息。

消息流动特性与流程

  • 流程
    1. 消息从端点from)进入路由。
    2. 消息在路由中经过一系列处理器过滤器处理。
    3. 最终,消息通过端点to)发送到外部系统,或继续流向其他路由。
  • 特性
    • 简洁:路由 DSL 易于理解和维护。
    • 灵活:支持多种组件和自定义处理器。
    • 动态:过滤器和条件路由增强了适应性。

对比分析

组织方式的差异

  • Spring Integration
    • 消息通道为核心,组件(如适配器)和注解(如 @ServiceActivator)围绕通道设计,强调消息的传递和解耦。
  • Apache Camel
    • 路由为核心,组件(如端点、处理器)围绕路由设计,强调消息流动路径的定义和简洁性。

实现思路的差异

  • Spring Integration
    • 通过通道解耦生产者和消费者,借助适配器和注解实现与外部系统的集成和消息处理,适合需要精确控制的场景。
  • Apache Camel
    • 通过路由定义消息流,借助端点和处理器支持多种技术和灵活逻辑,适合快速开发和复杂集成。

消息流动特性的差异

  • Spring Integration
    • 消息在通道中流动,流程为:入站适配器 → 通道 → 服务激活器/出站适配器,强调解耦和异步。
  • Apache Camel
    • 消息在路由中流动,流程为:端点(from) → 处理器/过滤器 → 端点(to),强调简洁和动态性。

总结

  • Spring Integration 通过消息通道实现了解耦和异步,组件和注解支持精确的消息流控制,适合需要细粒度管理的场景。
  • Apache Camel 通过路由实现简洁和灵活,端点和处理器支持快速集成和动态处理,适合复杂而快速开发的场景。

通过以上分析,我们可以清晰理解两者的组织方式如何驱动其实现思路,以及它们在消息流动中的不同流程和特性。

方面 Spring Integration Apache Camel
组织方式 围绕通道(channels),组件通过通道连接 围绕路由(routes),线性定义消息流
配置方式 XML、Java DSL、Groovy DSL、Kotlin DSL Java DSL、XML DSL、YAML DSL
EIP 实现 强调通道、适配器、桥接 强调路由、端点、处理器
消息流清晰度 XML 配置可能分散,Java DSL 更直观 路由定义直观,易于追踪复杂流程
易用性 适合 Spring 项目,配置可能较繁琐 灵活,DSL 易用,尤其在复杂场景
典型用例 基本集成(如 File、JMS),Spring 生态扩展 复杂路由、多种协议支持,跨框架使用
posted @   ioufev  阅读(692)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
点击右上角即可分享
微信分享提示

目录导航