Работа кварца срабатывает в неподходящее время

Описание проблемы. У нас есть кварцевое задание, которое планируется запускать в разное время в течение дня, например, с 13 до 16 и 19 часов. Проблема в том, что задание запускается и выполняется в другое время, кроме запланированного.

Что мы сделали: мы уже пытались полностью выключить наши серверы (JBoss) и очистить кварцевые таблицы, но это вообще не сработало.

Мы используем кварц 1.6, и я хочу знать, есть ли какая-либо ошибка в версии и может ли обновление кварца решить проблему ИЛИ есть ли какие-либо проблемы с настройкой свойств кварца и можно ли изменить свойства для решения этой проблемы.

Изменить - подробнее см. ниже:

Я скорректировал время работы. Кроме того, задание запускается в любое случайное время, кроме тех, которые мы упомянули в его расписании. Нет никакой закономерности, когда он срабатывает, кроме запланированного времени.

Ниже приведены сведения о задании и триггере в файле свойств БД. На основе этих деталей задания и деталей триггера будут настроены в БД в таблицах Quartz_Triggers и Quartz_CronTrigger:

<job>
        <job-detail>
            <name>Match Job</name>
            <group>JB_QUARTZ</group>
            <job-class>com.qd.qehadmin.common.scheduler.MatchJob</job-class>
            <volatility>false</volatility>
            <durability>true</durability>
            <recover>true</recover>
        </job-detail>
        <trigger>
            <cron>
                <name>Match Job Trigger</name>
                <group>JB_QUARTZ</group>
                <job-name>match Job</job-name>
                <job-group>JB_QUARTZ</job-group>
                <cron-expression>0 0 13,16,19 * * ?</cron-expression>
            </cron>
        </trigger>
    </job>

Ниже приведены подробные сведения о свойствах кварца в БД:

# Configure Main Scheduler Properties  
#============================================================================
org.quartz.scheduler.instanceName = JB_QUARTZ
org.quartz.scheduler.instanceId = AUTO
#============================================================================
# Configure ThreadPool  
#============================================================================
org.quartz.threadPool.class = org.quartz.simpl.SimpleThreadPool
org.quartz.threadPool.threadCount = 10
org.quartz.threadPool.threadPriority = 5
#============================================================================
# Configure JobStore  
#============================================================================
org.quartz.jobStore.misfireThreshold = 60000
org.quartz.jobStore.class = org.quartz.impl.jdbcjobstore.JobStoreTX
org.quartz.jobStore.driverDelegateClass=org.quartz.impl.jdbcjobstore.StdJDBCDelegate
org.quartz.jobStore.useProperties = true
org.quartz.jobStore.dataSource = jobSchedulerDS
org.quartz.jobStore.tablePrefix = JB_QRTZ_
org.quartz.jobStore.isClustered = true
org.quartz.jobStore.clusterCheckinInterval = 10000
#============================================================================
# Configure Datasources
#============================================================================
org.quartz.dataSource.jobSchedulerDS.jndiURL=java:JBAPI
org.quartz.dataSource.jobSchedulerDS.java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
#java.naming.provider.url=jnp://localhost:3099
java.naming.provider.url=jnp://166.20.337.12:8441,166.20.337.14:8441,166.20.337.16:8441,166.20.337.19:8441
#============================================================================

Ниже приведен Java-код для работы:

public void execute(JobExecutionContext ctx) throws JobExecutionException
    {

        try{        
            //Scheduler scheduler = new StdSchedulerFactory().getScheduler();           
            SendEmail sm = new SendEmail();     
            boolean running = false;            

                if (ctx.getJobDetail().getKey().getName().equalsIgnoreCase("match Job") ) { 
                    LogFile.MATCH_JOB.logInfo("Match jobs size  : "+ctx.getScheduler().getCurrentlyExecutingJobs().size(), this.getClass().getName());  
                    if(ctx.getScheduler().getCurrentlyExecutingJobs().size()==1)
                    {
                    initClient(); //This method will read properties from DB                    
                    startTime=System.currentTimeMillis();                   
                    Match(); //This method will execute job level code  
                    endTime=System.currentTimeMillis();

                    LogFile.MATCH_JOB.logInfo("***Match job ends*** Loadtest: "+Constants.loadTest+" in time: "+(endTime-startTime)/1000 + "secs", this.getClass().getName());
                }
                    else
                    {
                        running=true;  
                    } 
                }


            if(running)  
            { 
                LogFile.MATCH_JOB.logInfo("The Match job is already running – sending email",this.getClass().getName());
                sm.sendEmail();
            }       

        }catch(Exception e){
            e.printStackTrace();
            LogFile.MATCH_JOB.logError("***Match Job Error*** " +e.getStackTrace(), this.getClass().getName());
        }
    }

