Spring timed Task Job (quartz) visualization

Source: Internet
Author: User
Tags arrays manual int size min volatile xmlns

This article describes job visualizations (management, imperfect visual management of this article) when using the job framework of spring (spring inherited and simplified quartz)

The solution is to use listeners to implement job history, job statistics, exception logging, manual trigger Job

Let's take a look at the implementation process

Here you only need to implement several listeners and register to

-Statisticschedulerlistener listener trigger rule triggers, typically triggered when spring starts and refreshes

-Statisticjoblistener Job Listener (monitor job before and after execution)


The main use of statisticjoblistener here

public class Statisticjoblistener implements Joblistener {private static Logger log = Logger.getlogger (statisticjobli

    private static threadlocal<jobstatisticbean> ThreadLocal = new threadlocal<jobstatisticbean> ();

    private String name;
    public void SetName (String name) {this.name = name;
    } @Override Public String getName () {return this.name; }//beginging @Override public void jobtobeexecuted (Jobexecutioncontext context) {Log.info ("job will be executed. ..
        "+context.getjobdetail (). GetName ());
        Jobstatisticbean Jobstatisticbean = new Jobstatisticbean ();
        Jobstatisticbean.setjobname (Context.getjobdetail (). GetName ());
        Jobstatisticbean.setjobdetail (Context.getjobdetail ());
        Jobstatisticbean.settrigger (Context.gettrigger ());
        Jobstatisticbean.setstarttime (New Timestamp (System.currenttimemillis ()));
        Jobstatisticbean.setjobexecutioncontext (context); JobstatIsticbean.setjobintance (Context.getjobinstance ());
    Threadlocal.set (Jobstatisticbean); } @Override public void jobexecutionvetoed (Jobexecutioncontext context) {Log.info ("jobexecutionvetoed" +
    Context.getjobdetail (). GetName ());
        } @Override public void jobwasexecuted (Jobexecutioncontext context, jobexecutionexception jobexception) {
        Log.info ("Job Execution Complete" +context.getjobdetail (). GetName ());
        Jobstatisticbean Jobstatisticbean = Threadlocal.get ();
            if (jobstatisticbean!=null) {jobstatisticbean.setendtime (New Timestamp (System.currenttimemillis ())); Jobstatisticbean.settakestime (Jobstatisticbean.getendtime (). GetTime ()-jobstatisticbean.getstarttime (). GetTime (
        Statisticprocessor.add (Jobstatisticbean); }



specific cache can be extended by itself, which simply uses the current JVM cache and can expand Redis

public class Statisticprocessor extends Thread implements Applicationcontextaware, Initializingbean, Disposablebean {
    private static Logger Logjob = Logger.getlogger (loggercategory.job_statistic);
    private static Logger Logjobhistory = Logger.getlogger (loggercategory.job_statistic_history);

    private static Logger logjobexception = Logger.getlogger (loggercategory.job_statistic_exception);
    private static volatile queue<jobstatisticbean> Jobqueue = new concurrentlinkedqueue<jobstatisticbean> (); private static volatile queue<schedulerexceptionbean> Exceptionqueue = new concurrentlinkedqueue<
    Schedulerexceptionbean> (); private static volatile map<string, jobstatisticbean> jobmap = new concurrenthashmap<string, jobstatisticbean&

    gt; (); /** * Manual Trigger Job * @param Jobstatisticbean * @return * @throws Exception */public static Boolea N Runbyhand (Jobstatisticbean Jobstatisticbean) throws Exception{if (jobstatisticbean==null) return false;
        Jobexecutioncontext context = Jobstatisticbean.getjobexecutioncontext ();
        Job Job = Jobstatisticbean.getjobintance ();
        Job.execute (context);
    return true;  }/** * Add an instance of the job (use map to prevent duplication) and record the job execution record (Queue) * @param jobstatisticbean * @return */Public
            Static Boolean Add (Jobstatisticbean Jobstatisticbean) {if (!jobmap.containskey (Jobstatisticbean.getjobname ())) {
        Logjob.info ("Add Job" + jacksonutil.tojsonstring (Jobstatisticbean));
        } jobmap.put (Jobstatisticbean.getjobname (), Jobstatisticbean);
        Logjobhistory.info (jacksonutil.tojsonstring (Jobstatisticbean));
    Return Jobqueue.add (Jobstatisticbean); }/** * Add execution Exception Log * @param Schedulerexceptionbean * @return * */public static Boolean add (Sche Dulerexceptionbean Schedulerexceptionbean) {logjobexception.info (Jacksonutil.tojsonstring (SCHedulerexceptionbean));
    Return Exceptionqueue.add (Schedulerexceptionbean);
        } public static list<jobstatisticbean> getalljobs () {int size = Jobmap.size (); Size = size>100?
    Return Arrays.aslist (Jobmap.values (). ToArray (new jobstatisticbean[size]);
        } public static list<jobstatisticbean> getalljobhistory () {int size = Jobqueue.size (); Size = size>100?
    Return Arrays.aslist (Jobqueue.toarray (new jobstatisticbean[size]));
        } public static list<schedulerexceptionbean> getallexceptions () {int size = Exceptionqueue.size (); Size = size>100?
    Return Arrays.aslist (Exceptionqueue.toarray (new schedulerexceptionbean[size]));
    } private Volatile Boolean exit = FALSE;
    Private ApplicationContext applicationcontext = null;

    private static volatile statisticprocessor processorintance = null;
    Public synchronized void Init () {    if (processorintance==null) {logjob.info ("---------------------" +new Date (). toLocaleString () + "----------
            Logjobhistory.info ("---------------------" +new Date (). toLocaleString () + "--------------------------");
            Logjobexception.info ("---------------------" +new Date (). toLocaleString () + "--------------------------");
            Processorintance = new Statisticprocessor ();
            Processorintance.setname (Gconstants.threa_head + "jobstatisticprocessor");
            Processorintance.setdaemon (TRUE);
        Processorintance.start ();
                }} @Override public void Run () {do{try {thread.sleep (1000*30);  Synchronized (jobqueue) {if (!jobqueue.isempty ()) {Long outsize =
                        Jobqueue.size ()-100;
                        while (outsize--> 0) {jobqueue.poll (); }
                    }} synchronized (Exceptionqueue) {if (!exceptio
                        Nqueue.isempty ()) {Long outsize = exceptionqueue.size ()-100;
                        while (outsize--> 0) {exceptionqueue.poll ();
            }}}}catch (Exception e) {e.printstacktrace ();
    }}while (!this.exit);
        } @Override public void Setapplicationcontext (ApplicationContext applicationcontext) throws Beansexception {
    This.applicationcontext = ApplicationContext;
    } @Override public void Afterpropertiesset () throws Exception {This.init ();
    } @Override public void Destroy () {this.exit = true; }


public class Jobstatisticbean implements Serializable {
    private static long serialversionuid = -1l;

    Private String      jobName;
    Private String      className;
    Private Timestamp   startTime;
    Private Timestamp   endTime;
    Private Long        takestime;
    Private Jobdetail   Jobdetail;
    Private Trigger     Trigger;
    Private Jobexecutioncontext Jobexecutioncontext;
    Private Job     jobintance;
    //.. Getter & Setter 


<?xml version= "1.0" encoding= "UTF-8"?> <beans xmlns= "Http://www.springframework.org/schema/beans" Xmlns:xs I= "Http://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation= "Http://www.springframework.org/schema/beans Http://www.springframework.org/schema/beans/spring-beans-2.0.xsd "> <bean id=" Schedulerfactorybean "class=" Org.springframework.scheduling.quartz.SchedulerFactoryBean "lazy-init=" false "> <property name=" Schedulernam E "value=" Ezhe-taks "/> <property name=" triggers "> <list> <ref bean= "Task1"/> <ref bean= "Task2"/> </list> </property> <p Roperty name= "Globaljoblisteners" > <list> <bean class= "Com.gozap.ezhe.task.listen Er.
            Statisticjoblistener "> <property name=" name "value=" Job statistics "/> </bean>
   </list>     </property> <property name= "Schedulerlisteners" > <list> <bea n class= "Com.gozap.ezhe.task.listener.StatisticSchedulerListener" > </bean> </list&
        Gt </property> <property name= "Autostartup" value= "true"/> <property name= "Configlocation" Val Ue= "Classpath:quartz.properties"/> </bean> <!--automatically update the exchange rate task--<bean id= "Task1" class= "Org.spr Ingframework.scheduling.quartz.CronTriggerBean "> <property name=" jobdetail "> <bean id=" Jo Bupdatecurrencytask "class=" Org.springframework.scheduling.quartz.JobDetailBean "> <property name=" NA Me "value=" Automatically update the exchange rate task "/> <property name=" Jobclass "value=" Com.gozap.ezhe.task.CurrencyUpdateTask ">  </property> </bean> </property> <property name= "cronexpression" value= "0 0/30 * * *?" /> </bean> <!--auto XX task--<bean id= "Task2" class= "Org.springframework.scheduling.quartz.Cro Ntriggerbean "> <property name=" jobdetail "> <bean id=" logisticsscheduletask "class=" org.sp
                Ringframework.scheduling.quartz.JobDetailBean "> <property name=" name "value=" Auto xx task "/> <property name= "Jobclass" value= "Com.gozap.ezhe.task.LogisticsScheduleTask" ></property> &L t;/bean> </property> <property name= "cronexpression" value= "0 0 0/2 * *?" /> </bean> </beans>


public class Jobstatisticaction extends Baseaction {

    private list<jobstatisticbean> joblist;
    Private list<jobstatisticbean> jobhistorylist;
    Private list<schedulerexceptionbean> jobexceptionlist;

    Public String jobstatistic () throws Exception {
        joblist = Statisticprocessor.getalljobs ();
        Jobhistorylist = Statisticprocessor.getalljobhistory ();
        Collections.reverse (jobhistorylist);
        Jobexceptionlist = Statisticprocessor.getallexceptions ();
        return action.success;

   ============================ public

    list<jobstatisticbean> getjoblist () {
        return joblist;

    Public list<jobstatisticbean> getjobhistorylist () {
        return jobhistorylist;

    Public list<schedulerexceptionbean> getjobexceptionlist () {
        return jobexceptionlist;


<%@ page contenttype= "Text/html;charset=utf-8" language= "java"%> <%@ taglib uri= "/struts-tags" prefix= "s"% > <%@ page import= "java.text.SimpleDateFormat"%> <%@ page import= "java.util.Date"%> <% Simpledatef Ormat SDF = new SimpleDateFormat ("Yyyy-mm-dd HH:mm:ss.
    SSS ");
String nowtime = Sdf.format (New Date ()); %>  

This article describes just a simple implementation, recommend the use of design patterns in some way to refactor, if there is time later I will also refactor

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.