标签: spring-scheduled

如何在spring-boot中启用TaskScheduler?

我正在使用spring-boot设置弹簧默认值.我想使用这种@EnableScheduling机制,并有条件地安排我的任务.

因此我必须实现SchedulingConfigurer并设置TaskScheduler明确.

但是当注入时TaskScheduler,我得到以下错误.但是为什么spring-boot不会相应地自动提供调度程序呢?

@Configuration
@EnableAutoConfiguration
@EnableScheduling
public class AppConfig {

}

@Service
public class JobService implements SchedulingConfigurer {
    @Autowired
    private TaskScheduler taskScheduler;

    //schedule the task dynamically
    @Override
    public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
        taskRegistrar.setScheduler(taskScheduler); //fails
        taskRegistrar.addTriggerTask(task, trigger);
    }
}
Run Code Online (Sandbox Code Playgroud)

错误:

Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private org.springframework.scheduling.TaskScheduler; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.scheduling.TaskScheduler] found for dependency: expected at least 1 bean which qualifies as autowire …
Run Code Online (Sandbox Code Playgroud)

java spring spring-scheduled spring-boot

7
推荐指数
1
解决办法
2万
查看次数

使用Cron安排任务,允许动态更新

我使用sprint boot 1.3,spring 4.2

在这堂课上

@Service
public class PaymentServiceImpl implements PaymentService {
    ....
    @Transactional
    @Override
    public void processPayment() {
        List<Payment> payments = paymentRepository.findDuePayment();
        processCreditCardPayment(payments);
    }
}
Run Code Online (Sandbox Code Playgroud)

我想每隔x刻拨打一次processPayment.

此x时刻在数据库中设置.用户可以修改它.

所以我想我不能使用anotation.

我开始这样做了

@EntityScan(basePackageClasses = {MyApp.class,     Jsr310JpaConverters.class})
@SpringBootApplication
@EnableCaching
@EnableScheduling
public class MyApp {

    @Autowired
    private DefaultConfigService defaultConfigService;

    public static void main(String[] args) {
        SpringApplication.run(MyApp.class, args);
    }

