2011-11-23 36 views
5

Tôi đang sử dụng Quartz with Spring để chạy một nhiệm vụ cụ thể vào nửa đêm vào ngày đầu tiên của tháng. Tôi đã kiểm tra công việc bằng cách đặt ngày máy chủ của tôi & thời gian là 11:59 vào ngày cuối cùng của tháng, bắt đầu máy chủ và quan sát nhiệm vụ chạy khi đến 12:00, nhưng tôi lo ngại về các trường hợp máy chủ (vì bất kỳ lý do gì) có thể không chạy vào nửa đêm vào ngày đầu tiên của tháng.Chạy Công việc Thạch anh Bỏ lỡ

Tôi cho rằng việc xử lý không phù hợp trong Quartz sẽ quan tâm đến điều này, nhưng có thể tôi đã nhầm lẫn về điều đó?

Có ai có thể tư vấn cho tôi về cách tôi có thể xử lý việc này không? Tôi thực sự không muốn tạo một công việc chạy mỗi 'x' giây/phút/giờ và kiểm tra xem tôi có cần chạy công việc không nếu tôi có thể tránh được.

Tôi cũng tò mò là tại sao tôi không thấy bất kỳ thông tin đăng nhập liên quan đến Quartz nào, nhưng đó là vấn đề phụ.

Dưới đây là cấu hình mùa xuân của tôi cho công việc:

<bean id="schedulerService" class="com.bah.pams.service.scheduler.SchedulerService"> 
    <property name="surveyResponseDao" ref="surveyResponseDao"/> 
    <property name="organizationDao" ref="organizationDao"/> 
</bean> 

<bean name="createSurveyResponsesJob" class="org.springframework.scheduling.quartz.JobDetailBean"> 
    <property name="jobClass" value="com.bah.pams.service.scheduler.jobs.CreateSurveyResponsesJob"/> 
    <property name="jobDataAsMap"> 
     <map> 
      <entry key="schedulerService" value-ref="schedulerService"/> 
     </map> 
    </property> 
</bean> 
<!-- Cron Trigger --> 
<bean id="cronTrigger" class="org.springframework.scheduling.quartz.CronTriggerBean"> 
    <property name="jobDetail" ref="createSurveyResponsesJob"/> 
    <property name="cronExpression" value="0 0 0 1 * ? *"/> 
    <!--if the server is down at midnight on 1st of month, run this job as soon as it starts up next --> 
    <property name="misfireInstructionName" value="MISFIRE_INSTRUCTION_FIRE_ONCE_NOW"/> 
</bean> 

<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean"> 

    <property name="autoStartup" value="true"/> 

    <property name="quartzProperties"> 
     <props> 
      <prop key="org.quartz.jobStore.class">org.quartz.simpl.RAMJobStore</prop> 
      <prop key="org.quartz.jobStore.misfireThreshold">60000</prop> 
     </props> 
    </property> 
    <property name="jobDetails"> 
     <list> 
      <ref bean="createSurveyResponsesJob"/> 
     </list> 
    </property> 

    <property name="triggers"> 
     <list> 
      <ref bean="cronTrigger"/> 
     </list> 
    </property> 
</bean> 

Trả lời

2

MISFIRE_INSTRUCTION_FIRE_ONCE_NOW là nhằm mục đích bạn đề cập đến và nếu bạn nghi ngờ ngừng hoạt động của máy chủ (s), bạn chắc chắn nên kiên trì công việc của bạn ra khỏi bộ nhớ JVM (ví dụ: bằng cách sử dụng JDBCJobStore thay vì RAMJobStore).

RAMJobStore nhanh và nhẹ, nhưng tất cả thông tin lập lịch bị mất khi quá trình chấm dứt.

http://quartz-scheduler.org/documentation/quartz-2.x/configuration/ConfigRAMJobStore

JDBCJobStore được sử dụng để lưu trữ thông tin lịch (công việc, gây nên và lịch) trong một cơ sở dữ liệu quan hệ.

http://quartz-scheduler.org/documentation/quartz-2.x/configuration/ConfigJobStoreTX

Hy vọng nó giúp.

0

Tôi cũng đã phải đối mặt với vấn đề muốn chạy công việc được sắp xếp cuối cùng trên máy chủ khởi động lại.

Đây là giải pháp tôi đã tìm thấy là quay lại một khoảng thời gian cho trình kích hoạt và tính toán thời gian kích hoạt tiếp theo. Bằng cách lặp qua tất cả các trình kích hoạt thời gian gần đây nhất mà một trình kích hoạt nên đã kích hoạt trong quá khứ có thể được xác định.


Tính khoảng cách giữa mỗi bắn:

Date nextFireTime = trigger.getNextFireTime(); 
Date subsequentFireTime = trigger.getFireTimeAfter(nextFireTime); 
long interval = subsequentFireTime.getTime() - nextFireTime.getTime(); 

Tìm lần bắn tiếp theo cho một thời gian cho đến khi khoảng thời gian trong quá khứ:

Date previousPeriodTime = new Date(System.currentTimeMillis() - interval); 
Date previousFireTime = trigger.getFireTimeAfter(previousPeriodTime); 

Tôi đã tìm thấy rằng nếu bạn đang sử dụng a CronTrigger điều này ngăn cản bạn yêu cầu một thời gian cháy trong quá khứ.Để làm việc xung quanh này tôi sửa đổi thời gian bắt đầu, vì vậy đoạn trên trở thành:

Date originalStartTime = trigger.getStartTime(); // save the start time 
Date previousPeriodTime = new Date(originalStartTime.getTime() - interval); 
trigger.setStartTime(previousPeriodTime); 
Date previousFireTime = trigger.getFireTimeAfter(previousPeriodTime); 
trigger.setStartTime(originalStartTime); // reset the start time to be nice 

Duyệt qua tất cả các trigger và tìm ra một trong đó là gần đây nhất là trong quá khứ:

for (String groupName : scheduler.getTriggerGroupNames()) { 
    for (String triggerName : scheduler.getTriggerNames(groupName)) { 
     Trigger trigger = scheduler.getTrigger(triggerName, groupName); 
     // code as detailed above... 
     interval = ... 
     previousFireTime = ... 
    } 
} 

tôi sẽ để nó như một bài tập cho người đọc để cấu trúc lại nó thành các phương thức hoặc các lớp trợ giúp. Tôi thực sự sử dụng thuật toán trên trong trình kích hoạt ủy nhiệm được phân lớp mà sau đó tôi đặt trong một tập hợp được sắp xếp theo thời gian kích hoạt trước đó.

Các vấn đề liên quan