[정상 설치] Spring 통합 Quartz 2 정시 임무 실현 4: 세분 화 조정 및 이미 알 고 있 는 문제 들

이전에 이미 기능 을 기본적으로 실현 하 였 으 니, 여기 서 우 리 는 코드 를 다시 최적화 하 자.
시간 작업 을 만 들 고 수정 하 며 삭제 할 때 quartz 의 작업 은 간단 한 도구 보조 클래스 로 봉 인 될 수 있 습 니 다. 예 를 들 어 만 든 코드 는 다음 과 같이 추출 할 수 있 습 니 다.

  
  
  
  
  1. /**
  2. *
  3. *
  4. * @param scheduler the scheduler
  5. * @param jobName the job name
  6. * @param jobGroup the job group
  7. * @param cronExpression the cron expression
  8. * @param isSync the is sync
  9. * @param param the param
  10. */
  11. public static void createScheduleJob(Scheduler scheduler, String jobName, String jobGroup,
  12. String cronExpression, boolean isSync, Object param) {
  13. //
  14. Class<? extends Job> jobClass = isSync ? JobSyncFactory.class : JobFactory.class;
  15. // job
  16. JobDetail jobDetail = JobBuilder.newJob(jobClass).withIdentity(jobName, jobGroup).build();
  17. // ,
  18. jobDetail.getJobDataMap().put(ScheduleJobVo.JOB_PARAM_KEY, param);
  19. //
  20. CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cronExpression);
  21. // cronExpression trigger
  22. CronTrigger trigger = TriggerBuilder.newTrigger().withIdentity(jobName, jobGroup)
  23. .withSchedule(scheduleBuilder).build();
  24. try {
  25. scheduler.scheduleJob(jobDetail, trigger);
  26. } catch (SchedulerException e) {
  27. LOG.error(" ", e);
  28. throw new ScheduleException(" ");
  29. }
  30. }

작업 의 구체 적 인 정 보 를 Scheduler 를 포함 하여 모두 매개 변수 방식 으로 전송 합 니 다.
앞의 글 을 본 학생 들 은 quartz 가 spring 에서 성명 해 야 할 대상 이 한 줄 밖 에 남지 않 았 다 는 것 을 기억 할 수 있 습 니 다.

  
  
  
  
  1. <bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean" />

이 scheduler Factory Bean 은 spring 에서 만 설명 할 뿐 특별한 조작 을 하지 않 았 습 니 다. 보조 도구 류 에서 단일 모드 로 만 드 는 것 이 좋 지 않 습 니 다. 인 자 를 적 게 전달 할 수 있 습 니까?
당신 이 생각 하 는 것 이 맞습니다. 이런 방식 은 확실히 더 좋 고 결합 도 풀 수 있 습 니 다. 그러나 우 리 는 Scheduler Factory Bean 류 의 코드 를 살 펴 보 겠 습 니 다.

  
  
  
  
  1. public class SchedulerFactoryBean extends SchedulerAccessor implements FactoryBean<Scheduler>, BeanNameAware, ApplicationContextAware, InitializingBean, DisposableBean, SmartLifecycle {
  2. //......
  3. }

이 는 spring 의 Factory Bean 인 터 페 이 스 를 실현 했다. 즉, 만 들 때 간단 한 new 가 아니 라 다른 복잡 한 행동 도 섞 여 있 기 때문에 우 리 는 특별히 어떻게 할 필요 가 없다. spring 에서 설명 하 는 것 이 좋 겠 다.
그리고 getObject () 방법 을 봅 니 다.

  
  
  
  
  1. public Scheduler getObject() {
  2. return this.scheduler;
  3. }

실제 되 돌아 온 것 이 Scheduler 대상 이라는 것 을 알 게 되 었 습 니 다. 그렇다면 우리 클래스 에 scheduler Factory Bean 을 주입 하지 않 고 getScheduler () 를 호출 하 는 것 이 귀 찮 습 니 다. Scheduler 대상 을 직접 설명 할 수 있 습 니 다.

  
  
  
  
  1. @Service
  2. public class ScheduleJobServiceImpl implements ScheduleJobService {
  3. /** Bean */
  4. @Autowired
  5. private Scheduler scheduler;
  6. //......
  7. }

