【问题标题】:Best approach for a Java Web Application to call an external API only 4 times a day (accounting for daylight saving)Java Web 应用程序每天仅调用 4 次外部 API 的最佳方法(考虑夏令时)
【发布时间】:2021-08-05 05:10:31
【问题描述】:

我们有一个 Java Web 后端服务在 2 个生产服务器上运行,每个生产服务器中有 2 个 JVM,位于 Websphere Application Server 的负载平衡器后面。

我的用例:

  • 部署后首次调用外部 API。
  • 如果响应.OK
    • 在外部数据存储中缓存响应(与此问题无关)
  • 对于当天的下一个客户端请求,如果请求的时间不等于或紧接在一组时间(9:00、11:00、13:00、15:00)之后
    • 返回缓存的响应
  • 如果客户端请求恰好在集合中的任何给定时间(9:00、11:00、13:00、15:00)
    • 调用外部 API 并更新缓存(不再相关)。例如,请求在 9:00 发出
  • 对于9:00到10:59的所有后续请求(因为集合中的下一个时间是11:00)
    • 返回缓存的响应
  • 11:00
    • 调用外部 API 并更新缓存
  • 等等..

这样一天内只有四个外部 API 请求,而不是每个请求都直接调用外部 API。

如何在所有生产服务器的 Java 应用程序级别实现这一点,考虑到特定时区的夏令时,而无需任何网络或 IO 编程?

注意:该应用程序不使用 Spring boot。我正在尝试纯粹用 Java 来做这件事。

【问题讨论】:

  • @sanjeevRm 我将看看运行 cron 作业 Sanjeev,但必须有某种方法可以做到这一点,而不依赖于外部库,只依赖于 Java,比如使用 Scheduled Executor Service 或 type 4 个 UUID。
  • 你可以在java中使用java.util.Timerjava.util.TimerTask调度任务,Timer有schedule方法,这涉及到线程,如果处理不当会变得复杂
  • 您是限制每个 jvm 4 次调用还是每个所有 JVM 4 次调用?如果每个 JVM 为 4,最简单的方法是将您的时间 (9,11..) 作为参数传递,并简单地将上次调用的时间存储在缓存中,如果缓存较旧则刷新缓存(同步刷新块)。如果在所有 JVM 中只有 4 次调用,则需要使用共享缓存和更复杂的刷新逻辑以仅允许单个并发刷新。

标签: java performance rest websphere system-design


【解决方案1】:

因为您使用的是 JEE 应用程序服务器,所以如果可能,您应该使用符合规范的方法来提供最大的可移植性。您没有在帖子中提及您使用的是 Liberty 还是传统的 WebSphere。

如果您使用 Liberty,管理异步任务的一种符合 JEE 规范的方法是 ManagedScheduledExecutorService。 If 提供调度功能并为您处理线程。从以下信息开始:​​https://www.ibm.com/docs/en/was-liberty/base?topic=manually-configuring-managed-scheduled-executors

如果您使用的是传统的,那么所提供的 JEE 支持级别没有在 JEE 托管环境中处理异步任务的规范兼容方法。您可以使用符合 JSE 规范的 ScheduledExecutorService,但与托管版本不同的是,它不是为在您希望服务器为您管理所有资源(如线程)的应用服务器环境中使用而设计的。您将负责线程,并且需要考虑在 JEE 环境中使用非托管线程的影响(不是推荐的模式)。为避免这种情况,您可以使用此处描述的 WebSphere Scheduler 服务:https://www.ibm.com/docs/en/was/9.0.5?topic=calendars-scheduler

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-14
    • 2023-03-26
    • 2013-09-22
    • 1970-01-01
    • 2018-09-19
    • 1970-01-01
    • 2018-01-01
    • 2012-07-03
    相关资源
    最近更新 更多