source

스프링 크론 vs 일반 크론?

factcode 2022. 9. 14. 22:12
반응형

스프링 크론 vs 일반 크론?

레거시 Java/Spring/Hibernate 프로젝트 내에서 cron 작업을 수행하려고 하기 때문에 spring 스케줄러를 사용하기로 했습니다.

매달 첫째 주 일요일 12시에 Task.doStuff를 실행해 주세요.

application-context.xml에서 작업 스케줄러를 다음과 같이 설정했습니다.

<task:scheduled-tasks scheduler="MyTaskScheduler">
    <task:scheduled ref="myTask" method="doStuff" cron="0 0 12 ? 1/1 SUN#1 *"/> <!-- Every first Sundy of the month -->
</task:scheduled-tasks>

<task:scheduler id="MyTaskScheduler" pool-size="10"/>

문제의 cron 식 자체가 0 0 12? 1/1 SUN #1* 입니다.

그리고.myTask콩이라고 하는 방법이 있습니다.doStuff유닛 테스트에서 실행했을 때 완벽하게 동작합니다.

빌드 및 도입 시 봄부터 부트 타임 예외가 발생합니다.

Caused by: java.lang.IllegalArgumentException: cron expression must consist of 6 fields (found 7 in 0 0 12 ? 1/1 SUN#1 *)
at org.springframework.scheduling.support.CronSequenceGenerator.parse(CronSequenceGenerator.java:233)
at org.springframework.scheduling.support.CronSequenceGenerator.<init>(CronSequenceGenerator.java:81)
at org.springframework.scheduling.support.CronTrigger.<init>(CronTrigger.java:54)
at org.springframework.scheduling.support.CronTrigger.<init>(CronTrigger.java:44)
at org.springframework.scheduling.config.ScheduledTaskRegistrar.afterPropertiesSet(ScheduledTaskRegistrar.java:129)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1477)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1417)

처음 cron 식을 사용하고 있기 때문에 처음에는 뭔가 잘못하고 있다고 생각했지만, cronmaker를 사용하고 있는 것을 재차 확인했더니 같은 결과가 나왔습니다.

모든 문서에는 다음과 같이 기재되어 있습니다.cron 표현식은 6개 또는7개의 서브 표현식(필드)으로 이루어진 문자열입니다.1

어떤 예에도 없기 때문에 7번째 요소(년)를 삭제하려고 하면 다른 오류 메시지가 나타납니다.

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'org.springframework.scheduling.config.ScheduledTaskRegistrar#0': Invocation of init method failed; nested exception is java.lang.NumberFormatException: For input string: "0#1"

org.springframework.filening은 다른 모든 것과 다른 cron 플레이버를 지원합니까?스프링에 특화된 문서에는 '정확한 표현'이라고만 적혀 있습니다.

이 컨텍스트에서 이 cron 식을 올바르게 동작시키려면 어떻게 해야 합니까?어떤 도움이라도 주시면 감사하겠습니다.

현시점에서는, 이 식을 간단하게 매주 일요일에 실행해, 어느 일요일인지 계산해, 그것이 효과가 있는지를 확인하기 위해서 Java 로직을 추가하는 것이 해결책입니다만, 이것은 설정 어프로치의 목적에 어긋나, 마치 안티패터인 것처럼 보입니다.

스프링 스케줄링된 작업의 형식이 cron 식과 다릅니다.

UNIX cron 식과 같은 형식을 따르지 않습니다.

필드는 6개뿐입니다.

  • 둘째,
  • 극히 작은,
  • 시간
  • 요일
  • 달,
  • 요일

아스타리스크(*)는 match any를 의미합니다.*/X는 "모든 X"를 의미합니다(예 참조).

나는 요일 숫자가 통하지 않는다.그리고 'MON-FRI'가 훨씬 읽기 쉬워요.다음은 표현의 예를 제시하겠습니다.

"0 0 18 * * MON-FRI" means every weekday at 6:00 PM. 

