将更改日志转换为 Apache Camel 中的实际状态

Posted

技术标签:

【中文标题】将更改日志转换为 Apache Camel 中的实际状态【英文标题】:Translating change log into actual state in Apache Camel 【发布时间】:2014-12-01 13:53:13 【问题描述】:

我有两个系统,分别称为 A 和 B。 当 A 中某些重要的对象发生变化时,A 通过 Apache Camel 将其发送给 B。 但是,我遇到过一种情况,当 A 实际上具有对象的更改日志时,而 B 必须仅反映对象的实际状态。 此外,A 中的更改日志可以包含“未来”记录。 这意味着,该对象的状态更改安排在未来的某个时刻。 系统 A 的用户可以编辑此更改日志、删除更改记录、添加具有任何时间戳(过去和将来)的新更改记录,甚至更新现有更改。 当然,A 将这些变更记录发送给 B,但 B 只需要对象的实际状态。

请注意,我可以从 A 查询对象,但 A 是一个性能关键系统,因此我不打算查询某些内容,因为它会导致额外的负载。 此外,用于从 A 查询数据的 API 过于复杂,我希望尽可能避免使用它。

我可以在这里看到两个问题。 首先是意识到变更日志记录中的特定变化是否会导致实际状态的变化。 我要将更改日志存储在中间数据库中。 随着更改日志记录的到来,我将在中间数据库中添加/删除/更新它,然后计算对象的实际状态并将此状态发送给 B。

其次是跟踪变更计划。 除了以固定的时间间隔(比如 15 分钟)运行定期作业之外,我什么都不能发明。 此作业将扫描从上次调用到当前调用的时间间隔内的所有记录。

我喜欢 Apache Camel 的原因在于它基于组件的方法,当您只需要连接端点并完成所有工作时,只需少量编码。 在 Apache Camel 和 EIP 中是否有任何预先存在的原语来解决这个问题?

【问题讨论】:

您说从 A 查询数据的 API 过于复杂。您打算如何从 A 获取数据? A是否有任何推送机制?你要直接访问A的仓库吗?你要修改A吗?如果是这样,为什么不添加更好的 API 来使用一些缓存机制进行查询以保护性能? 当 A 检测到某个实体被更改时,它会将其序列化为 XML 并将其写入文件系统中的文件中。我使用以下消费者:<from uri="ftp://path-to-directory">。此外,A 有一个推送所有数据的机制,我将使用它来进行数据的初始加载。我不拥有 A 的代码,我既不能影响它的查询 API,也不能引入缓存。此外,这是一个政策问题:如果我能证明这条总线不会影响 A 的性能,那么说服 A 的所有者允许访问集成总线要容易得多。 您的情况并非微不足道,我不相信您能找到任何灵丹妙药的解决方案。最接近的组件 AFAIK 是camel.apache.org/cache.html。如果不合适,您可以随时使用 Camel 提供的所有附加功能(如事务、监控等)为您定制基于 DB 的解决方案 【参考方案1】:

我实际上正在研究一个非常相似的用例,其中系统 A 发送 快照和更新,这需要在发送到系统 B 之前进行翻译。

首先,您需要从系统 A 触发为您提供初始状态(“快照”)的机制,timer: 组件可以启动一次性启动逻辑。

现在,您将收到快照数据(您没有指定如何接收,可能是ftp 文件或jms 端点)。验证数据,将其拆分为项目,并将每个数据项目存储在本地内存中 cache:,正如 Sergey 在他的评论中所建议的那样,唯一键控。使用合乎逻辑的过期策略(例如 48 小时)。

从那里,不断处理来自ftp: 端点的“更新”数据。对于每次更新,您都需要将更新与 cache: 中的数据进行匹配,并确定需要将什么(以及何时)发送到系统 B。

稍后需要发送到系统 B 的数据需要保存在内存或数据库中。

最后,您需要一个调度机制来确定每 15 分钟是否应该发送新数据,您可以轻松地使用timer:quartz: 来实现这一点。

总之,您可以从以下组件构建此集成:timercacheftpquartz 以及一些自定义 bean/处理器来执行自定义逻辑。

主要挑战是处理缓存然后更新的数据,并制定控制机制,以应对在初始连接、断开连接或骆驼应用程序重新启动时应该发生的情况。

祝你好运;)

【讨论】:

以上是关于将更改日志转换为 Apache Camel 中的实际状态的主要内容,如果未能解决你的问题,请参考以下文章

Apache Camel 遍历列表

替代Apache Camel中已弃用的XmlJsonDataFormat

如何在apache camel DSL或camel Processor内部设置其他身份验证属性?

Apache camel - SQL到CSV

如何将属性与 Spring XML 中 Apache Camel 路由中的(布尔)文字进行比较?

当异常消息转到camel中的deadLetterChannel时,如何将MultipartEntityBuilder转换为inputStream?