    @Bean
    public TaskScheduler poolScheduler() {
        SimpleAsyncTaskExecutor taskScheduler = new SimpleAsyncTaskExecutor();

        DefaultConfigDto defaultConfigDto = defaultConfigService.getByFieldName("payment-cron-task");
        String cronTabExpression = "0 0 4 * * ?";
        if (defaultConfigDto != …
Run Code Online (Sandbox Code Playgroud)

spring spring-scheduled spring-boot

7
推荐指数
1
解决办法
1万
查看次数

如何在计划任务中使用OAuth2RestTemplate?

我有两个资源服务器:一个具有用于通过电子邮件发送通知的API,另一个用于运行计划任务.当计划任务开始时,我想呼叫电子邮件服务以通知用户他们的任务正在启动.两种服务都使用OAuth2进行身份验证.计划任务服务已设置客户端凭据,以便通过提供客户端凭据来获取访问令牌: 获得令牌


致电服务

为了实现这一点,我使用Spring Boot和Spring Security OAuth2.任务服务有一个OAuth2RestTemplate来调用电子邮件服务.当计划任务启动并尝试使用OAuth2RestTemplate时,它会尝试将OAuth2ClientContext作为sesson范围的bean.显然,它不会找到一个,因为我没有在请求线程中执行,我正在后台任务线程中运行.我得到这个例外:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 
  'scopedTarget.oauth2ClientContext': Scope 'session' is not active for the current thread; 
  consider defining a scoped proxy for this bean if you intend to refer to it 
  from a singleton
Run Code Online (Sandbox Code Playgroud)

由于我使用静态客户端凭据进行系统到系统身份验证,因此我认为没有充分的理由使用会话范围的数据来处理我的访问令牌.我更希望有一个单独的OAuth2ClientContext bean,任何线程都可以使用它来通过OAuth2RestTemplate发出请求.

我该如何配置?

spring-scheduled spring-boot spring-security-oauth2

7
推荐指数
1
解决办法
2108
查看次数

Spring调度程序和spring批处理项编写器的事务问题

我正在尝试使用@Scheduled注释运行spring批处理作业,如下所示:

@Scheduled(cron = "* * * * * ?")
public void launchMessageDigestMailing() throws JobParametersInvalidException, JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException {
    jobLauncher.run(messagesDigestMailingJob, new JobParametersBuilder().addDate("execution_date", new Date()).toJobParameters());
}
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

javax.persistence.TransactionRequiredException: Executing an update/delete query
Run Code Online (Sandbox Code Playgroud)

但是,当我从spring mvc控制器启动作业时,不会发生此错误,如下所示:

@GetMapping("/messageDigestMailing")
public void launchMessageDigestMailing() throws JobParametersInvalidException, JobExecutionAlreadyRunningException, JobRestartException, JobInstanceAlreadyCompleteException {
    jobLauncher.run(messagesDigestMailingJob, new JobParametersBuilder().addDate("execution_date", new Date()).toJobParameters());
}
Run Code Online (Sandbox Code Playgroud)

我知道Spring批处理事务并且不需要@Transactional/ @EnableTransactionManagement.为什么我会得到上述异常?

我在网上找到的所有样本都使用了ResourcelessTransactionManager(参见https://www.mkyong.com/spring-batch/spring-batch-and-spring-taskscheduler-example),但我确实需要将我的工作执行持续到数据库.

有人可以帮忙吗?

编辑:这是堆栈跟踪(您可以在ItemWriter下面看到弹簧批次):

Caused by: org.springframework.dao.InvalidDataAccessApiUsageException: Executing an update/delete query; nested exception is javax.persistence.TransactionRequiredException: Executing an update/delete query …
Run Code Online (Sandbox Code Playgroud)

spring spring-batch spring-transactions spring-scheduled

7
推荐指数
1
解决办法
1224
查看次数

spring @Scheduled with cron无法解析属性

我正在使用spring框架v4.1.7并且在调度cron任务时遇到问题,我想在属性文件中定义cron参数.

我的java代码:

@Scheduled(cron = "${invoice.export.cron}")
private void scheduledExport() {
    // ... the code to execute ...
}
Run Code Online (Sandbox Code Playgroud)

在我的属性文件中,我必须invoice.export.cron: 0 0 7 * * MON-FRI?
启用我@EnableScheduling在主配置类上的调度.

我试图调试这个问题,发现应该从属性占位符这里解析cron表达式.跟着电话进入resolveStringValue我的这个位置AbstractBeanFactory.而且据我所知,这是问题所在.该this.embeddedValueResolvers列表是空的...因此它不能解决我传递到属性@Scheduled(cron).

任何人都有一个想法,如果我做错了什么或错过了什么?

提前致谢!:)

spring spring-scheduled

6
推荐指数
1
解决办法
2424
查看次数

使用zookeeper在集群中调度任务

我们使用 Spring 来运行在单节点上运行良好的计划任务。我们希望在 N 个节点的集群中运行这些计划任务,以便在一个时间点最多由一个节点执行任务。这是针对企业用例的,我们可能期望多达 10 到 20 个节点。

我研究了各种选择:

  1. 使用 Quartz,它似乎是在集群中运行计划任务的流行选择。缺点:我想避免的数据库依赖。
  2. 使用 zookeeper 并始终仅在领导者/主节点上运行计划任务。缺点:任务执行负载没有分布
  3. 使用 zookeeper 并在所有节点上调用计划任务。但是在任务运行之前获取分布式锁并在执行完成后释放。缺点:所有节点上的系统时钟应该同步,如果应用程序过载导致系统时钟漂移,这可能是一个问题。
  4. 使用zookeeper,让主节点按照时间表继续生成任务,并将其分配给随机工作者。如果先前的计划任务尚未处理,则不会分配新任务。缺点:这似乎增加了太多的复杂性。

我倾向于使用 #3,这似乎是一个安全的解决方案,假设 zookeeper 集成节点运行在一个单独的集群上,系统时钟使用 NTP 同步。这也是假设如果系统时钟同步,那么所有节点都有平等的机会获得锁来执行任务。
编辑:经过深思熟虑后,我意识到这可能不是一个安全的解决方案,因为系统时钟应该在运行计划任务的节点之间同步,而不仅仅是 Zookeeper 集群节点。我说不安全是因为运行任务的节点可能因 GC 暂停和其他原因而过载,并且时钟可能不同步。但我再次认为这是分布式系统的标准问题。

您能否告知我对每个选项的理解是否准确?或者可能有比列出的选项更好的方法来解决这个问题。

spring distributed-system spring-scheduled apache-zookeeper apache-curator

6
推荐指数
1
解决办法
4200
查看次数

Spring @Scheduled方法无法使用Spring Data JPA保存

使用SpringBoot 1.4.1.RELEASE.一个简单的任务是创建,每5秒运行一次.它使用Spring Data JPA从数据库中获取数据,通过API发送数据,并且成功后,使用Spring Data JPA更新数据库中的发送状态.

以下是调度程序代码段

@Component
public class MemberJob {
    @Value("${base.url}")
    private String baseApiUrl;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    @Qualifier("memberServiceBean")
    private EntityService memberServiceBean;

    @Scheduled(fixedDelay = 5000l)
    public void runJob() throws Exception {
         Collection<Member> notSynched = memberRepository.findAll();
         notSynched.stream().forEach(m -> {
                //Send to server: on success
                m.setSyncStatus(true);
                memberServiceBean.update(m);
         });
    }
}
Run Code Online (Sandbox Code Playgroud)

问题在于成员未成功更新.由于某些原因,Spring Data JPA无法使用@Scheduled方法.如何使数据jpa在自调用 @Scheduled方法中更新此对象?

是的在服务层的更新方法装饰有@Transactional像这样

@Transactional(propagation = Propagation.REQUIRED)
public Member update(Member m) {
    return (Member) getRepository().save(m);
}
Run Code Online (Sandbox Code Playgroud)

更新

根据对评论部分的建议,更新方法被try/catch不幸的例外所捕获!像这样

 try{
     m …
Run Code Online (Sandbox Code Playgroud)

spring-data-jpa spring-scheduled spring-boot

6
推荐指数
1
解决办法
965
查看次数

@Scheduled和@Async在spring-boot中共享相同的线程池

我已经配置了两个不同的线程池,一个用于@Scheduled和另一个用于@Async.但是,我注意到@Async没有使用线程池.

这是Scheduler配置

@Configuration
@EnableScheduling
public class SchedulerConfig implements SchedulingConfigurer {
    private final int POOL_SIZE = 10;

    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
        ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
        threadPoolTaskScheduler.setPoolSize(POOL_SIZE);
        threadPoolTaskScheduler.setThreadNamePrefix("my-sched-pool-");
        threadPoolTaskScheduler.initialize();
        scheduledTaskRegistrar.setTaskScheduler(threadPoolTaskScheduler);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是Async的配置

@Configuration
@EnableAsync
public class AppConfig {

 @Bean(name = "asyncTaskExecutor")
    public TaskExecutor asyncExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(15);
        executor.setMaxPoolSize(15);
        executor.setQueueCapacity(100);
        executor.setThreadNamePrefix("my-async-pool-");
        executor.initialize();
        return executor;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我如何调用它们

@Scheduled(fixedRateString = "2000" )
    public void schedule() {
      log.debug("here is the message …
Run Code Online (Sandbox Code Playgroud)

threadpoolexecutor spring-scheduled spring-boot taskscheduler spring-async

6
推荐指数
1
解决办法
2293
查看次数

Spring 计划的 cron 作业运行次数过多

我的作业每隔指定的时间运行一次,但它每隔指定的时间运行一次,例如,如果我将作业设置为在 22:54 运行,它将从 22:54:00 到 22:54:59 每秒运行一次。我希望它只在指定的时间运行一次...非常感谢任何帮助

我的代码:

@Scheduled(cron = "* 54 22 * * ?")
    public void getCompaniess() {
         System.out.println(new Date()+" > Running testScheduledMethod...");

    }
Run Code Online (Sandbox Code Playgroud)

输出: Thu Mar 12 22:54:00 GMT 2020 > Running testScheduledMethod... Thu Mar 12 22:54:01 GMT 2020 > Running testScheduledMethod... ..... Thu Mar 12 22:54:59 GMT 2020 > Running testScheduledMethod...

cron spring-scheduled spring-boot

6
推荐指数
1
解决办法
1585
查看次数

如何验证当前日期时间是否在 Spring Cron 表达式内?

我有一个 Spring Cron 表达式,例如 */10 * 9-17 * * MON-FRI

我想知道当前时间或任何给定时间是否在范围内。

我知道我可以使用 CronExpression 类并使用 next() 方法。但它给了我下一个有效的可运行时间。

谢谢

spring spring-scheduled spring-boot

6
推荐指数
1
解决办法
4807
查看次数