V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Eugene1024
V2EX  ›  程序员

Java 如何实现这样的定时任务?

  •  
  •   Eugene1024 · 2017-06-17 16:53:23 +08:00 · 3713 次点击
    这是一个创建于 2476 天前的主题,其中的信息可能已经有所发展或是发生改变。

    背景:web 系统,用户规模 100 人左右,使用同一页面提交表单,用户提交表单申请后,系统短信通知相应的负责人, 负责人必须 10 分钟之内去审批,10 分钟没有审批则短信去通知负责人的领导。

    定时任务: 10 分钟没有审批就去通知相关的人

    做过的尝试:1.Java 使用 Timer,由于需要查询数据库“已提交表单记录”的状态,run 方法里查询实现不了;

    2.前端当用户提交后跳转到的页面使用 setTimeout (“ function a()”,10000 );在 function a()里面去用 ajax 去请求后端,并在后端执行查询并短信通知相应的人。 但是当一个请求执行了,该页面如果有用户再提交表单的时候 setTimeout ()会被重置,只执行了第二个的定时。

    没有使用过 Quartz,系统也没使用 SSM 之类的框架。

    16 条回复    2017-06-18 18:15:28 +08:00
    sagaxu
        1
    sagaxu  
       2017-06-17 17:06:04 +08:00 via Android
    第一个为什么 run 方法里查不了 db ?第二个是错误的办法,关掉浏览器就不通知了?
    GuDream8
        2
    GuDream8  
       2017-06-17 17:32:00 +08:00
    我的思路是这样的:
    (1) 将每个用户提交的表单记录在表里,表中有三个字段 `create_at`(表单生成的时间) ,`update_at`(表单更新的时间)
    `status`(表单的状态),负责人审批后更新 status 的值,并且更新 `update_at` 的值;
    (2)在 Linux 下将定时任务写入 cron,每分钟执行一次,当判断到 `update_at` 与 `create_at` 的间隔时间大于十分钟时,就去通知相关的人。
    ovear
        3
    ovear  
       2017-06-17 17:33:27 +08:00
    简单的解决方法:启一个消息列队
    更简单的方法:开一个 Thread 然后无限死循环
    dollar
        4
    dollar  
       2017-06-17 17:42:41 +08:00
    如果有大量后台任务处理需求,可以使用任务队列,例如 beanstalkd .设置 delay 为 10 分钟,如果 10 分钟内审批就主动删除任务,超时任务被触发就发送邮件通知.
    jaryur
        5
    jaryur  
       2017-06-17 18:19:33 +08:00 via iPhone
    不想存数据库可以存其他地方,例如文件,nosql,消息队列
    notreami
        6
    notreami  
       2017-06-17 18:21:05 +08:00
    @GuDream8 数据库存时间戳,定时轮训查库,我觉得是最简单,足够安全的方案。否则就需要引入 Quartz,zk 等等了。
    bin456789
        7
    bin456789  
       2017-06-17 18:24:37 +08:00
    croptab 定时请求
    好像很低端的样子
    coolyujiyu
        8
    coolyujiyu  
       2017-06-17 21:06:38 +08:00
    没有使用过 Quartz,那就学。。。
    快的话 20 分钟就上手,还需要咋样呢。。。
    然后定时任务扫描流程表就醒了,超过 10 分钟没处理的就预警
    microget
        9
    microget  
       2017-06-17 21:25:49 +08:00
    100 人左右的规模轮询足够了,没必要引入更复杂的方案。
    用 Timer 弄个每分钟执行的任务,筛选出 10 分钟前提交且尚未审核的记录,然后再处理。
    jianghu52
        10
    jianghu52  
       2017-06-17 22:03:55 +08:00
    我说一个很 low 的解决方案。我之前有一个 php 的 web 系统,也有类似的需求。开始用 php 调用进程。结果过几天就出一次事情。因为时钟不准。
    后来实在没辙。就用低级方案。写一个能相应事件的页面。然后在 Linux 系统下用 crontab 调用一个 python 文件。python 文件里面就 2 行代码。就是访问一下那个事件的 url。然后问题就解决了。在 Windows 下的话。也好解决。Windows 下如果没有 python 环境。那么就用定时任务启动一个进程。访问相应页面。之后进程关闭。
    Linux 下,Windows 下我实验过。虽然很 low。但是真的可以解决问题。
    orderc
        11
    orderc  
       2017-06-18 00:34:28 +08:00
    数据量小定时扫表处理,数据量大用延时消息队列。
    iminto
        12
    iminto  
       2017-06-18 01:02:17 +08:00
    1.为什么 run 方法里查不了 db ?谁告诉你的。。在者现在 Java 搞定时任务也淘汰了 Timer 类的用法,用的是更强大的 ScheduleExecutorService。

    2.错误的办法,关掉浏览器就不通知了?

    3.quartz10 分钟就能精通,为什么不去学? Quartz 和 SSM 也没有关系
    Ouyangan
        13
    Ouyangan  
       2017-06-18 11:19:24 +08:00
    springboot+@schedule
    CYKun
        14
    CYKun  
       2017-06-18 11:25:54 +08:00 via Android
    run 方法里查不了数据库我觉得有这么几个可能:

    1. OpenSessionInView 用惯了忘了开 session
    2. 切面用惯了忘了开事务
    honeycomb
        15
    honeycomb  
       2017-06-18 12:57:01 +08:00
    quartz 还是简单的
    spring 也有比 quartz 简单的任务功能
    nnxiaod
        16
    nnxiaod  
       2017-06-18 18:15:28 +08:00
    不用 Spring 也不用 Quartz,那就 Timer 了啊,,,
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3240 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 12:12 · PVG 20:12 · LAX 05:12 · JFK 08:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.