【问题标题】:Is it okay to manage scheduled jobs with Servlet state?可以使用 Servlet 状态管理计划作业吗?
【发布时间】:2015-09-03 11:18:22
【问题描述】:

我的 Web 应用程序需要允许不同位置的用户可能为每个位置安排一项数据导入作业。每项工作可能需要很长时间才能完成。一个位置可能有多个用户可以同时安排作业(使用不同的时间表),在这种情况下,最后提交的时间表胜出。可以随时取消和修改计划。此外,可以随时添加新位置(及其时间表)。我正在使用 JDK 1.6 和原始 servlet。

鉴于线程安全问题和对 servlet 状态的依赖,我的以下计划似乎充满了危险。

计划:

  1. 使用 ScheduledExecutorService 在 servlet 的 init() 方法中调度作业。 ServletContextListener 是通常推荐的安排作业的地方,但鉴于 HttpRequest 可能会到达以更改现有作业的日程安排,我似乎需要:

  2. 使用成员变量 map<location, ScheduledFuture<?>> 跟踪 servlet 中计划的作业线程。我知道在 servlet 中保持状态被认为是不好的,但就我而言,这似乎是必要的,以便我可以:

  3. 取消计划的作业线程,并在用户请求时使用已知位置作为上面地图的键重新计划它。这部分似乎需要同步块,但块应该快速执行,同时访问应该仅限于少数用户。 这似乎是使用同步的有效用例吗?

可以使用 Servlet 状态管理计划作业吗?您在我的计划中发现了哪些漏洞,以及按照我的意愿做事的更好方法是什么?

谢谢!

【问题讨论】:

    标签: java multithreading servlets scheduled-tasks


    【解决方案1】:

    不要在 servlet 中进行工作,而是在离线进程(不属于 Web 应用程序的程序)中进行。让 servlet 简单地充当离线进程的触发机制。有多种方法可以完成触发过程(文件传输、共享数据库、消息传递或远程过程调用)。请参阅enterprise integration patterns 作为起点。

    在离线程序中进行处理的好处是您不需要在 servlet 中管理状态,这会导致代码更加模块化。

    编辑:为清楚起见进行了编辑。

    【讨论】:

    • 我用过类似的东西。添加信息。到 DB -> crontab 触发 -> python 代码检查 DB,如果需要,处理和更新 DB。 -> 对 Web 应用程序的下一个请求显示更改。另外:我从未见过在基于非事务的上下文中使用 servlet。
    • @Ross 和 user4704303,感谢您的想法。数据库听起来很简单(因为我已经在使用它了),但这听起来像是轮询解决方案而不是推送,这对我的需求来说不一定是坏事。但是,调度程序似乎并没有按照我理解的方式被使用——调度重复的工作。相反,它会安排一个作业来检查是否应该开始一个新作业。我想远程过程会是一个推送,但不确定我是否要设置它。
    • 我打算写一个答案,但根本没有足够的知识来提供我完全有信心的足够质量的答案。我能说的是我确实认为它对同步有效,因为 servlet 是多线程的,并且该变量会发生变化。我认为您不需要在 servlet 中使用 init() 方法。也许一旦您在 ServletContextListener 的帮助下定义了 ScheduledExecutorService(有关更多信息,请参见:stackoverflow.com/q/4691132/539394),您可以使用 servlet 中的 getServletConfig() 方法访问它?消除对 servlet 变量的需要。
    • 还有.. 例外情况会发生什么:code.nomad-labs.com/2011/12/09/…
    猜你喜欢
    • 2022-11-01
    • 1970-01-01
    • 2019-03-02
    • 2016-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多