2015-11-02 10 views
0

Я ищу рамки для планирования набора задач заселенных в базе данныхЛучший способ для планирования задач из базы данных с помощью Java (Spring)

JPA объекты выглядят как это

@Entity 
class Task extends Model { 
    @NotNull 
    @Min(1L) 
    @Column(name = "interval_ms", nullable = false) 
    Integer interval 

    @NotNull 
    String payload 

    @NotNull 
    Boolean enabled 
} 

@Entity 
class TaskResult extends Model { 
    @ManyToOne(optional = false) 
    Task task 

    @Column(nullable = false) 
    Boolean result 

    @Column(nullable = false) 
    String message 
} 

задачи должны быть выполняемый каждый интервал, определенный в поле «интервал», результат должен быть записан в таблицу TaskResult

Цель задачи - сделать запрос GET или POST, поэтому запросы должны быть объединены, чтобы избежать ситуации, когда много задачи начинаются для выполнения параллельно.

Я использую весенний ботинок.

Что такое лучшие практики здесь?

+0

- проблема создания отдельной/независимой нити для eac h задача? – nabeel

+0

Кварц (https://quartz-scheduler.org/) прекрасно сочетается с песком, который имеет интеграцию с базой данных. Вы посмотрели на него? – jny

ответ

4

Если вы используете Spring Boot, вы можете использовать компонент TaskExecutor и настроить размер пула http://docs.spring.io/spring/docs/current/spring-framework-reference/html/scheduling.html#scheduling-task-executor-usage Затем используйте TaskScheduler для определения, когда задача должна выполняться. Значения событий для этого параметра поступают из базы данных (т.е. объекта).

Как только я создал планировщик, но использовал кварц. Я создал newJob, который запускался каждые 1 минуту (но вы также можете использовать miliseconds) и искал EmailQueue в базе данных, если был найден электронный адрес, он пытается отправить его, когда возникла ошибка при отправке, он не удаляет адрес электронной почты в очереди и записывает в таблицу журнала информацию об ошибке. Планировщик (1 минута) был настроен из базы данных. В вашем случае вы должны использовать: newJob (QuartzJob.class) .withIntervalInMilliseconds

http://quartz-scheduler.org/api/2.2.0/org/quartz/SimpleScheduleBuilder.html#withIntervalInMilliseconds(long)

@Service 
public class MyQuartz implements InitializingBean, DisposableBean { 

    @Autowired 
    StdSchedulerFactory stdSchedulerFactory; 
    @Autowired 
    TableConfiguration tableConfiguration; 
    Scheduler sched = null; 
    JobDetail job, job2; 
    JobDetail[] jobs = new JobDetail[2]; 

    public void initIt() throws Exception { 

     try { 
      System.out.println("Shedulling a job..."); 
      sched = stdSchedulerFactory.getScheduler(); 
     } catch (SchedulerException e) { 
      System.err.println("Could not create scheduler."); 
      e.printStackTrace(); 
     } 
     try { 
      System.out.println("Starting scheduler"); 
      sched.start(); 
     } catch (SchedulerException e) { 
      System.err.println("Could not start scheduler."); 
      e.printStackTrace(); 
     } 
     // define the job and tie it to our QuartzJob class 
     job = newJob(QuartzJob.class).withIdentity("myJob", "group1").build(); 
     job2 = newJob(QuartzCronJob.class).withIdentity("myCronJob", "group2") 
       .build(); 
     jobs[0] = job; 
     // .. here I have more jobs ... 
     // Trigger the job to run now, and then every 5 minutes 

     Trigger trigger = newTrigger() 
       .withIdentity("myTrigger", "group1") 
       .startNow() 
       .withSchedule(
         simpleSchedule().withIntervalInMinutes(
           tableConfiguration.getTimeInterval()) 
           .repeatForever()).build(); 

     // ... more triggers also here 
     // Tell quartz to schedule the job using our trigger 
     try { 
      sched.scheduleJob(job, trigger); 
      System.out.println("..job schedulled."); 
     } catch (SchedulerException e) { 
      System.err.println("Could not schedulle a job."); 
      e.printStackTrace(); 
     } 

    } 

    @Override 
    public void destroy() throws Exception { 

     try { 
      System.out.println("Stopping scheduler..."); 
      for (int i = 0; i < jobs.length; i++) { // Destroying all jobs 
       sched.deleteJob(jobs[i].getKey()); 
      } 
      sched.shutdown(true); // Waiting for jobs to complete. 
      System.out.println("...scheduler Terminated. Good Bye."); 
     } catch (SchedulerException e) { 
      System.err.println("ERROR, scheduler cannot be stopped."); 
      e.printStackTrace(); 
     } 
    } 

    @Override 
    public void afterPropertiesSet() throws Exception { 

    } 
} 

и

@Service 
@Transactional 
public class QuartzCronJob implements Job { 
    @Override 
    public void execute(JobExecutionContext context) 
      throws JobExecutionException { 
     SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this); 
     SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); 
     Calendar calendar = new GregorianCalendar(); 
     String schedulled = sdf.format(calendar.getTime()); 

     System.out.println("LIST now " + schedulled); 
     List<EmailQueue> emails = emailQueueDao.findAllForToday(schedulled); 

     if (emails != null) { 
      for (EmailQueue email : emails) { 
       // Send email: 
       try { 
        sendmail.sendNotification(email.getFrom(), email.getTo(), 
          email.getSubject(), email.getMessage(), "Sched."); 
        // Delete email from queue: 
        emailQueueDao.delete(email.getId()); 
        System.out.println("Email sucessfully sent and deleted."); 
       } catch (Exception e) { 
        sendmail.logEmail(LoggerSeverity.ERROR, 
          "Could not send schedulled email", "Sched."); 
        System.err.println("Could not send schedulled email"); 
       } 
      } 
     } 
     // ... more code here, this is just a working sample... 
    } 
} 

Мой код не использует пулы, но я не извлекаться более чем 3 письма из базы данных, поскольку она запускается один раз в минуту :)

+0

Как справиться с этим в кластерной среде? Как избежать столкновения? – navaltiger

 Смежные вопросы

  • Нет связанных вопросов^_^