물론 scheduler Factory Bean 을 주입 하 는 것 도 틀 리 지 않 을 것 입 니 다. spring 소스 코드 를 본 학생 들 은 이것 이 getBean ("bean") 과 getBean ("& bean") 의 차이 점 임 을 바로 알 수 있 을 것 입 니 다.
그리고 앞에서 빠 뜨 린 두 곳 을 말 해 보 세 요.
1. 업데이트 작업
이전에 우리 가 작업 을 업데이트 할 때 정 해진 작업 의 실행 시간 을 업 데 이 트 했 지만 매개 변 수 를 업데이트 하지 않 았 습 니 다. 즉, context. getMerged JobDataMap (). get (...) 방법 으로 얻 은 매개 변 수 는 아직 낡 았 습 니 다.
만약 에 우리 가 작업 의 시간 표현 식 을 업데이트 했다 고 가정 하면 작업 은 새로운 시간 표현 식 에 따라 실 행 했 지만 파 라 메 터 를 가 져 온 후에 시간 표현 식 이 원래 의 것 임 을 알 수 있 습 니 다.
매개 변 수 를 업데이트 하려 고 시도 합 니 다. 다음 코드 를 사용 하 십시오.

  
  
  
  
  1. JobDetail jobDetail = scheduler.getJobDetail(getJobKey(jobName, jobGroup));
  2. //jobDetail = jobDetail.getJobBuilder().ofType(jobClass).build();
  3. //
  4. JobDataMap jobDataMap = jobDetail.getJobDataMap();
  5. jobDataMap.put(ScheduleJobVo.JOB_PARAM_KEY, param);
  6. jobDetail.getJobBuilder().usingJobData(jobDataMap);

업데이트 할 수 없 음 을 발 견 했 습 니 다. 다른 api 를 시도 해 보 았 지만 방법 이 없 었 습 니 다. 마지막 으로 작업 을 삭제 한 다음 에 만 드 는 방식 으로 매개 변수의 업 데 이 트 를 우회 적 으로 실 현 했 습 니 다.demo 에서 업데이트 작업 은 직접 수정 방식 과 삭제 수정 방식 이 있 습 니 다. 차이 점 은 바로 여기에 있 습 니 다.
2. 작업 의 동기 화 와 비동기
동기 화 와 비동기 가 quartz 2.2 버 전에 서 사용자 에 게 차이 점 은 job 류 에 @ DisallowConcurrentExecution 주 해 를 추 가 했 는 지 여부 에 있 습 니 다.
이 특징 에 따라 우 리 는 두 개의 job 실현 공장 류 를 구축 하고 그 중의 한 가지 유형 에 주 해 를 추가 합 니 다 @ Disallow ConcurrentExecution 을 추가 한 다음 에 작업 을 추가 할 때의 매개 변수 에 따라 구체 적 으로 무엇 을 사용 하 는 지 확인 할 수 있 습 니 다.

  
  
  
  
  1. //
  2. Class<? extends Job> jobClass = isSync ? JobSyncFactory.class : JobFactory.class;

정시 작업 이 실 행 될 때 업데이트 하 는 것 은 동기 화 와 비동기 화 를 바 꿀 수 없 음 을 주의해 야 합 니 다.
다음은 최신 정 리 된 demo 그림 입 니 다.
다음은 내 가 통합 사용 할 때 겪 은 이미 알 고 있 는 문제 들 을 말 해 보 자.
1. 작업 을 업데이트 할 때 매개 변수 문제.앞에서 말 한 작업 에 들 어 오 는 인 자 를 업데이트 할 수 없습니다.
2. 동기 화 또는 비동기 가 정시 작업 이 실 행 될 때 수정 할 수 없습니다. 이것 은 앞에서 도 언급 했 습 니 다.
3. 정시 작업 이 실 행 될 때 수정 하면 작업 을 장시간 스 레 드 차단 상태, 즉 BLOCKED 상태 로 만 들 수 있 습 니 다. 작업 중 간단 한 한 줄 System. out 출력 만 있 더 라 도.그것 을 회복 시 키 는 것 도 간단 하 다. 재건 축 을 삭제 하면 된다.
4. 정시 임무 가 두 번 실행 되 는 문제.이것 도 인터넷 에서 가장 많이 올 라 온 문제 입 니 다. 여기 서 중점적으로 말씀 드 리 겠 습 니 다.
인터넷 상에 서 이 문 제 를 일 으 킨 원인 은 현재 주로 두 가지 설 이 있다.
1. spring 프로필 을 여러 번 불 러 와 서 quartz 의 bean 이 여러 번 예화 되 어 작업 이 여러 번 실 행 됩 니 다.
2. tomcat 의 webapps 디 렉 터 리 문제.tomcat 가 실 행 될 때 두 번 의 설정 파일 을 불 러 와 서 작업 을 여러 번 실 행 했 습 니 다.
이 두 가지 견 해 는 나의 demo 에 존재 하지 않 을 것 이지 만 검증 을 위해 나 도 시도 해 보 았 다.
tomcat 를 사용 하지 않 고 main 방법 에서 프로 그래 밍 방식 으로 spring 을 시작 합 니 다. 심지어 spring 을 사용 하지 않 고 quartz 로 공식 적 으로 제 시 된 코드 를 사용 합 니 다.

  
  
  
  
  1. try {
  2. // Grab the Scheduler instance from the Factory
  3. Scheduler scheduler = StdSchedulerFactory.getDefaultScheduler();
  4. // and start it off
  5. scheduler.start();
  6. scheduler.shutdown();
  7. } catch (SchedulerException se) {
  8. se.printStackTrace();
  9. }

