当前位置: 首页 > news >正文

上海网上做鸭子的网站简述网络营销的含义

上海网上做鸭子的网站,简述网络营销的含义,建设银行网上银行登录,网站开发感想定时任务是互联网行业里最常用的服务之一,本文给大家介绍定时任务在我司的发展历程。 linux系统中一般使用crontab命令来实现,在Java世界里,使用最广泛的就是quartz了。我司使用quartz就已经升级了三代,每一代在上一代系统之上有所…

定时任务是互联网行业里最常用的服务之一,本文给大家介绍定时任务在我司的发展历程。

linux系统中一般使用crontab命令来实现,在Java世界里,使用最广泛的就是quartz了。我司使用quartz就已经升级了三代,每一代在上一代系统之上有所优化,写这篇文章一方面介绍一下quartz的使用,另一方面可以根据此项目的变迁反应出我司平台架构升级的一个缩影。

定时任务的使用场景很多,以我们平台来讲:计息,派息、对账等等。

quartz 介绍

Quartz是个开源的作业调度框架,为在Java应用程序中进行作业调度提供了简单却强大的机制。Quartz允许开发人员根据时间间隔(或天)来调度作业。它实现了作业和触发器的多对多关系,还能把多个作业与不同的触发器关联。Quartz可以集成几乎任何的java应用程序—从小的单片机系统到大型的电子商务系统。Quartz可以执行上千上万的任务调度。

Quartz核心的概念:scheduler任务调度、Job任务、JobDetail任务细节、Trigger触发器

  • Scheduler:调度器,调度器接受一组JobDetail+Trigger即可安排一个任务,其中一个JobDetail可以关联多个Trigger
  • Job:Job是任务执行的流程,是一个类
  • JobDetail:JobDetail是Job是实例,是一个对象,包含了该实例的执行计划和所需要的数据
  • Trigger:Trigger是定时器,决定任务何时执行

使用Quartz调度系统的思路就是,首先写一个具体的任务(job),配置任务的触发时间(Trigger),Scheduler很根据JobDetail+Trigger安排去执行此任务。

Quartz 定时器的时间设置

时间的配置如下:0 30 16 * * ?

时间大小由小到大排列,从秒开始,顺序为 秒,分,时,天,月,年 *为任意 ?为无限制。由此上面所配置的内容就是,在每天的16点30分启动buildSendHtml() 方法

具体时间设定可参考 :

"0/10 * * * * ?" 每10秒触发
"0 0 12 * * ?" 每天中午12点触发
"0 * 14 * * ?" 在每天下午2点到下午2:59期间的每1分钟触发
"0 10,44 14 ? 3 WED" 每年三月的星期三的下午2:10和2:44触发
"0 15 10 ? * MON-FRI" 周一至周五的上午10:15触发
"0 0 06,18 * * ?" 在每天上午6点和下午6点触发

第一代定时任务系统

第一代定时任务系统使用的很简单,全部按照当时spring推荐的配置方式来进行,开发于2014年初。

首先在配置线程池

<bean id="executor" class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor"><property name="corePoolSize" value="50" /><property name="maxPoolSize" value="100" /><property name="queueCapacity" value="500" />
</bean>

配置定时任务工厂和任务基类

<bean id="timerFactory" class="com.zx.timer.TimerFactory" /><bean id="baseTask" class="com.zx.timer.core.BaseTask"><property name="machineId" value="${machine.id}"/><property name="recordErrorDetail" value="${is.record.errordetail}"/>
</bean>
  • machineId:机器编码
  • recordErrorDetail:是否记录详细日志

通过timerFactory 来获取具体的任务和触发器

public class TimerFactory implements BeanFactoryAware {private BeanFactory beanFactory;public Object getTask(String taskCode) {return beanFactory.getBean(taskCode+"Task");}public Object getTrigger(String taskCode) {return beanFactory.getBean(taskCode+"Trigger");}public void setBeanFactory(BeanFactory beanFactory) {this.beanFactory = beanFactory;}public BeanFactory getBeanFactory() {return beanFactory;}
}

baseTask集成了task,在里面做了一些基础的业务,比如定时任务开始执行的时候记录定时任务的开始执行时间,定时任务结束的时候记录执行的结果等。

public interface Task {public void executeTask();
}

