添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

由于公司项目的需求,有时候需要更改系统时间,当把系统时间从当前(T1)往未来时间(T2)调整的话没什么问题,但是再从未来时间(T2)往回调整就会造成定时任务挂起的情况。网上也找了很多资料,但是没有什么合适的解决方案,很多文章提供的解决方案就是→重启项目!!!(我竟无言以对)。
然后呢,就自己想了个解决方案,当然只是完成了需求,在性能方面其实不好。希望有更好解决方案的前辈留言指点一下。

定时任务大概分三类:
1.是java自带的Timer+TimerTask
2.是基于注解式的实现 @Scheduled(…)
3.是定时任务框架 如quartz 这样。
本文是使用注解的方式开发的。关于Timer+TimerTask 以及注解式的基础讲解就不再介绍了,网上有很多写的很好的博客需要的童鞋可以去看一下。这里就说下我的解决思路吧。

首先来说,定时任务执行时间的配置有两种:
1.cron表达式(绝对时间)
2.fixedRate(相对时间)
这里简单说一下上述的绝对时间意思是:
cron表达式中会涉及到绝对时间比如:每天凌晨2点执行 。那么它计算执行时间的方式是通过系统时间算出来的,也就是说如果用cron表达式来配置的话那么你更改系统时间就会影响到你的定时任务,举个简单的例子:比如第一次执行任务的时间为9:00,执行间隔为1小时一次;那么下次执行的时间应该是 10:00 而如果你修改系统时间就可能会造成定时任务的失效;

而fixedRate相对时间的意思是:计算执行时间的方式是根据项目启动的时间来算出来的,是从项目启动时间开始计算的。比如:第一次执行任务的时间为9:00,执行间隔为1小时一次;那么下次执行的时间应该是 一个小时以后 。也就是说它是通过记录你上次任务执行了多久来判断下次任务的触发时机。它不关心你的系统时间是多少。所以这种方式能够很好的解决我们更改系统时间的需求。

