3

Java 定时任务求教

 1 year ago
source link: https://www.v2ex.com/t/935932
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

V2EX  ›  程序员

Java 定时任务求教

  lufeng666 · 7 小时 25 分钟前 · 1703 次点击
  • 有个需求想问下各位大佬:我想用 java 技术实现被动通知。
  • 举个例子:我每周五下午 5 点都要写周报,想创建个任务,每周五下午 5 点都会给我发邮件,通知我去写周报。
  • 要求是粒度精细到每天就行,任务都是有周期的,可能每天、每周、每月、每年。
  • 我能想到的实现方式是存个 cron 表达式到 mysql 数据库,然后每天遍历一遍看是否需要触发。但是感觉很笨,有没有那种开源的三方 jar 可以引用,能快速简洁实现这样的功能的?
46 条回复    2023-04-27 21:58:02 +08:00
Kontinue

Kontinue      7 小时 23 分钟前

难道不是一个 @Scheduled 就完事儿了吗
ilovey482i

ilovey482i      7 小时 22 分钟前

Quartz
hhjswf

hhjswf      7 小时 20 分钟前

这种事情手机定个闹钟不是更简单?
lufeng666

lufeng666      7 小时 20 分钟前

@Kontinue 每天都遍历一遍所有任务,这个方法很笨,因为大多数任务并不需要执行。数据量上来后,这个方法也特别耗性能。corn 表达式的生成与解析有没有啥好的三方库推荐的?
grance

grance      7 小时 18 分钟前

lission

lission      7 小时 16 分钟前

同 2 楼 Quartz
hidemyself

hidemyself      7 小时 15 分钟前

一个定时任务就行了
遍历每个任务看下有没有到下次执行时间,到了就执行,没到就跳过
Bingchunmoli

Bingchunmoli      7 小时 12 分钟前 via Android

同问,如果做一个用户自定义时间的定时任务,怎么轻量一点
yyfbbb

yyfbbb      7 小时 12 分钟前

用 github actions 执行规则,设置每周五定时执行就可以
doyel

doyel      7 小时 5 分钟前

写个 sendmail 用 OS 的 cron 调用,一个循环日程就能完成的事情,还要跑个应用吗。。。
linauror

linauror      7 小时 5 分钟前

感觉日历中的日程基本就可以满足你的需求(小米),可以重复每天,或者周,月,年
crazyweeds

crazyweeds      7 小时 4 分钟前

其实自己写一个也很快,Timer 就能实现。
轻量开源就是 Quartz ,但是也挺烦的其实。
fengleiyidao

fengleiyidao      7 小时 0 分钟前

Quartz +1
SmartTom

SmartTom      6 小时 51 分钟前

用分布式的 xxjob 吧
goodidea1

goodidea1      6 小时 44 分钟前

chatgpt 会给你答案
mmdsun

mmdsun      6 小时 43 分钟前

推荐 powerjob
这个作者也在 v 站
totoro52

totoro52      6 小时 40 分钟前

Quartz 还要自己写 有点麻烦, 直接上 xxl-job 吧 然后写一个发送邮件就行了 我记得里面自带, 你一句代码都不用写
wqhui

wqhui      6 小时 36 分钟前

这么简单的操作只想 crontab 懒得写应用,或者你说个复杂点的场景?
RightHand

RightHand      6 小时 31 分钟前 via Android

win 计划任务调用 jar ,Linux 就 cron 呗
SilentRhythm

SilentRhythm      6 小时 24 分钟前

延时队列是否可行,创建和触发时判断下次通知的时间,不过不知道 op 数据量有多大
Bingchunmoli

Bingchunmoli      6 小时 16 分钟前 via Android

@doyel 是想做个订阅地区天气有雨就会通知带伞的功能,如果用户可以自己输入订阅时间就有点难做,循环感觉不优雅
lufeng666

lufeng666      6 小时 14 分钟前

@mmdsun 已 star
issakchill

issakchill      5 小时 58 分钟前

@Scheduled 每天查一次 不会多耗性能的
doyel

doyel      5 小时 55 分钟前

@Bingchunmoli 那就从拉取天气接口后根据根据结果给用户推吧,前提都是有监听能让你拉起提醒来,要看具体平台和场景了。
xiongge

xiongge      5 小时 49 分钟前

你可以考虑使用 Quartz Scheduler 这个开源的 Java 库来实现你的需求。它是一个功能强大的任务调度框架,支持多种任务周期(每天、每周、每月、每年等),可以非常方便地设置任务的触发时间和频率,并且支持任务的持久化存储。

在你的应用中引入 Quartz Scheduler 库后,你可以通过编写一个 Job 类来定义你的任务逻辑,然后通过创建一个 Trigger 对象来设置任务的触发时间和频率。你还可以将任务的配置信息存储到数据库中,并且在应用启动时从数据库中读取配置信息来动态创建任务。

以下是一个使用 Quartz Scheduler 实现定时发送邮件的示例代码:

java
Copy code
// 定义一个 Job 类来发送邮件
public class SendEmailJob implements Job {
public void execute(JobExecutionContext context) throws JobExecutionException {
// 在这里编写发送邮件的逻辑
}
}

// 创建一个 Trigger 对象来设置任务的触发时间和频率
Trigger trigger = TriggerBuilder.newTrigger()
.withIdentity("sendEmailTrigger", "email")
.withSchedule(CronScheduleBuilder.cronSchedule("0 0 17 ? * FRI")) // 每周五下午 5 点触发
.build();

