1

在当前项目中,我们需要对从系统导出的数据进行一些相当复杂的计算。计算由第三方软件处理(这对我们来说基本上是一个黑匣子)。我们有这个软件作为 Linux 或 Windows 二进制文件,并且知道如何在命令行中使用我们的数据执行它。

在一个 CPU 内核上处理单个数据集大约需要 200 小时。但是,我们可以将数据集拆分为更小的数据集(结构等效)并并行运行计算。稍后,我们可以轻松地汇总结果。我们的目标是能够在 10 小时内处理每个数据集。

我们的客户有一个专有的工作处理应用程序。该接口是基于文件系统的:我们将作业的 EXE 文件(是的,它是 Windows 支持的)和配置 INI 文件复制到传入文件夹,作业处理应用程序在其中一个节点上执行此作业(处理错误、故障转移等.) 最后将结果复制到传出文件夹。这个专有的作业处理系统有数百个 CPU 内核,因此显然有足够的能力在 10 小时内处理我们的数据集。甚至不到30分钟。

现在,问题是,到目前为止,我们的应用程序是基于 J2EE 的,或多或少的标准 JBoss 应用程序。我们需要:

  • 与专有的队列式作业处理系统集成,并
  • 以可靠的方式拆分/聚合我们的数据集。

对我来说,我们必须做的许多部分看起来非常类似于拆分器和聚合器等企业应用程序集成模式。所以我在想Apache Camel是否适合实现:

  • 我们将以消息的形式构建我们的作业(EXE + INI + 数据集)。
  • 拆分器通过将数据集分成几个较小的数据集,将大型作业消息分成较小的消息。
  • 我们可能需要实现自己的消息传递通道来将消息写入传入目录或从专有作业处理系统的传出目录读取消息。
  • 我们需要一个聚合器来将作业部分的结果聚合成一个作业的单个结果。

但是,我还没有使用 Apache Camel 的经验,所以我决定就适用性征求意见。

鉴于上述问题,您认为 Apache Camel 是否适合该任务?

结束语:我不是在寻找外部资源或工具/库建议。只是一个确认(或相反),如果我在 Apache Camel 的正确轨道上。

4

3 回答 3

3

我认为 Apache Camel 适合您的需求,因为它是迄今为止我发现的最好的集成框架之一。

我目前的项目涉及处理 ECM,必须处理可能达到每天 100 万份的大量文件。

作为输入,我们有代表一组文档(或大量文档)的 XML 文件以及指向存储在 NAS 上的真实文件的链接。

首先,我们必须将所有这些 XML 文件转换为专有 XML 格式,该格式适合我们的 ECM 系统(我们的黑盒)使用的专有文档导入器,并将它们拆分成更小的部分,以便利用多个导入队列。

然后,我们必须监控导入器队列并正确调度它们以平衡队列负载,并且在该操作之后,我们必须找出从导入器生成的输出专有格式 XML 文件中读取操作的结果。

在这个过程的每一步之间,都有一个 ActiveMQ 队列(具有数据库持久性),以保持一切异步,并且每个阶段都可以扩大,增加该特定队列上并发消费者的数量。

此外,我们的微服务是由 ESB 管理的庞大而冗长的工作流的一部分,因此我们从 ESB 提供的队列中获取输入消息,并使用小型 Web 服务将输出消息再次写回这些队列以获取/设置对象。

我们决定选择 Camel,因为它解决了许多集成问题,它可以完全控制每条路线,并且可以通过hawtio轻松监控。

此外,大部分配置都是通过编写或修改 xml 上下文文件来完成的,为您提供了灵活性并节省了您编写大量代码的时间。社区很活跃,框架更新很频繁,你可以找到很多书籍和教程。

所以我认为与我的项目目标相比,您的问题有很多联系点和亲和力,所以我再次确定使用 Apache Camel。

结果非常好。

于 2015-10-14T14:19:43.590 回答
2

你那里有一个相当复杂的用例。让我以简单的格式重新表述你想做的事情并提供我的想法。如果你看到我错过了理解的东西,请给我留言,我会修改我的帖子。

基于 JBoss 的 J2EE 应用程序,它有一个大型数据集,需要将其拆分为较小的部分,然后再转换为自定义格式。然后,此格式将被写入磁盘并由另一个应用程序处理,该应用程序将在磁盘上的输出文件夹中创建新数据结果。然后,您想要获取此输出并汇总结果。

我会说 apache camel 可以做到这一点,但您必须花时间根据您的需要正确调整系统并在您的组件上设置一些自定义配置。我想象这个过程看起来像:

from("my initial data source")
    .split().method(CustomBean.class, "customSplitMethod")
        //You might want some sort of round robin pattern to 
       //distribute between the different directories 
        .to("file://customProgramInputDirectory");

from("file://customProgramOutputDirectory")
    .aggregate(constant(true), new MyCustomAggregationStratedgy())
    .to("output of your data source");

既然您说您将与“专有的队列式作业处理系统”集成,我可能将其他程序的输入和输出误解为 fileDirectories,如果它是基于队列的系统并且它支持 jms,则有一个通用的您可以使用的模板,如果不是总是可以创建自定义骆驼组件,那么您的模式只会从说“file://”变为“MyCustomEndpoint://”

于 2015-10-14T12:27:40.527 回答
-2

答案是否定的——Camel 不是最好的框架,即使它可以延伸来模仿你所描述的内容。

Apache Camel 确实对传入的工作统一性进行了一些拆分,这些工作标识Exchange当然可以是一个文件(使用 camel-file 组件)。但是,在拆分时,每个“块”都会被发送到一个专用的Processor.

问题是块是一个Exchange本身,并且意味着被放入内存中(以便以后能够并行执行任务)。在您的情况下,我假设这部分数据仍然太大而无法在内存中处理。如果没有,Camel 会满足您的需求,甚至执行与您描述的系统集成所需的所有轮询。

您要求不要提出任何建议,但如果我是您,我会尝试使用 Spring Batch。

于 2015-10-14T13:30:11.540 回答