"0 0 */1 * * *" means every hour on the hour.

"0 0 */8 * * *" means every 8 hours on the hour.

"0 0 12 1 * *" means 12:00 PM on the first day of every month. 

여기서 몇 가지 추가 정보를 찾을 수 있습니다.

또한 스프링 설명서가 유용할 수 있습니다.

메모: https://www.baeldung.com/cron-expressions

Spring Scheduled 태스크는 다음과 같습니다.

1 2 3 4 5 6 Index
- - - - - -
* * * * * * command to be executed
- - - - - -
| | | | | | 
| | | | | ------- Day of week (MON - SUN)
| | | | --------- Month (1 - 12)
| | | ----------- Day of month (1 - 31)
| |-------------- Hour (0 - 23)
| --------------- Minute (0 - 59)
----------------- Seconds (0 - 59)

송신원: https://www.cyberciti.biz/faq/how-do-i-add-jobs-to-cron-under-linux-or-unix-oses/

Linux Cron 작업은 다음과 같습니다.

1 2 3 4 5 Index
- - - - -
* * * * * command to be executed
- - - - -
| | | | |
| | | | ----- Day of week (0 - 7) (Sunday=0 or 7)
| | | ------- Month (1 - 12)
| | --------- Day of month (1 - 31)
| ----------- Hour (0 - 23)
------------- Minute (0 - 59)

사이드 노트:

  • 어떤 기사에서는 year인 7개의 옵션 파라미터가 가능하다고 했는데, 최신 스프링을 사용해 봤는데 오류가 있어서 동작하지 않는 것 같습니다.
  • Linux cron 작업 식이 충분히 간단한 경우 앞에 0을 붙이면스케줄된 작업식으로 변환됩니다.
    • : : 5 마다다
      • */5 * * * * cron job Linux cron 업작
      • 0 */5 * * * * 스케줄

보너스: Spring Schedule Cron Generator

  1. 클릭합니다.Show code snippet
  2. 클릭합니다.Run Code snippet
  3. 재미있게 보내!

$('.select2').select2({
  width: '100%'
});

//// Init ////////////
$dropdown = $("#secondsSelect");
for (let i = 1; i < 60; i++) {
  $dropdown.append($("<option />").val(i).text(i));
}
$dropdown = $("#minSelect");
for (let i = 1; i < 60; i++) {
  $dropdown.append($("<option />").val(i).text(i));
}
$dropdown = $("#hoursSelect");
for (let i = 1; i < 24; i++) {
  $dropdown.append($("<option />").val(i).text(i));
}
$dropdown = $("#dayOfMonthSelect");
for (let i = 1; i < 32; i++) {
  $dropdown.append($("<option />").val(i).text(i));
}
//// Init End ////////////


$('.select2').on('select2:select', function(e) {
  let value = e.params.data.id;
  let prevValue = $(this).val().length > 0 ? $(this).val()[0] : null;

  if (value != parseInt(value)) {
    $(this).val(value).change();
  } else if (prevValue != parseInt(prevValue)) {
    $(this).val(value).change();
  }
  calculateSpringCron();
});

let r = function(dropdown) {
  return dropdown.val().join(",");

}

let calculateSpringCron = function() {

  let result = [
    r($("#secondsSelect")),
    r($("#minSelect")),
    r($("#hoursSelect")),
    r($("#dayOfMonthSelect")),
    r($("#monthsSelect")),
    r($("#weekdaySelect")),
  ];

  $("#result").val(result.join(" "));

  $("#result-expand").html(result.join(" &nbsp; &nbsp;"))

}