// 创建一个 SchedulerFactory 对象并启动 Scheduler
SchedulerFactory sf = new StdSchedulerFactory();
Scheduler scheduler = sf.getScheduler();
scheduler.start();

// 注册 Job 和 Trigger
JobDetail job = JobBuilder.newJob(SendEmailJob.class)
.withIdentity("sendEmailJob", "email")
.build();
scheduler.scheduleJob(job, trigger);
在上面的代码中,我们定义了一个 SendEmailJob 类来发送邮件,然后创建了一个 Trigger 对象来设置任务的触发时间和频率,最后将 Job 和 Trigger 注册到 Scheduler 中。在 Scheduler 启动后,当触发时间到达时,Quartz Scheduler 就会自动执行 SendEmailJob 中定义的发送邮件逻辑。

希望这个示例能够帮助你实现你的需求。
Bingchunmoli

Bingchunmoli      5 小时 47 分钟前 via Android

@doyel 做的是定时任务查询,而不是监听的
wetalk

wetalk      5 小时 45 分钟前

简单点的用 xxl-job ,不嫌麻烦手撸时间轮
lizhian

lizhian      5 小时 44 分钟前

手机助手不是更好吗
CEBBCAT

CEBBCAT      5 小时 9 分钟前

系统日历不就可以吗?几乎所有的系统都带有日历功能,日历还可以云同步。我感觉可能是文化的差异,国内都忽略了日历这种软件
chirsgod

chirsgod      5 小时 8 分钟前

PowerJob 、XXL-JOB 、Quartz 这些都可以的啊,你这个需求我感觉都用不到这种东西就能实现
aino

aino      4 小时 59 分钟前

Cron 表达式是一种用于指定定时任务执行时间的语法格式。它由 6 个字段组成,分别表示秒、分、时、日、月、周几。每个字段可以是一个数值、一组数值、一个范围、一个通配符或一些组合。

Cron 表达式的格式为:秒 分 时 日 月 周几

下面是每个字段可以包含的值:

秒:0~59
分:0~59
时:0~23
日:1~31
月:1~12
周几:0~6 ( 0 表示周日)
除了上述的数值外,还可以使用通配符*表示任意值,使用逗号,表示多个值,使用连字符-表示一个范围,使用斜杠 /表示间隔时间。

例如,下面的 Cron 表达式表示每天的上午 10 点执行一次任务:

0 0 10 * * ?

又如,下面的 Cron 表达式表示每周五晚上 10 点到 11 点之间每隔 5 分钟执行一次任务:

0 */5 22-23 ? * FRI
PVXLL

PVXLL      4 小时 50 分钟前

这种需求还需要( Mysql 数据库?,是不是还得考虑分布式、缓存、配置中心、服务发现、kubernetes ?
NGXDLK

NGXDLK      4 小时 48 分钟前

1 、java 里面 @Scheduled 注解应该就能满足
2 、不怕麻烦,搞 cron 定时任务,到点调用 java 发送邮件
NGXDLK

NGXDLK      4 小时 45 分钟前

@PVXLL 还得考虑容灾,哈哈
theOneMe

theOneMe      4 小时 40 分钟前

mac 里的提醒事项就行
uasier

uasier      4 小时 37 分钟前

非 java ,青龙面板,用着很舒服
burymme11

burymme11      4 小时 28 分钟前

@lufeng666 我大致理解你的需求了,是不是有很多个通知要推送,每个通知的调度触发点还不一样(有每周,有每月。。)?
如果是这样,个人不推荐 xxl-job 或者 Quartz 等定时调度框架,因为如果后面数据量起来了,会构建越来越多的 job/task ,指标不治本。个人推荐走延时消息,比如 A 要每天 10 点,第一次你监听处理后,再往 topic 里丢,等第二天继续,类似,mq 也会做持久化,消息一般不会丢,读写性能肯定比 db 强
zhaokun

zhaokun      4 小时 24 分钟前

iPhone 提醒 app 就可以实现
nothingistrue

nothingistrue      4 小时 22 分钟前

就是个简单的按 cron 表达式发邮件,就别折腾 Java 了,写个不到 100 行的 Shell 扔给 cronb 就行了。用 Java 其实也很简单,Spring 的 @Scheduled 就够了,连 Quartz 都用不上。除非你是往现有应用里面加这个定时功能,否则不要干这种拖裤子放屁的事,没有 Linux 的话 Window 的定时计划加 bat 脚本,也能支持。
wxw752

wxw752      4 小时 17 分钟前

@lufeng666 #4 其实定时任务扫表的方式并不笨,配合上线程池能满足很多场景了,数据量不大这么做简单高效。

如果真是有上百万要发的邮件,那时候我相信你会选择 mq
sadfQED2

sadfQED2      4 小时 9 分钟前 via Android

while(True){
sleep(1000)
if(time==XXX){发邮件}
}
direction

direction      3 小时 35 分钟前

xxl-job
oneisall8955

oneisall8955      3 小时 17 分钟前 via Android

腾讯轻联,原腾讯 hiflow ,2023 年 9 月 22 日前升级个版每月 3000 个任务,免费版 1000 个任务。感觉还行
zhady009

zhady009      35 分钟前

如果就如你描述的那样根本没必要引用什么库

如果有更复杂的要求和场景才可能需要
mundane

mundane      10 分钟前

如果 cron 表达式不用经常变的话,@Scheduled 注解就行了,多个任务就用多个 @Scheduled

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK