http://blog.itpub.NET/11627468/viewspace-1766967/

quartz启动后有多个线程同时在跑。启动时会启动主线程、集群线程、检漏线程、工作线程。主线程负责查询到需要触发的线程,并放入到线程队列。
集群线程负责集群、检漏线程负责对未成功执行的任务进行检漏。工作线程默认是20,一般PC服务器可以调到200。

一、主线程QuartzScheduleThread
关于QuartzScheduleThread是quartz启动时开始启动,用于trigger的获取、触发,并放入到线程池中执行。
详细可以看quartz详解2:quartz由浅入深第4章

详细流程如下:

关于quartz2.0版本之后可以批量执行trigger的功能。要测试是否影响定时的准确度。

二、线程池SimpleThreadPool
线程池的初使化:new 线程并放入线程池的链表中。
执行线程:把任务放到一个线程中执行。
线程结束:修改线程状态。
线程池关闭:每个线程关闭,正在执行的线程等线程执行完了再关闭。

三、工作线程WorkThread
线程池中执行的工作线程,可以通过配置文件quartz.properties来配置大小:

JobRunShell实现runnable接口,放入到workThread下执行:

四、集群线程ClusterManager和检漏线程MisfireHandler
可以看到quartz启动时,这两个线程也启动了。

那么,它是在什么时候启动的呢?是在执行QuartzScheduler的start()方法时在JobStore类上加载的。

再来分析下,这两个线程的作用。

这两个线程都有initialize,manage,run,shutdown方法。
--1、先看ClusterManager,在new ClusterManger后,就会触发initialize方法,initialize方法再调用manager方法。
run方法的代码:

点击(此处)折叠或打开

  1. public void run() {
  2. while (!shutdown) {
  3. if (!shutdown) {
  4. long timeToSleep = getClusterCheckinInterval();
  5. long transpiredTime = (System.currentTimeMillis() - lastCheckin);
  6. timeToSleep = timeToSleep - transpiredTime;
  7. if (timeToSleep <= 0) {
  8. timeToSleep = 100L;
  9. }
  10. if(numFails > 0) {
  11. timeToSleep = Math.max(getDbRetryInterval(), timeToSleep);
  12. }
  13. try {
  14. Thread.sleep(timeToSleep);
  15. } catch (Exception ignore) {
  16. }
  17. }
  18. if (!shutdown && this.manage()) {
  19. signalSchedulingChangeImmediately(0L);
  20. }
  21. }//while !shutdown
  22. }

private long clusterCheckinInterval = 7500L;   //默认7.5秒执行一次集群的manage。
而集群的manager做的事情是判断是否有节点down掉,同时每7.5秒发送同步心跳修改数据库信息。

LAST_CHECKIN_TIME每7.5秒会更新一次。

--2、再看MisfireHandler的作用:
run方法默认每15秒执行一次。如果没有misfire的话,则每60秒执行一次。
manager逻辑如下:
 private long misfireThreshold = 60000L;   //默认时间超过了1分钟。
就是把超过1分钟还没执行的任务,认为是misfire,然后保存到trigger表,等待重新再执行。

有状态的job如果第一次没有执行完,第二次执行的时间错过了,就会被认为是misfire
doUpdateOfMisfiredTrigger调用CronTriggerImpl的updateAfterMisfire方法。
如果misfire设置为MISFIRE_INSTRUCTION_SMART_POLICY或MISFIRE_INSTRUCTION_FIRE_ONCE_NOW就是马上执行。
如果misfire设置为MISFIRE_INSTRUCTION_DO_NOTHING则在下一个周期再执行。
默认是:MISFIRE_INSTRUCTION_SMART_POLICY
可以通过trigger的build方法增加参数实现:
withMisfireHandlingInstructionFireAndProceed().build()
withMisfireHandlingInstructionDoNothing().build()

五、总结:
从线程角度来分析集群的性能的话,主要是:
1、主线程QuartzScheduleThread的瓶颈很可能出现在数据库行锁。
--可以考虑定时任务数据保存在分布式缓存。减少对数据库的过分依赖。
2、工作线程WorkThread的瓶颈很可能出现在任务的阻塞。
--可以通过用异步任务来解析,异步任务如何放在数据库有性能问题可以再考虑分布式缓存。

quartz详解4:quartz线程管理的更多相关文章

  1. 转载:quartz详解:quartz由浅入深

    转载网址:http://blog.itpub.net/11627468/viewspace-1763498/ 一.quartz核心概念 先来看一张图:         scheduler 任务调度器 ...

  2. quartz详解3:quartz数据库集群-锁机制

    http://blog.itpub.NET/11627468/viewspace-1764753/ 一.quartz数据库锁 其中,QRTZ_LOCKS就是Quartz集群实现同步机制的行锁表,其表结 ...

  3. iOS 2D绘图详解(Quartz 2D)之路径(点,直线,虚线,曲线,圆弧,椭圆,矩形)

    前言:一个路径可以包含由一个或者多个shape以及子路径subpath,quartz提供了很多方便的shape可以直接调用.例如:point,line,Arc(圆弧),Curves(曲线),Ellip ...

  4. Linux进程上下文切换过程context_switch详解--Linux进程的管理与调度(二十一)

    1 前景回顾 1.1 Linux的调度器组成 2个调度器 可以用两种方法来激活调度 一种是直接的, 比如进程打算睡眠或出于其他原因放弃CPU 另一种是通过周期性的机制, 以固定的频率运行, 不时的检测 ...

  5. quartz详解2:quartz由浅入深

    http://blog.itpub.net/11627468/viewspace-1763498/ 一.quartz核心概念 先来看一张图:     scheduler 任务调度器 trigger 触 ...

  6. 【配置详解】Quartz配置文件详解

    我们通常是通过quartz.properties属性配置文件(默认情况下均使用该文件)结合StdSchedulerFactory 来使用Quartz的.StdSchedulerFactory 会加载属 ...

  7. quartz详解1:初步了解quartz

    http://blog.itpub.NET/11627468/viewspace-1763389/ 一.引入 你曾经需要应用执行一个任务吗?这个任务每天或每周星期二晚上11:30,或许仅仅每个月的最后 ...

  8. Linux fdisk命令参数及用法详解---Linux磁盘分区管理命令fdisk

    fdisk 命令 linux磁盘分区管理 用途:观察硬盘之实体使用情形与分割硬盘用. 使用方法: 一.在 console 上输入 fdisk -l /dev/sda ,观察硬盘之实体使用情形. 二.在 ...

  9. 零基础学习java------39---------json格式交互,Restful(不懂),静态资源映射,SSM整合(ssm整合思想,application.xml文件详解(声明式事务管理),)

    一. json格式交互(知道) 1 . 回顾ajax基本语法 $.ajax({ url:"", // 请求的后台路径 data:{"":"" ...

随机推荐

  1. LR_问题_平均响应时间解释,summary与analysis不一致----Summary Report中的时间说明

    Summary是按整个场景的时间来做平均的,最大最小值,也是从整个场景中取出来的. (1)       平均响应时间:事物全部响应时间做平均计算 (2)       90%响应时间:将事物全部响应时间 ...

  2. spring事物(一),@EnableTransactionManagement @Transactional 启动解析

    1.事物的声明阶段 @EnableTransactionManagement,是我们开启注解事物的第一步,我们来看下这个类为我们干了什么 @Target(ElementType.TYPE) @Rete ...

  3. Android之Handler消息处理机制

    Handler的作用 Handler消息机制在Android中的应用非常广泛,很多组件的底层实现都是靠Handler来完成的,所以掌握Handler消息机制的原理还是非常重要的.Handler的主要功 ...

  4. Python测试进阶——(7)动手编写Bash脚本启动Python监控程序并传递PID

    如下: #./cf_workload_functions.sh function timestamp(){ # get current timestamp sec=`date +%s` nanosec ...

  5. 我的第一个爬虫【python selenium】

    去年写的一个小功能,一年过得好快,好快! 目的:爬取京东商品详情页面的内容(商品名称.价格.评价数量)后存储到xls文档中,方便商家分析自己商品的动态. 软件:chrome(windows).chro ...

  6. 机器学习-liuyubobobo(慕课网)

    第一章 python3玩转机器学习 第二章 机器学习基础 安装:1.anaconda   2.pycharm 第三章 Jupyter Notebook,numpy,Matplotlib 1.jupyt ...

  7. ActiveMQ的安装与配置详情

    (1)ActiveMQ的简介 MQ: (message queue) ,消息队列,也就是用来处理消息的,(处理JMS的).主要用于大型企业内部或与企业之间的传递数据信息. ActiveMQ 是Apac ...

  8. 如何将dmp文件导入到Oracle

    一.概述 在将dmp文件导入到Oracle中之前,需要先创建一个orcale用户.然后使用该用户名和密码,以imp的方式将数据导入到oracle中. 二.执行步骤 1.登陆oracle数据库 a.sq ...

  9. C++面试常见问题——03String类的实现

    String类的具体实现 string的内容其实就是C中的字符串,在C中是char*型,在C++中是string类型. //C char *str = "mengziyue"; / ...

  10. maven的概念模型及maven坐标

     1.概念模型 项目对象模型:一个maven工程有一个pom.xml文件,通过pom.xml文件定义项目的坐标.项目依赖.项目信息.插件目标等. 依赖管理系统:通过maven的依赖管理对项目所依赖的j ...