문제 가 존재 합 니 다. 이것 은 설정 파일 로 딩 의 문제 가 아니 라 quartz 자체 에 존재 하 는 bug 일 것 입 니 다. 그리고 이 여러 번 실행 하 는 것 은 매우 규칙 적 입 니 다. 기본적으로 다음 과 같은 방법 으로 갑 니 다.
5 초 에 한 번 운행 하 는 것 으로 정 해 져 있 으 며, 모든 것 이 정상 적 이 며, 여러 번 실행 되 는 현상 이 발생 하지 않 았 다
10 초 에 한 번 운행 하 는 것 으로 정 해 져 있 으 며, 모든 것 이 정상 적 이 며, 여러 번 실행 되 는 현상 이 발생 하지 않 았 다
29 초 에 한 번 운행 하고 운행 할 때 한 번 은 정상 이 며 한 번 은 정상 이 아니다
59 초 에 한 번 운행 하고 운행 할 때 한 번 은 정상 이 며 한 번 은 정상 이 아니다
이상 은 내 가 실측 해 낸 것 이 고, 더 오래 측정 하지 못 했 으 니, 필경 시간 이 너무 걸 렸 기 때문이다.두 번 운행 하 는 현상 이 있 을 때 모두 간격 이 있다. 즉, 한 번 은 정상 이 고 한 번 은 정상 이 아니다.
quartz 자체 에 bug 가 존재 하 는 것 으로 추정 되 는 이상 우 리 는 이 문 제 를 어떻게 해결 해 야 합 니까?
사실 개인 적 으로 이 문 제 는 중요 하지 않 은 데 왜 중요 하지 않다 고 말 합 니까?이것 은 당신 의 프로젝트 업무 설계 가 완벽 한 지, 코드 가 건장 한 지 에 관 한 것 입 니 다.
디자인 이 좋 은 업무 방법, 특히 외부 호출 을 위 한 인터페이스 나 방법 은 모두 멱 등 성 을 지원 해 야 하 는데, 무엇이 멱 등 성 입 니까?즉, 이 방법 은 같은 매개 변 수 는 적어도 한 시간 구간 에서 내 가 1 번 호출 하고 10 번 100 번 호출 하 는 것 과 결 과 는 모두 같다.
멱 등 성 을 지 지 했 습 니 다. 앞에서 말 한 두 번 의 운행 상황 은 중요 하지 않 습 니까?일부 정시 임 무 는 분포 식 으로 설 계 된 시스템 (나중에 검토) 에서 정시 임 무 를 수행 하기 위해 의도 적 으로 두 번 호출 하기 도 한다.
물론 멱 등 성 을 지원 하 는 것 은 방법 에 들 어 갈 때 판단 하 는 것 이 좋 습 니 다. 이미 실 행 된 시간 이 지나 면 바로 돌아 가 는 것 이 아니 라 같은 결 과 를 다시 실행 하여 자원 을 절약 하 는 것 이 좋 습 니 다.
전체 데모 원본 주소:

좋은 웹페이지 즐겨찾기