calculateSpringCron();
.ms-container {
  display: flex;
  flex-direction: column;
  width: 100%;
  padding-left: 3em;
  padding-right: 3em;
  background: none !important;
  padding-bottom: 5em;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/multi-select/0.9.12/css/multi-select.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/multi-select/0.9.12/js/jquery.multi-select.min.js"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">

<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js" integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM" crossorigin="anonymous"></script>

<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.8/css/select2.min.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.8/js/select2.min.js"></script>

<div class="row">
  <div class="col-12">
    <h1>Spring Schedule Cron Generator</h1>
  </div>
</div>
<div class="row">
  <div class="col-4">
    Seconds:
    <select id="secondsSelect" class="select2" name="states[]" multiple="multiple">
      <option value="*" selected="selected">Every seconds</option>
      <option value="*/2">Every even seconds</option>
      <option value="1-59/2">Every odd seconds</option>
      <option value="*/5">Every 5 seconds</option>
      <option value="*/10">Every 10 seconds</option>
      <option value="*/15">Every 15 seconds</option>
      <option value="*/30">Every 30 seconds</option>
    </select>
  </div>
  <div class="col-4">
    Minutes:
    <select id="minSelect" class="select2" name="states[]" multiple="multiple">
      <option value="*" selected="selected">Every minutes</option>
      <option value="*/2">Every even minutes</option>
      <option value="1-59/2">Every odd minutes</option>
      <option value="*/5">Every 5 minutes</option>
      <option value="*/10">Every 10 minutes</option>
      <option value="*/15">Every 15 minutes</option>
      <option value="*/30">Every 30 minutes</option>
    </select>
  </div>
  <div class="col-4">
    Hours:
    <select id="hoursSelect" class="select2" name="states[]" multiple="multiple">
      <option value="*" selected="selected">Every hour</option>
      <option value="*/2">Every even hour</option>
      <option value="1-11/2">Every odd hour</option>
      <option value="*/3">Every 3 hour</option>
      <option value="*/4">Every 4 hour</option>
      <option value="*/6">Every 6 hour</option>
    </select>
  </div>
</div>

<div class="row">
</div>

<div class="row">
  <div class="col-4">
    Days of month:
    <select id="dayOfMonthSelect" class="select2" name="states[]" multiple="multiple">
      <option value="*" selected="selected">Every day of month</option>
      <option value="*/2">Even day of month</option>
      <option value="1-31/2">Odd day of month</option>
      <option value="*/5">Every 5 days of month (5,10,15...)</option>
      <option value="*/10">Every 10 days of month (10,20,30...)</option>
    </select>
  </div>
  <div class="col-4">
    Months:
    <select id="monthsSelect" class="select2" name="states[]" multiple="multiple">
      <option value="*" selected="selected">Every month</option>
      <option value="*/2">Even months</option>
      <option value="1-11/2">Odd months</option>
      <option value="*/4">Every 4 months</option>
      <option value="*/6">Every 6 months(half year)</option>
      <option value="1">Jan</option>
      <option value="2">Feb</option>
      <option value="3">Mar</option>
      <option value="4">Apr</option>
      <option value="5">May</option>
      <option value="6">Jun</option>
      <option value="7">Jul</option>
      <option value="8">Aug</option>
      <option value="9">Sep</option>
      <option value="10">Oct</option>
      <option value="11">Nov</option>
      <option value="12">Dec</option>
    </select>
  </div>
  <div class="col-4">
    Weekday:
    <select id="weekdaySelect" class="select2" name="states[]" multiple="multiple">
      <option value="*" selected="selected">Every weekday</option>
      <option value="MON-FRI">Weekdays (MON-FRI)</option>
      <option value="SAT,SUN">Weekend</option>
      <option value="SUN">SUN</option>
      <option value="MON">MON</option>
      <option value="TUE">TUE</option>
      <option value="WED">WED</option>
      <option value="THU">THU</option>
      <option value="FRI">FRI</option>
      <option value="SAT">SAT</option>
    </select>
  </div>
</div>
<div class="row">
  <div class="col-12">
    Result:
    <input id="result" class="form-control" /> With a bit of seperation for better viewing:<br/>
    <h1 id="result-expand"></h1>
  </div>
</div>

언급URL : https://stackoverflow.com/questions/30887822/spring-cron-vs-normal-cron

반응형