电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術(shù)文章
文章詳情頁

淺談springboot項目中定時任務(wù)如何優(yōu)雅退出

瀏覽:5日期:2023-04-19 15:38:39

在一個springboot項目中需要跑定時任務(wù)處理批數(shù)據(jù)時,突然有個Kill命令或者一個Ctrl+C的命令,此時我們需要當(dāng)批數(shù)據(jù)處理完畢后才允許定時任務(wù)關(guān)閉,也就是當(dāng)定時任務(wù)結(jié)束時才允許Kill命令生效。

啟動類

啟動類上我們獲取到相應(yīng)的上下文,捕捉相應(yīng)命令。在這里插入代碼片

@SpringBootApplication/**指定mapper對應(yīng)包的路徑*/@MapperScan('com.youlanw.kz.dao')/**開啟計劃任務(wù)*/@EnableScheduling/**開啟異常重試機制*/@EnableRetrypublic class YlkzTaskApplication { public static ConfigurableApplicationContext context; public static void main(String[] args) { context = SpringApplication.run(YlkzTaskApplication.class, args); /** * 捕捉命令實現(xiàn)優(yōu)雅退出 */ MySignalHandler.install('TERM'); //捕捉kill命令 MySignalHandler.install('INT'); //捕捉ctrl+c命令 }}

優(yōu)雅退出配置類

通過install方法捕捉到相應(yīng)的命令,

通過signalAction方法進行總開發(fā)的控制。

import org.slf4j.LoggerFactory;import sun.misc.Signal;import sun.misc.SignalHandler;/** * @description: 定時任務(wù)控制類(實現(xiàn)優(yōu)雅退出) * @method: * @author: mamengmeng * @date: 10:51 2018/8/13 */public class MySignalHandler implements SignalHandler { private final static org.slf4j.Logger logger = LoggerFactory.getLogger(MySignalHandler.class); private SignalHandler oldHandler; /** * 定時任務(wù)總開關(guān)-狀態(tài):true:打開 false:關(guān)閉 */ public static boolean base_flag = true; @Override public void handle(Signal signal) { signalAction(signal); } public static SignalHandler install(String signalName) { Signal diagSignal = new Signal(signalName); MySignalHandler instance = new MySignalHandler(); instance.oldHandler = Signal.handle(diagSignal, instance); return instance; } public void signalAction(Signal signal) { try { //關(guān)閉總開關(guān) this.base_flag = false; logger.info('n執(zhí)行優(yōu)雅退出操作n等待運行中任務(wù)執(zhí)行完畢…………'); Thread.sleep(3000); StringBuffer stringBuffer = new StringBuffer('a'); //此處為相關(guān)的業(yè)務(wù)代碼,只要還有一個定時任務(wù)在執(zhí)行,那么就等待線程任務(wù)執(zhí)行完畢。 while (BaseApplyTask.apply_flag || BaseResumeTask.resume_flag || CorpDemandTask.demand_flag || RecommendResumeTask.resume_flag || BaseCodeTask.code_flag || RecommendoneTask.resume_flag ||ResumeByZcbTask.zpbresume_flag) {//等待線程任務(wù)執(zhí)行完畢stringBuffer.append(''); } //獲取到的上下文對象關(guān)閉相應(yīng)的程序。 YlkzTaskApplication.context.close(); logger.info('n================n程序已安全退出!n================'); oldHandler.handle(signal); } catch (Exception e) { logger.error('handle|Signal handler' + 'failed, reason ' + e.getMessage()); e.printStackTrace(); } }}

舉例說明

我們在定時任務(wù)中添加一個總開關(guān),當(dāng)總開關(guān)是關(guān)著時是不允許定時任務(wù)執(zhí)行的,

@Componentpublic class BaseCodeTask { private final static Logger logger = LoggerFactory.getLogger(BaseCodeTask.class); @Autowired private ResumeService resumeService; public static boolean code_flag = true; //簡歷任務(wù)執(zhí)行狀態(tài) true:執(zhí)行中 false:執(zhí)行完畢 private static final Integer LIMIT = 500; private final static long time = 60 * 1000; //一分鐘 /** * @param * @description: 同步簡歷信息(定時任務(wù)) * 任務(wù)執(zhí)行間隔時間:6秒 * 待同步數(shù)據(jù)為空,則5分鐘后執(zhí)行下一次 * @method: sendResume * @author: zhengmingjie * @date: 16:17 2018/8/3 * @return: void */ @Scheduled(initialDelay = 1000, fixedDelay = time / 10) @Async public void sendResume() throws Exception { List<Resume> list = null; try { //總開關(guān)狀態(tài):true:打開 false:關(guān)閉 if (!MySignalHandler.base_flag)return; this.code_flag = true; logger.info('n======定時任務(wù):初始化基本數(shù)據(jù)======n開始執(zhí)行n'); //以下是業(yè)務(wù)代碼。相關(guān)的定時任務(wù)批處理 resumeService.initializationMap(); resumeService.setCodeDictionary(); resumeService.setCityInfo(); resumeService.setCodePostInfo(); logger.info('n======定時任務(wù):初始化基本數(shù)據(jù)======n結(jié)束n'); } catch (Exception e) { e.printStackTrace(); } finally { this.code_flag = false; } }}

定時任務(wù)優(yōu)雅退出的使用可以有效的防止批處理任務(wù)的中斷,小伙伴們可以嘗試添加哦。。。。

補充知識:springboot自帶定時器實現(xiàn)定時任務(wù)的開啟關(guān)閉以及動態(tài)修改定時規(guī)則

最近項目中遇到了需要自動定時導(dǎo)出的需求,用戶可以從頁面修改導(dǎo)出的時間規(guī)則,可以啟用和停用定時任務(wù)。

經(jīng)過了解,項目中目前實現(xiàn)定時任務(wù),一般有三種選擇,一是用Java自帶的timer類。稍微看了一下,可以實現(xiàn)大部分的指定頻率的任務(wù)的調(diào)度(timer.schedule()),也可以實現(xiàn)關(guān)閉和開啟(timer.cancle)。但是用其來實現(xiàn)某天的某個時間或者某月的某一天調(diào)度任務(wù)有點不方便。

二是采用Quartz 調(diào)度器實現(xiàn)。這是一個功能很強大的開源的專門用于定時任務(wù)調(diào)度的框架,也很好的和springboot整合,缺點:配置復(fù)雜,需要花費一定的時間去了解和研究。(本人懶,因此沒有選擇這個,但是這個功能地區(qū)強大,有時間研究)

三是spring3.0以后自帶的scheduletask任務(wù)調(diào)度,可以實現(xiàn)quartz的大部分功能,不需要額外引用jar,也不需要另外配置。而且支持注解和配置文件兩種。

因此最后選擇直接用spring自帶的task 實現(xiàn)。

基本用法很簡單,通過在方法上加注解@schedule(也可以通過xml文件配置的方式),注解里有 cron ,fixedDelay ,fixedRate ,initialDelay 等等參數(shù),可以完成指定時間,平率執(zhí)行此方法。這里不詳細介紹。

直接介紹,通過頁面動態(tài)修改cron參數(shù),修改定時規(guī)則的思路。

1 實現(xiàn)接口SchedulingConfigurer,這個接口只有一個方法,配置定時任務(wù)。重寫此方法,添加新的任務(wù)實現(xiàn)runable和新的觸發(fā) 實現(xiàn)trigger 。

2 在新的觸發(fā)里,把修改的cron寫入新的觸發(fā)

3 寫UI 方法,接收前端修改的定時參數(shù)。

代碼如下:

package com.fiberhome.ms.cus.cashform.ui;import java.util.Date;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.scheduling.Trigger;import org.springframework.scheduling.TriggerContext;import org.springframework.scheduling.annotation.SchedulingConfigurer;import org.springframework.scheduling.config.ScheduledTaskRegistrar;import org.springframework.scheduling.support.CronTrigger;import org.springframework.stereotype.Component;@Componentpublic class DynamicScheduledTask implements SchedulingConfigurer {@Autowiredprivate ScheduleExport scheduleExport;// private static String DEFAULT_CRON = '0/10 * * * * ?';private String cron = '';public String getCron() {return cron;}public void setCron(String cron) {this.cron = cron;}@Overridepublic void configureTasks(ScheduledTaskRegistrar taskRegistrar) {// TODO Auto-generated method stubtaskRegistrar.addTriggerTask(new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubtry {scheduleExport.scheduleTaskExport();//異步定時生成文件System.out.println('Msg:定時生成文件成功');} catch (Exception e) {// TODO: handle exceptione.printStackTrace();System.out.println('Error:定時生成文件錯誤');}}}, new Trigger() {@Overridepublic Date nextExecutionTime(TriggerContext triggerContext) {// TODO Auto-generated method stubif (''.equals(cron)|| cron == null)return null;CronTrigger trigger = new CronTrigger(cron);// 定時任務(wù)觸發(fā),可修改定時任務(wù)的執(zhí)行周期Date nextExecDate = trigger.nextExecutionTime(triggerContext);return nextExecDate;}});System.out.println('can?');}}

這個方法可以實現(xiàn) 根據(jù)頁面設(shè)置動態(tài)修改定時器的cron參數(shù),不用重啟服務(wù)。但是運行之后發(fā)現(xiàn)了一個缺陷,即必須在修改完之后,只有再一次到達定時任務(wù)的時間,才會調(diào)用新的觸發(fā)時間, 這就導(dǎo)致,頁面設(shè)置的時間并不能即時生效,這在項目中是不符合用戶的要求,于是為了解決這個bug,換了另外一種解決方法。

思路:(了解ThreadPoolTaskScheduler這個類,TaskScheduler接口的默認實現(xiàn)類,多線程定時任務(wù)執(zhí)行。可以設(shè)置執(zhí)行線程池數(shù)(默認一個線程))

1、ThreadPoolTaskScheduler 實現(xiàn)TaskScheduler,可以通過方法 schedule(java.lang.Runnable task, Trigger trigger),添加定時任務(wù)和觸發(fā)器。返回java.util.concurrent.ScheduledFuture<?>,future可以控制任務(wù)的開關(guān)等。

2、前端修改定時參數(shù),在set方法中修改ThreadPoolTaskScheduler 的觸發(fā)器。

代碼如下:

package com.fiberhome.ms.cus.cashform.ui.util;import java.util.Date;import java.util.concurrent.ScheduledFuture;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.scheduling.Trigger;import org.springframework.scheduling.TriggerContext;import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;import org.springframework.scheduling.support.CronTrigger;import org.springframework.stereotype.Component;import com.fiberhome.ms.cus.cashform.ui.ScheduleExport;@Componentpublic class DynamicScheduleTaskSecond {@Autowiredprivate ThreadPoolTaskScheduler threadPoolTaskScheduler;@Autowiredprivate ScheduleExport scheduleExport;private ScheduledFuture<?> future;private String cron = '';public String getCron() {return cron;}public void setCron(String cron) {this.cron = cron;stopCron();future = threadPoolTaskScheduler.schedule(new Runnable() {@Overridepublic void run() {// TODO Auto-generated method stubtry {scheduleExport.scheduleTaskExport();// 異步定時生成文件System.out.println('Msg:定時生成文件成功');} catch (Exception e) {// TODO: handle exceptione.printStackTrace();System.out.println('Error:定時生成文件錯誤');}}}, new Trigger() {@Overridepublic Date nextExecutionTime(TriggerContext triggerContext) {// TODO Auto-generated method stubif (''.equals(cron) || cron == null)return null;CronTrigger trigger = new CronTrigger(cron);// 定時任務(wù)觸發(fā),可修改定時任務(wù)的執(zhí)行周期Date nextExecDate = trigger.nextExecutionTime(triggerContext);return nextExecDate;}});}public void stopCron() {if (future != null) {future.cancel(true);//取消任務(wù)調(diào)度}}}

驗證可行,作個記錄,如果有認為可以調(diào)整的地方,歡迎討論!

以上這篇淺談springboot項目中定時任務(wù)如何優(yōu)雅退出就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持好吧啦網(wǎng)。

標簽: Spring
相關(guān)文章:
主站蜘蛛池模板: 金环宇|金环宇电线|金环宇电缆|金环宇电线电缆|深圳市金环宇电线电缆有限公司|金环宇电缆集团 | 煤棒机_增碳剂颗粒机_活性炭颗粒机_木炭粉成型机-巩义市老城振华机械厂 | 广东佛电电器有限公司|防雷开关|故障电弧断路器|智能量测断路器 广东西屋电气有限公司-广东西屋电气有限公司 | 发电机价格|发电机组价格|柴油发电机价格|柴油发电机组价格网 | 天坛家具官网 | 机床导轨_导轨板_滚轮导轨-上海旻佑精密机械有限公司 | 涡街流量计_LUGB智能管道式高温防爆蒸汽温压补偿计量表-江苏凯铭仪表有限公司 | 【连江县榕彩涂料有限公司】官方网站| 高考志愿规划师_高考规划师_高考培训师_高报师_升学规划师_高考志愿规划师培训认证机构「向阳生涯」 | 苏州西朗门业-欧盟CE|莱茵UL双认证的快速卷帘门品牌厂家 | DDoS安全防护官网-领先的DDoS安全防护服务商 | China plate rolling machine manufacturer,cone rolling machine-Saint Fighter | 铸铁平台,大理石平台专业生产厂家_河北-北重机械 | 【电子厂招聘_普工招工网_工厂招聘信息平台】-工立方打工网 | 深圳市宏康仪器科技有限公司-模拟高空低压试验箱-高温防爆试验箱-温控短路试验箱【官网】 | 意大利Frascold/富士豪压缩机_富士豪半封闭压缩机_富士豪活塞压缩机_富士豪螺杆压缩机 | 有机废气处理-rto焚烧炉-催化燃烧设备-VOC冷凝回收装置-三梯环境 | 浙江宝泉阀门有限公司| 切铝机-数控切割机-型材切割机-铝型材切割机-【昆山邓氏精密机械有限公司】 | 氟塑料磁力泵-不锈钢离心泵-耐腐蚀化工泵厂家「皖金泵阀」 | 高压互感器,电流互感器,电压互感器-上海鄂互电气科技有限公司 | YAGEO国巨电容|贴片电阻|电容价格|三星代理商-深圳市巨优电子有限公司 | 广东健伦体育发展有限公司-体育工程配套及销售运动器材的体育用品服务商 | 耐火浇注料价格-高强高铝-刚玉碳化硅耐磨浇注料厂家【直销】 | 派克防爆伺服电机品牌|国产防爆伺服电机|高低温伺服电机|杭州摩森机电科技有限公司 | 注塑机-压铸机-塑料注塑机-卧式注塑机-高速注塑机-单缸注塑机厂家-广东联升精密智能装备科技有限公司 | 艾默生变频器,艾默生ct,变频器,ct驱动器,广州艾默生变频器,供水专用变频器,风机变频器,电梯变频器,艾默生变频器代理-广州市盟雄贸易有限公司官方网站-艾默生变频器应用解决方案服务商 | 新车测评网_网罗汽车评测资讯_汽车评测门户报道 | 长沙中央空调维修,中央空调清洗维保,空气能热水工程,价格,公司就找维小保-湖南维小保环保科技有限公司 | 散热器-电子散热器-型材散热器-电源散热片-镇江新区宏图电子散热片厂家 | 南京试剂|化学试剂|分析试剂|实验试剂|cas号查询-专业60年试剂销售企业 | 百度关键词优化_网站优化_SEO价格 - 云无限好排名 | STRO|DTRO-STRO反渗透膜(科普)_碟滤 | 威实软件_软件定制开发_OA_OA办公系统_OA系统_办公自动化软件 | 众品地板网-地板品牌招商_地板装修设计_地板门户的首选网络媒体。 | PCB设计,PCB抄板,电路板打样,PCBA加工-深圳市宏力捷电子有限公司 | 5L旋转蒸发器-20L-50L旋转蒸发器-上海越众仪器设备有限公司 | 环球周刊网| 视频教程导航网_视频教程之家_视频教程大全_最新视频教程分享发布平台 | 搬运设备、起重设备、吊装设备—『龙海起重成套设备』 | 河北码上网络科技|邯郸小程序开发|邯郸微信开发|邯郸网站建设 |