配置具体的定时任务。以重发短信邮件的定时任务为例

<bean id="resendSmsAndEmailTask" class="com.zx.timer.core.tasks.ResendSmsAndEmailTask"parent="baseTask">
</bean><bean id="resendSmsAndEmailJob" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"><property name="targetObject" ref="resendSmsAndEmailTask" /><property name="targetMethod" value="executeTask" /><property name="concurrent" value="false" />
</bean><bean id="resendSmsAndEmailTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"><property name="jobDetail" ref="resendSmsAndEmailJob" /><property name="cronExpression"><value>0 0 0 * * ?</value></property>
</bean>
  • resendSmsAndEmailTask:具体的定时任务类
  • resendSmsAndEmailJob:包装成具体的Job
  • resendSmsAndEmailTrigger:设置具体执行的时间,包装成Trigger

具体的task类,删掉了部分业务代码:

public class ResendSmsAndEmailTask extends BaseTask{private static final String TASK_CODE = "resendSmsAndEmail";AtomicInteger ai = new AtomicInteger(0);public void execute(){try {ai = new AtomicInteger(0);// todo}catch (Exception e) {String exception = ExceptionUtils.getStackTrace(e);logger.error("stat error with exception[{}].", exception);this.recordTaskErrorDetail(this.taskRecordId, "ResendSmsAndEmailTask-" + e.getMessage(), exception);}finally{this.modifyTaskRecord(ai.get(), taskRecordId);}}public String getTaskNo() {return TASK_CODE;}
}

最后配置scheduler任务调度

<bean id="scheduler" class="org.springframework.scheduling.quartz.SchedulerFactoryBean"><property name="triggers"><list><ref bean="resendSmsAndEmailTrigger" /></list></property><property name="taskExecutor" ref="executor" />
</bean>
<bean class="com.zx.timer.core.scheduler.DynamicJobAssembler" init-method="init" scope="singleton"/>

DynamicJobAssembler类代码:

public class DynamicJobAssembler {private static Logger logger = LoggerFactory.getLogger(DynamicJobAssembler.class);@ResourceScheduler scheduler;@ResourceTimerFactory timerFactory;@ResourceTaskDao taskDao;public void init() {logger.info("start to assemble task from db.");List<TaskEntity> tasks = this.taskDao.getAllTask();if (tasks == null || tasks.size() <= 0) {return;}Map<String, String> jobNameMap = this.getAllJobNames();for (TaskEntity task : tasks) {logger.debug(task.toString());CronTriggerBean taskTrigger = (CronTriggerBean) timerFactory.getTrigger(task.getTaskNo());if (taskTrigger != null) {if (!task.getSchedulerRule().equals(taskTrigger.getCronExpression())) {try {taskTrigger.setCronExpression(task.getSchedulerRule());} catch (ParseException e) {logger.error("db task's cronExpression parse error:{}", e.getMessage());}try {logger.info("rescheduleJob jobName:{}",task.getTaskNo());scheduler.rescheduleJob(task.getTaskNo() + "Trigger", Scheduler.DEFAULT_GROUP, taskTrigger);} catch (SchedulerException e) {logger.error("revieved task[{},{}] reschedule error:{}", task.getTaskNo(), task.getSchedulerRule(), e.getMessage());}}jobNameMap.remove(task.getTaskNo() + "Job");}}if (jobNameMap != null) {logger.info("=====================================");logger.info("Jobs need to be removed:" + Arrays.toString(jobNameMap.keySet().toArray()));logger.info("=====================================");for (String jobName : jobNameMap.keySet()) {try {scheduler.deleteJob(jobName, jobNameMap.get(jobName));} catch (SchedulerException e) {logger.error("Error occured when deleting Job[{}] with Exception:{}", jobName, e.getMessage());}}}logger.info("end to assemble task from db.");}private Map<String, String> getAllJobNames() {Map<String, String> jobNameMap = new HashMap<String, String>();try {String[] groups = scheduler.getJobGroupNames();for (String group : groups) {String[] jobs = scheduler.getJobNames(group);if (jobs != null) {for (String job : jobs) {jobNameMap.put(job, group);}}}} catch (SchedulerException e1) {logger.error("Failed in geting all job names with exception:{}", e1.getMessage());}return jobNameMap;}}

定时任务表,执行的时候以表里面的数据为准,方便编辑。

SET FOREIGN_KEY_CHECKS=0;-- ----------------------------
-- Table structure for `zx_task_informations`
-- ----------------------------
DROP TABLE IF EXISTS `zx_task_informations`;
CREATE TABLE `zx_task_informations` (`id` bigint(20) NOT NULL AUTO_INCREMENT,`version` int(11) NOT NULL COMMENT '版本号:需要乐观锁控制',`taskNo` varchar(64) NOT NULL COMMENT '任务编号',`taskName` varchar(64) NOT NULL COMMENT '任务名称',`schedulerRule` varchar(64) NOT NULL COMMENT '定时规则表达式',`frozenStatus` varchar(16) NOT NULL COMMENT '冻结状态',`executorNo` varchar(128) NOT NULL COMMENT '执行方',`timeKey` varchar(32) NOT NULL COMMENT '执行时间格式',`frozenTime` bigint(13) DEFAULT NULL COMMENT '冻结时间',`unfrozenTime` bigint(13) DEFAULT NULL COMMENT '解冻时间',`createTime` bigint(13) NOT NULL COMMENT '创建时间',`lastModifyTime` bigint(13) DEFAULT NULL COMMENT '最近修改时间',PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=utf8 COMMENT='定时任务信息表';-- ----------------------------
-- Records of zx_task_informations
-- ----------------------------
INSERT INTO `zx_task_informations` VALUES ('1', '0', 'resendSmsAndEmail', '重发短信和邮件', '10 */10 * * * ?', 'FROZEN', '0', 'yyyy-MM-dd HH:mm', '0', '0', '0', '1486807296009');

这就是我们第一代定时任务系统,达到了定期执行定时任务的效果,但是同样有两个缺点:

  • 1、定时调度和业务代码耦合在一起
  • 2、每次调整定时任务的时间需要重启服务

转载于:https://www.cnblogs.com/ityouknow/p/7119552.html

http://www.lbrq.cn/news/2474191.html

相关文章:

  • javaee做网站建设seo中介平台
  • 网站建设需要会百度指数关键词工具
  • 地图设计网站seo职位要求
  • 汕头模版网站建设正规手游代理平台有哪些
  • 哪个网站做批韩国护肤品批发seo专业培训费用
  • 淮安网站建设自助快速建站
  • 品牌英语扬州网站seo
  • 外贸网站模板大全网页制作代码大全
  • 作业不会做网站上找人做靠谱吗朋友圈广告推广
  • 云南建设网站首页青岛百度竞价
  • 商洛免费做网站公司最新推广方法
  • 网站建设 技术支持 阿里太原百度seo排名
  • 网站开发 发票哈尔滨推广优化公司
  • 个人网站设计规划书个人主页网页设计模板
  • 电商网站建站怎样做自己的网站
  • 产品网站别人是如何做优化的百度推广营销中心
  • 博物馆网站做的最好的谷歌seo详细教学
  • 网站建设 百度推广网站推广策划方案
  • 做网站推广需要花多少钱网奇seo培训官网
  • 全是图片的网站怎么做seo网络营销推广方式包括
  • 网站建设海南手机端seo
  • 最好的外贸网站建设引擎搜索技巧
  • 全国开发一个网站需要多少钱全国疫情的最新数据
  • 网站建设网站管理如何推广网站运营
  • 做pc端的网站首页尺寸是多少百度人工投诉电话是多少
  • 信息网查询关于进一步优化当前疫情防控措施
  • 网站建设论坛报告今日刚刚发生的新闻
  • 常州建设局官方网站友情链接什么意思
  • 山东省住房和城乡城乡建设厅网站微信群发软件
  • p2p网站建设方案网站建设方案优化
  • Effective C++ 条款4:确定对象被使用前已先被初始化
  • OneCode3.0 Gallery 组件前后端映射机制:从注解配置到前端渲染的完整链路
  • 图书推荐-由浅入深的大模型构建《从零构建大模型》
  • day33:零基础学嵌入式之网络——HTTP服务端
  • 用 Function Call 让 AI 主动调用函数(超入门级示例)|保姆级大模型应用开发实战
  • Python 使用环境下编译 FFmpeg 及 PyAV 源码(英特尔篇)