person FindYourself    schedule 05.09.2017    source источник
comment
Это не ошибка Quartz. Скорее всего, вы что-то делаете не так. Более того, очень сложно сказать, поскольку вы не предоставили никакого соответствующего кода и / или своих конфигураций.   -  person yishaiz    schedule 14.09.2017
comment
Привет, Ишаиз, Спасибо за ответ. Пожалуйста, дайте мне знать, какие подробности вам требуются по этому поводу. Эта проблема сбивает нас с толку уже пару месяцев, и мы вообще не можем ее решить. Спасибо!   -  person FindYourself    schedule 15.09.2017
comment
Ваш файл свойств Quartz и код, который отвечает за планирование вашей работы. Также вы можете добавить тег [quartz-scheduler], который намного более популярен.   -  person yishaiz    schedule 16.09.2017
comment
Кроме того, вы говорите, что задание выполняется не в запланированное время - это обычное время? кто они такие?   -  person yishaiz    schedule 16.09.2017
comment
Вы можете добавить всю эту информацию в сам вопрос, так будет легче читать   -  person yishaiz    schedule 18.09.2017
comment
Кроме того, добавьте тег [quartz-scheduler] и ответьте на мой вопрос о том, когда запускается ваша работа.   -  person yishaiz    schedule 18.09.2017
comment
Кроме того, если я проверю вашу cron 0 0 7,13,19 * * ?, например на cronmaker.com, время: 13:00, 19:00 и 7:00. , а это не то, что вы хотите, согласно тому, что вы написали в своем вопросе.   -  person yishaiz    schedule 18.09.2017
comment
Привет, Ишаиз, детали были обновлены в вопросе. Пожалуйста, проверьте и дайте мне знать, если возникнут дополнительные вопросы. Спасибо много!   -  person FindYourself    schedule 21.09.2017
comment
У кого-нибудь есть указатели? Помощь будет принята с благодарностью. Спасибо!   -  person FindYourself    schedule 27.09.2017
comment
Чтобы быть уверенным, что я правильно понимаю, задание запускается в любое требуемое время, но кроме того оно также запускается в другое время? Можете ли вы написать пример того, когда задание запускалось в какой-то конкретный день? Кроме того, как определить, в какое время запускалось задание? ведение журнала по java / просмотр таблиц кварца / что-то еще?   -  person yishaiz    schedule 27.09.2017
comment
Кроме того, я вижу, что вы используете getCurrentlyExecutingJobs(). См. Этот ответ stackoverflow.com/a/27395623/3883957 и в нем говорится Также обратите внимание, что этот метод не с учетом кластера, а также не забудьте не использовать его в классе Job, так что, возможно, это вызывает проблемы.   -  person yishaiz    schedule 27.09.2017
comment
Кроме того, попробуйте взглянуть на кварцевые таблицы после 13:00 / 16:00 / 19:00 и посмотреть, что должно быть в следующий раз, когда задание будет запущено, независимо от того, правильное это значение или нет.   -  person yishaiz    schedule 27.09.2017
comment
Привет, Ишаиз, извини, что вернулся так поздно, так как я был в отпуске в этот период. Я просмотрел ваши предложения и нашел их полезными, но я не могу понять решение в упомянутой вами ссылке из-за того, что не использовал метод getCurrentlyExecutingJobs (), особенно приведенную ниже часть &&! JobCtx.getFireTime (). Equals (ctx.getFireTime () Объекты jobCtx и ctx мне кажутся одинаковыми, и как это влияет на получение времени запуска. Не могли бы вы объяснить. Заранее большое спасибо!   -  person FindYourself    schedule 09.10.2017
comment
Кажется, что ctx - это текущее задание, а jobCtx находится в цикле всех CurrentExecutingJobs, каждый раз, когда он сравнивает другое задание с текущим заданием. Но это не так важно, важно то, что я процитировал: использование getCurrentlyExecutingJobs не зависит от кластера и не забывайте не использовать его в классе Job. Вы можете попробовать, например, отказаться от использования этого и просто посмотреть, исправляет ли это время срабатывания триггера. Кроме того, Вы не ответили на мои предыдущие вопросы, поэтому для меня будет сложно помочь больше.   -  person yishaiz    schedule 09.10.2017
comment
Привет, Ишаиз, время работы 0 0 13,16,19 * *? т.е. только 13:00, 16:00 и 19:00 (см. сведения о файле свойств базы данных выше). Да, в дополнение к этим временам задание также запускается в случайное время без видимой причины. Я посмотрел на триггер, и значения следующего времени срабатывания правильно обновляются в таблицах QUARTZ TRIGGER в БД для задания. Даже если задание доходит до запускается в другое время, чем обычные, о которых я упоминал выше, значение обновляется в таблице. Но это то, что нам нужно, чтобы выяснить, почему он запускается в такие неподходящие моменты. Кроме того, нет общего шаблона в этом неправильном срабатывании.   -  person FindYourself    schedule 12.10.2017
comment
Обратите внимание, что это CRON TRIGGER, настроенный в базе данных для работы. Кроме того, когда вы говорите, что не используйте getCurrentlyExecutingJobs () в классе Job, вы предлагаете какую-либо альтернативу, чтобы проверить, выполняется ли конкретное задание уже или нет, потому что согласно требованию мы должны поставить проверку и не запускать задание, если оно уже выполнено Бег. Я вижу в предоставленной вами ссылке, что они также используют метод getCurrentlyExecutingJobs (), так как это имеет значение и решение проблемы. Думаю, сейчас я ничего не пропустил. Приношу свои извинения и спасибо за то, что терпеливо относился ко мне и был со мной до сих пор .. :)   -  person FindYourself    schedule 12.10.2017
comment
Привет, Ишаиз, другие, любая помощь / комментарии по вышеизложенному. Спасибо!   -  person FindYourself    schedule 23.10.2017
comment
Привет, 1. Не могли бы вы ответить на вопрос о . Также как определить, в какое время запускалось задание? ведение журнала по java / просмотр таблиц кварца / что-то еще?. 2. Вы сказали, что Даже если задание запускается в другое время, отличное от того, которое я упомянул выше, значение обновляется в таблице - какое значение обновляется, не то? Если это так, то Quartz - это тот, кто планирует неправильное время. Так ли это? 3. На всякий случай - вы ведь работаете в кластерном режиме?   -  person yishaiz    schedule 23.10.2017
comment
4. Что касается любой альтернативы, чтобы проверить, выполняется ли уже конкретное задание или нет - поскольку вы находитесь в режиме кластера, вы должны проверить его с помощью API, считывающего из базы данных. Потому что любой API, который читает из кучи в вашей текущей JVM, не будет эффективным, потому что он не знает, выполняет ли какой-либо другой экземпляр то же задание. Итак: [1] возможно, этот ответ stackoverflow.com/a/31479434/3883957 вам подойдет. [2] Или, может быть, в Quartz есть еще одна таблица с API, который записывает эту информацию. [3] Или использовать что-то вроде Redis для распространения информации.   -  person yishaiz    schedule 23.10.2017
comment
[4] Или записать это в свою базу данных, из которой каждое задание будет читать \ писать. Но в любом случае вы используете его внутри самого задания, поэтому, возможно, вариант [1], который я вам дал, не поможет. 5. Это приводит меня к вопросу - зачем вам проверять, не запущено ли задание? Насколько мне известно, Quartz должен быть ответственным за вызов задания только один раз в кластере, так зачем вам это нужно внутри задания?   -  person yishaiz    schedule 23.10.2017
comment
6. Еще вопрос - какой 1.6 Quartz вы используете? 1.6.6 или что-то старше?   -  person yishaiz    schedule 24.10.2017
comment
Привет, Ишаиз, да, мы проверяем значения отметок времени в кварцевых таблицах и в журналах с помощью Java, и это только в кластерном режиме. Нам нужно проверить, выполняется ли задание уже или нет, потому что в случае, если нагрузка больше и оно выполняется до следующего запланированного времени, оно фактически не должно запускаться снова, а сообщить команде, что оно уже выполняется. Мы используем кварц 1.6.0.   -  person FindYourself    schedule 27.10.2017
comment
Если я правильно понимаю, вы хотите предотвратить дублирование выполнения заданий. В этом случае вы можете использовать StatefulJob, и Quartz позаботится об этом - см. Этот ответ stackoverflow.com/a/1638573 / 3883957. И тогда вам не понадобится getCurrentlyExecutingJobs. Что касается версии Quartz 1.6, вы можете захотеть обновить ее как минимум до 1.6.6 (если не до более новой версии ...), потому что кажется, что в 1.6.0 много ошибок. Например, посмотрите, что они говорят в комментариях jira.terracotta.org/jira/browse / QTZ-311   -  person yishaiz    schedule 29.10.2017
comment
Привет, Ишаиз, спасибо! Чтобы избежать этой проблемы, мы решили сделать следующее: 1) Обновите кварцевую версию как минимум до 1.6.6 или новее 2) Используйте делегат OracleDriver для Oracle DB вместо StandardJDBCTemplate 3) Удалите метод getCurrentlyExexutingJobs () из кода. Теперь у меня два вопроса: Q1 Как предотвратить перекрытие заданий. Для этого мы используем таблицу FIRED_TRIGGERS, которая сохраняет запись задания в базе данных во время его выполнения. Будет ли это нормальным подходом? Q2 Пока мы принимаем решение о версии для обновления, не могли бы вы предложить нам версию и что нужно учитывать при обновлении?   -  person FindYourself    schedule 15.11.2017
comment
1. Я думаю, что вам следует как можно больше избегать прямого доступа к таблицам Quartz и стараться использовать Quartz API как можно чаще. Но если это необходимо и решает проблему, может быть, все в порядке. Но вы должны постараться убедиться, что вы что-то не упустили при использовании этой таблицы. Но почему вы все равно не используете StatefulJob?   -  person yishaiz    schedule 15.11.2017
comment
2. Извините, но я недостаточно знаю, в чем разница между версиями и какая версия лучше всего подходит для вас (конечно, самая новая должна быть лучшей, но это более рискованно). Есть несколько руководств по миграции, например quartz-scheduler.org/ документация / quartz-2.x /   -  person yishaiz    schedule 15.11.2017
comment
Привет, Ишаиз! Мы переходим с версии 1.6.0 на 2.0.2. Кажется, все работает нормально, как будто данные поступают во вновь созданные таблицы в базе данных, но когда задания должны начинаться на самом деле, он не может этого сделать и терпит неудачу с ошибкой ниже, когда он пытается получить данные свойств из базы данных Oracle:   -  person FindYourself    schedule 22.01.2018
comment
Привет, я рекомендую вам открыть новый вопрос для этой проблемы. Это другая проблема, чем в текущем вопросе, и вам будет легче понять проблему, в настоящее время трудно понять трассировку стека. Также некоторые другие люди могут увидеть вопрос и помочь вам. после того, как вы разместите новый вопрос, вы можете написать здесь ссылку на этот вопрос, и я тоже смогу посмотреть.   -  person yishaiz    schedule 22.01.2018
comment
Привет, Ишаиз, спасибо !. Вот ссылка на новый вопрос. stackoverflow.com/questions/48396851/   -  person FindYourself    schedule 23.01.2018
comment
Привет, Ишаиз, мы недавно обновились до версии 2.0.2 с 1.6.0, но проблема все еще сохраняется. Я открыл здесь новый вопрос stackoverflow.com/questions/51400442/. Было бы здорово, если бы можно было дать какое-то понимание. Спасибо!   -  person FindYourself    schedule 18.07.2018
comment
Привет, жаль слышать, что это все еще проблема для вас. Я думаю, было бы здорово, если бы вы добавили образцы кода (файл свойств, java, xml, если необходимо) в новый вопрос, как вы добавили в этом вопросе, чтобы новый был более понятным (также для других людей, иначе они выиграли бы '' читаю все эти комментарии).   -  person yishaiz    schedule 18.07.2018