@Scheduled(fixedRate=6000L)//这里表示项目启动后执行一次,然后每间隔6秒钟任务执行一次,
public void run(){
//...任务代码
@Scheduled(fixedRate=6000L,initialDelay=6000L)//这里表示项目启动后6秒钟执行一次,然后每隔6秒执行一次。
public void run(){
//...任务代码

到这里,已经解决掉一部分问题了!
最关键的部分来了: cron表达式可以配置任意时间,比如刚才提到的:每天两点执行一次任务。 那么此时就遇到问题了,刚才说了fixedRate的判断机制是通过相对时间来确定的,压根和系统时间没半毛钱关系。那么如何来完成这个需求呢。先看下代码:

@Scheduled(fixedRate = 60000L)
public void run(){
	//获取当前系统时间,判断当前系统时间是否为凌晨2点
	SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
	if(!sdf.format(System.currentTimeMillis()).equals("02:00")){
		return;
	...任务代码

大致思路就是通过fixedRate的方式来触发定时任务,然后在任务方法中拿到系统时间进行验证,如果不到2点就return出去,这样就实现了功能上行的需求。

这种方法缺陷也很明显,就是每分钟都需要启动一次定时任务,看起来很呆。比较浪费资源,苍蝇再小也是肉哇。 但是对于我当前的项目来说这个需求是非常重要的。浪费点资源也是值得的。
最后,希望有更好解决方案的童鞋或者前辈能够给指点一下。

由于公司项目的需求,有时候需要更改系统时间,当把系统时间从当前(T1)往未来时间(T2)调整的话没什么问题,但是再从未来时间(T2)往回调整就会造成定时任务挂起的情况。网上也找了很多资料,但是没有什么合适的解决方案,很多文章提供的解决方案就是→重启项目!!!(我竟无言以对)。然后呢,就自己想了个解决方案,当然只是完成了需求,在性能方面其实不好。希望有更好解决方案的前辈留言指点一下。定时任务大概...
目录:(1#)代表第一层楼,以下类推<br><br>2000XP双系统启动问题 (1#)<br> <br>ADSL拨号中出现的错误代码(2#)<br><br>at命令的用法(3#)<br><br>AWARD BIOS设置详解 (上)(4#)<br><br>AWARD BIOS设置详解( 下)(5#)<br><br>BB是报警的声音(6#)<br><br>开机BIOS语言(7#)<br><br>BIOS可以被映射(8#)<br><br>BIOS与CMOS区别(9#)<br><br>CMOS密码清除方法(10#)<br><br>在DOS下安装Win XP(11#)<br><br>在DOS中使用系统还原工具(12#)<br><br>Explorer.exe程序在系统中的作用(13#)<br><br>folder.htt等文件的问题(14#)<br><br>found.000文件夹的问题(15#)<br><br>让IE以最大化显示(16#)<br><br>Mfm1992文件问题(17#)<br><br>Regsvr32 用法和错误消息的说明(18#)<br><br>Regsvr32使用方法(19#)<br><br>Regsvr32命令修复系统故障(20#)<br><br>RUNDLL32.EXE 是什么程序(上)(21#)<br><br>RUNDLL32.EXE 是什么程序(下)(22#)<br><br>SFC使用方法(23#)<br><br>Windows2000/XP启动过程详解(24#)<br><br>Win2000进程(25#)<br><br>在Windows 2000使用纯DOS的方法(26#)<br><br>Win2000设置技巧(27#)<br><br>Windows常用命令集(28#)<br><br>巧妙安装各种Windows操作系统(29#)<br><br>windows下的EXE文件大揭密(30#)<br><br>Windows XP 常见的进程列表(31#)<br><br>xp的boot.ini文件内容(32#)<br><br>windowsXP你不可不知道的秘密哦!~(33#)<br><br>WinXP开机菜单含义(34#)<br><br>XP轻松实现免激活升级(35#)<br><br>{XP去除开机登陆画面!)(36#)<br><br>WinXP瘦身办法(37#)<br><br>XP瘦身,减肥大全(38#)<br><br>体验Windows XP系统内置的AT命令(39#)<br><br>WinXP/2000操作系统自动关机的实现(40#)<br><br>WINXP优化精髓1(41#)<br><br>WINXP优化精髓2(42#)<br><br>WINXP优化精髓3(43#)<br><br>WINXP优化精髓4(44#)<br><br>在Windows XP中对文件进行加密(45#)<br><br>在Windows XP中运行DOS程序(46#)<br><br>XP重装需要激活的问题(47#)<br><br>巧妙安装各种Windows操作系统(48#)<br><br>操作系统进程描述1(49#)<br><br>操作系统进程描述2(50#)<br><br>操作系统进程描述3(51#)<br><br>操作系统系统配置(52#)<br><br>常遇电脑故障应急处理方法(53#)<br><br>常见死机原因剖析(54#)<br><br>【关闭系统时的死机】(55#)<br><br>处理冲击波(56#)<br><br>磁盘格式的问题(57#)<br><br>电脑死机故障分析(58#)<br><br>更改IE的默认搜索引擎(59#)<br><br>更改临时文件夹的路径(60#)<br><br>更改屏幕保护程序关联方式(61#)<br><br>调整调出输入法的顺序(62#)<br><br>更改系统源文件途径(63#)<br><br>工具地址(64#)<br><br>关闭WinXP的错误报告(65#)<br><br>快速关闭没有响应的程序(66#)<br><br>黑屏的几个原因(67#)<br><br>恢复“开始”菜单中的“运行”(68#)<br><br>加快WinXP窗口显示速度(69#)<br><br>加快软驱传输速度(70#)<br><br>解决A盘不见的方法(71#)<br><br>解决EXE关联丢失方法(72#)<br><br>解决IE二级链接方法(73#)<br><br>解决IE器常见故障(77#)<br><br>解决IP地址冲突的方法(75#)<br><br>解决NTFS下Win2000密码丢失(76#)<br><br>解开被锁定的.reg与.inf文件(77#)<br><br>Windows98不能正常关机解决法(78#)<br><br>解决WinXP启动问题(79#)<br><br>解决WinXP搜索故障(80#)<br><br>解决XP输入法不见问题(81#)<br><br>解决XP搜索失效问题(82#)<br><br>解决不定时搜寻软驱问题(83#)<br><br>部分软件无法安装(84#)<br><br>解决插电即开机问题(85#)<br><br>解决窗口按钮上乱码问题(86#)<br><br>打开硬盘分区出错(87#)<br><br>注册表文件不出现确认对话框(88#)<br><br>多系统安装(89#)<br><br>解决多硬盘盘符混乱问题(90#)<br><br>系统关机变重启故障(91#)<br><br>光驱读盘不正常(92#)<br><br>回收站无法清空(93#)<br><br>解决活动窗口按钮被改写(94#)<br><br>解决接通电源后自动开机问题(95#)<br><br>操作系统停止响应(96#)<br><br>解决开机ESCD错误(97#)<br><br>开始菜单响应速度过慢(98#)<br><br>解决控件提示问题(99#)<br><br>解决某些网页不能访问(100#)<br><br>“内存不足”的解决方法(101#)<br><br>任务栏的图标变大了(102#)<br><br>解决鼠标乱动问题(103#)<br><br>解决鼠标右键被锁定(104#)<br><br>解决“添加删除程序”里面隐藏问题(105#)<br><br>win98图标老乱套,与文件类型不配(106#)<br><br>网页恶意代码的十一大危害及其解决方案(107#)<br><br>找回Administrator账户密码(108#)<br><br>"文件保护"的解决方法(109#)<br><br>双击无法打开文件夹(110#)<br><br>解决无法关机问题(111#)<br><br>无法升级更新(112#)<br><br>系统无法自动保存设置(113#)<br><br>解决系统声音不正常(114#)<br><br>解决系统托盘区的图标丢失(115#)<br><br>系统无法自动保存设置(116#)<br><br>解决系统资源不足问题(117#)<br><br>解决系统资源严重不足(118#)<br><br>解决显示器花屏问题(119#)<br><br>“蓝屏”的几个原因(120#)<br><br>解决限制使用应用程序问题(121#)<br><br>音量为何会自动调节(122#)<br><br>应用程序不能启动(123#)<br><br>解决硬盘坏磁道问题(124#)<br><br>硬盘引导型故障分析及排除(125#)<br><br>加快右键菜单的响应速度(126#)<br><br>解决右键发送到问题(127 #)<br><br>解决桌面图标乱的方法(128#)<br><br>解决自动搜索软驱(129#)<br><br>禁用指定DOS命令办法(130#)<br><br>禁止ipc$默认共享的方法(131#)<br><br>禁止Win2000启动时读软驱(132#)<br><br>禁止winxp的默认硬盘共享(133#)<br><br>禁止WinXP文件夹自动展开(134#)<br><br>禁止光盘自动运行(135#)<br><br>控制面板大全(136#)<br><br>破解IE分级密码(137#)<br><br>破解网页禁用鼠标右键(138#)<br><br>巧妙清除Windows XP任务栏的隐藏图标记录(139#)<br><br>取消磁盘扫描(140#)<br><br>取消磁盘扫描前的等待时间(141#)<br><br>如何保存网页的背景音乐(142#)<br><br>如何彻底删除输入法文件(143#)<br><br>如何防止恶意网页篡改注册表(144#)<br><br>如何关闭CD自动播放功能(145#)<br><br>如何关闭Dr.Watson(146#)<br><br>NTFS格式下加、解密问题(147#)<br><br>如何进入BIOS设置?(148#)<br><br>如何启动休眠功能(149#)<br><br>如何清除冰河(150#)<br><br>如何让注册表保持在根目录(151#)<br><br>如何设置从光驱启动(12#)<br><br>设置“显别人的IP”(153#)<br><br>电脑显示器的相关设置与常见故障排除方法(154#)<br><br>如何实现关机时清空页面文件(155#)<br><br>如何使IE不再发送错误报告(156#)<br><br>如何使用Tasklist命令(157#)<br><br>如何使用系统还原(158#)<br><br>如何锁住桌面背景(159#)<br><br>如何挽救已受物理损坏的软盘中的文件(160#)<br><br>如何移动收藏夹(161#)<br><br>如何隐藏磁盘驱动器(162#)<br><br>如何优化电脑系统的BIOS?(163#)<br><br>如何找到自启动程序(164#)<br><br>如何直接移动应用程序(165#)<br><br>重新安装IE浏览器(166#)<br><br>如何自动重启(167#)<br><br>删除右键菜单的内容(168#)<br><br>删除NTFS分区(169#)<br><br>删除屏幕保护和壁纸(170#)<br><br>删除启动选项中的选项(171#)<br><br>删除遗留的鼠标右键菜单项(172#)<br><br>删除“添加/删除程序”中的无效信息(173#)<br><br>删除系统备份文件(174#)<br><br>删除信使服务(175#)<br><br>删除虚拟光驱创建的盘符(176#)<br><br>删除隐藏不活动的图标(177#)<br><br>设置窗口自动刷新(178#)<br><br>设置开始菜单中的用户名(179#)<br><br>设置任务管理器(180#)<br><br>设置虚拟内存(181#)<br><br>什么时信使服务(182#)<br><br>什么是 DirectX(183#)<br><br>什么是host表(184#)<br><br>什么是POP3(185#)<br><br>什么是丢包(186#)<br><br>端口概念1(187#)<br><br>端口概念2(188#)<br><br>什么是软件版本标志(189#)<br><br>双系统安装方法(190#)<br><br>双系统的安全卸载(191#)<br><br>双系统共用虚拟内存(192#)<br><br>双系统默认启动项更改(193#)<br><br>双系统问题集合(194#)<br><br>双系统问题集合(195#)<br><br>通过CMOS设置定时开机(196#)<br><br>为文件夹添加背景音乐(197#)<br><br>限制驱动器的使用(198#)<br><br>虚拟软驱(199#)<br><br>隐藏光驱的方法(200#)<br><br>隐藏控制面板中的选项(201#)<br><br>隐藏启动程序方法(202#)<br><br>隐藏驱动器一法(203#)<br><br>隐藏添加删除程序(204#)<br><br>隐藏桌面‘回收站’的两个方法(205#)<br><br>隐藏桌面所有图标(206#)<br><br>处理硬盘物理坏道方法(207#)<br><br>运行命令(208#)<br><br>在Windows 2000使用纯DOS的方法(209#)<br><br>在Windows XP中运行DOS程序(210#)<br><br>找回“显示桌面”按钮(211#)<br><br>找回丢失的桌面图标透明效果(212#)<br><br>自动安装Windows XP(213#)<br><br>自动关闭停止响应程序(214#)<br><br>关闭小键盘上的NumLock(215#)<br><br>清除地址栏中的记录(216#)<br><br>自动释放系统资源(217#)<br>
简单定时任务解决方案:使用redis的keyspace notifications(键失效后通知事件) 需要注意此功能是在redis 2.8版本以后推出的,因此你服务器上的reids最少要是2.8版本以上; (A)业务场景: 1、当一个业务触发以后需要启动一个定时任务,在指定时间内再去执行一个任务(如自动取消订单,自动完成订单等功能) 2、redis的keyspace notifications 会在key失效后发送一个事件,监听此事件的的客户端就可以收到通知 (B)服务准备: 1、修改reids配置文件(redis.conf)【window系统配置文件为:redis.windows.conf
  基于上一篇文章,本来做好的NTP对时功能,结果发现一个致命缺陷,将系统时间修改到未来某个时间,然后启动定时器,此时如果再将系统时间改回当前的正确时间,发现定时器挂起了,不运转了。遂查找资料,发现是定时器内部实现的原因。 这个问题我们可以简单跟踪下Timer的源码,Timer中有两个重要的对象,一个是TaskQueue,一个是TimerThread。 TaskQueue 是一个队列,里面放的就是我们调用Timer.schedule时传的参数task。TimerThread 是一个线程,继承
时区切换对Quartz的cron表达式有影响,切换的1小时内停止触发定时任务,导致sla没有定时清空内存计数,误发限流。 美国夏令时PST切换到冬令时PDT,会有时间跳变。不带时区跳变的,会出现时间重叠或不连续 问题复现 mac本机模拟,把时区换成美国的,然后把时间调到11月5号01:59 import java.text.ParseException; import java.ut...
Android 替换ScheduledFuture定时器解决修改系统时间引起Timer定时器挂起问题 大家知道平时使用的Timer定时器时,如果修改系统时间(将系统时间修改到当前前面的时间)会引起imer定时器挂起 我们替换定时任务ScheduledFuture 可以避免这个问题 简单用法如下: 启动计时: private ScheduledExecutorService service; pr...
今天在系统定时任务中发现了一个问题,一旦修改系统时间,把系统时间调到当前时间之后(即大于当前时间T1)T2,Timer线程正常执行;如果再将系统时间修改到当前时间之前T3(即T3小于T2),那么Timer线程就会挂起,或者假死,此时不会再执行定时任务,好像线程已经死掉一样。 我们可...
在 Django 中使用 Apscheduler 实现定时任务时,服务重启后定时任务失效的原因是因为 Apscheduler 的默认存储方式是内存存储,当服务重启后,内存中的数据会被清空,导致定时任务信息丢失。 为了解决这个问题,可以将 Apscheduler 的存储方式改为数据库存储。具体实现步骤如下: 1. 首先安装 Apscheduler 和 Django 的数据库驱动,比如 psycopg2 或者 mysqlclient。 2. 在 Django 项目的 settings.py 文件中配置数据库信息: DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'your_db_name', 'USER': 'your_db_user', 'PASSWORD': 'your_db_password', 'HOST': 'localhost', 'PORT': '5432', 3. 在 Django 项目的 settings.py 文件中添加 Apscheduler 的配置信息: SCHEDULER_JOBSTORES = { 'default': SQLAlchemyJobStore(url='postgresql://your_db_user:your_db_password@localhost/your_db_name') SCHEDULER_EXECUTORS = { 'default': {'type': 'threadpool', 'max_workers': 20} SCHEDULER_JOB_DEFAULTS = { 'coalesce': False, 'max_instances': 3 SCHEDULER_API_ENABLED = True 其中,`url` 参数的格式为:`<database>://<user>:<password>@<host>/<database_name>`,根据自己的数据库信息进行修改。 4. 在 Django 项目的 urls.py 文件中注册 Apscheduler 的 API: from apscheduler.scheduler import Scheduler from apscheduler.jobstores.sqlalchemy import SQLAlchemyJobStore from django_apscheduler.jobstores import DjangoJobStore from django_apscheduler import util scheduler = Scheduler( jobstores={ 'default': DjangoJobStore(), 'sqlalchemy': SQLAlchemyJobStore(url='postgresql://your_db_user:your_db_password@localhost/your_db_name') executors={ 'default': {'type': 'threadpool', 'max_workers': 20} job_defaults={ 'coalesce': False, 'max_instances': 3 timezone=util.get_timezone('Asia/Shanghai') # 添加定时任务 def test_job(): print("test job") scheduler.add_job(test_job, 'interval', seconds=10) # 启动定时任务 scheduler.start() # 注册 API from django.urls import path from django_apscheduler.views import DjangoJobView, DjangoJobAllView, DjangoJobRunView urlpatterns = [ path('admin/', admin.site.urls), path('jobs/', DjangoJobView.as_view()), path('jobs/all/', DjangoJobAllView.as_view()), path('jobs/run/<job_id>/', DjangoJobRunView.as_view()), 其中,`scheduler.add_job()` 函数用于添加定时任务,这里添加了一个每隔 10 秒执行一次的测试任务。 5. 在 Django 项目的 wsgi.py 或者 asgi.py 文件中启动 Apscheduler: import os from django.core.wsgi import get_wsgi_application from apscheduler.schedulers.background import BackgroundScheduler os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'project.settings') application = get_wsgi_application() scheduler = BackgroundScheduler() scheduler.add_jobstore('django', 'default') scheduler.start() 在这里,使用 BackgroundScheduler 启动 Apscheduler,并将默认的 jobstore 设置为 django,即使用 DjangoJobStore 存储定时任务信息。 通过以上步骤,就可以将 Apscheduler 的存储方式改为数据库存储,解决服务重启后定时任务失效问题