【问题标题】:How can I avoid duplication of business logic when batch processing?批处理时如何避免业务逻辑的重复?
【发布时间】:2015-02-12 18:18:05
【问题描述】:

我有一个专门用于批处理的 Web 应用程序(这里是批处理服务,API 驱动),我有一个专门用于其他所有事情的主 Web 应用程序。我一直在努力决定最好的方法是避免批处理服务中业务逻辑的重复。两个应用程序都是集群的。批处理的分离对于简单的工作来说是可以的,但我有更复杂的工作,如果业务逻辑被复制,它只会导致混乱。这是我用于此问题的用例。

  1. 客户为用户更新安排 cron 作业。
  2. 为批处理服务提供了一个包含 20,000 条用户记录的 CSV 文件。
  3. 批处理服务通过文件对记录执行验证,基本上是试运行。
  4. 批处理服务将检查允许的更改和错误阈值(百分比为计数)
  5. 如果通过验证阈值,批处理服务将开始创建/更新用户。
  6. 创建或更新用户时,有许多模块/功能需要了解这些事件。
  7. 跟踪工作进度,客户可以查看进度、日志和工作状态。

以下是我一直在考虑的一些解决方案:

  • 合并业务逻辑并在两个应用程序之间共享。这不一定很容易,因为主应用程序是一个 Grails 应用程序,并且到处都是 GORM。
  • 在主应用程序上设置批处理服务命中 API,以进行创建和更新以及可能更复杂的验证场景。担心这会对 tomcat 造成影响,但调用将通过负载均衡器进行分配。
  • 让批处理服务在主应用程序上命中 API 以进行验证,然后将创建/更新请求排队并让主应用程序检索它们。同上,队列有助于减少 http 调用。还需要一个队列来将状态报告回批处理服务。
  • 通过让批处理服务进行自己的验证和插入/更新来复制一些逻辑,然后触发用户创建的事件或用户更新的事件,以便主应用中的模块/功能可以处理这些更改。
  • 将批处理服务嵌入到主应用程序中

其他细节:

  • 批处理服务和 Web 应用程序都是集群的
  • 两者都在 AWS 上运行,因此我可以轻松访问 SQS 和 SNS 等工具
  • Java 1.7 应用程序
  • Tomcat 容器
  • 主要应用是 Grails
  • 批处理服务以 Spring Batch 和 Quartz 为核心

所以我的问题是,根据上述详细信息,避免业务逻辑重复的可接受方法是什么?可以/应该更改架构以更好地适应这种情况吗?

另一个需要考虑的想法是这会是什么样子以及“微服务”架构。这个词在办公室里被反复讨论过很多次,我们一直在考虑将主要的 Web 应用程序分解为服务的想法。例如,我们最终可能会提供用户管理服务。

【问题讨论】:

    标签: java batch-processing spring-batch microservices


    【解决方案1】:

    在您的情况下,我建议按关注点进行分离,我的意思是一个插件,如果使用 Grails,则只收集域类,其他插件负责服务......这些将代表应用程序核心,我认为如果您的应用程序包含太多 KLOC,这种方式会容易得多,如果您在模块之间有大量调用,使用微服务将花费您太多时间。

    功能模块之间的通信又名。插件可以通过事件制作,参见 events-si 或 rabbit MQ 插件。

    【讨论】:

      【解决方案2】:

      假设您正在使用 Java EE 6 应用程序。

      您的 CSV 批量更新程序可能只不过是一个计时器,它每隔一段时间读取一个转储到文件夹中的 CSV 文件,并且对于在该文件上编码的每个用户更新,将一条消息泵入一个编码您想要执行的更新的队列.

      在其他地方,您有一个消息驱动的 bean,它对更新请求消息做出反应,并为 JMS 消息上报告的用户触发更新业务逻辑。

      事务成功提交后,如果您有十个不同的应用程序有兴趣知道用户已更新,您可以将消息发布到,例如,带有消息类型='userUpdated' 的通知主题。 关心这个问题的 10 个应用程序中的每一个都可能是这个主题的消费者。 他们将被告知用户已更新,并可能在内部发布本地事件(例如,CDI 事件 - 番石榴事件 - 无论如何 - 内部 satke 持有者现在会这样做)。

      通常,每个技术堆栈中总会有 Java EE 替代品。 每个体面的技术堆栈都提供了促进 UI 和业务逻辑之间松散耦合的方法,因此 HTML / WEB 只是被视为应用程序业务逻辑的众多入口点之一。

      在 scala 中,我有一个看起来超级有趣的 AKKA 框架。

      关键是,只要您的业务逻辑不是写在只有 Web 应用程序可以利用的地方,就可以了。否则,您已经做出了将业务逻辑与 UI 耦合的设计决策。

      【讨论】:

      • 谢谢,我更新了用例以更清楚地说明我们需要空运行文件、跟踪作业进度并允许客户查看作业历史记录和日志。您将如何处理?
      • 同样的方式。批处理作业应用程序正在运行并将日志写入批处理应用程序可访问的某个位置。比如说,一个文件或一个适当的数据库。如果您这样做,您的 Web 应用程序可能有一个与长轮询(彗星)侦听器关联的面板,当日志表被信息触摸时,该面板会返回 UI 更新。所以在这里你的消息总线将是数据库。或者,如果您愿意,您可以简单地将您的消息从 CSV 增强到服务器,并通过更新 userId=5,remaining=50 等计数来丰富更新。 Blogic 更新,并在通知主题 50Left.
      • 当您的 Web 应用程序从通知主题中读取:CSV 作业还剩 50 个用户时,它会更新 Application Scoped bean 的状态,说:progress= 50 个用户剩余。您的 UI 将定期轮询此信息,或者如果您使用 comet,则在有更新时立即轮询。
      猜你喜欢
      • 2021-11-27
      • 2019-06-17
      • 2013-12-21
      • 2016-09-26
      • 2020-08-12
      • 2016-03-21
      • 2011-02-07
      • 1970-01-01
      • 2010-10-13
      相关资源
      最近更新 更多