springboot + schedule

参考文章:https://blog.youkuaiyun.com/sinianliushui/article/details/78841713

参考文章: https://blog.youkuaiyun.com/hao7030187/article/details/79077464

参考文章:https://www.cnblogs.com/domi22/p/9418433.html

 

springboot的SchedulerTask相对Quartz来说,简单方便,可试用于小型的job处理。

因没法持久化因此不支持分布式部署,和动态数据源配置。

如果要

一、简易配置

1. 开启定时任务,在启动类添加以下注解

@EnableScheduling

2. 创建并发配置,并发线程

@Component
public class SchedulerConfig implements SchedulingConfigurer {

    /**
     * 设置定时任务
     * @param scheduledTaskRegistrar
     */
    @Override
    public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
        scheduledTaskRegistrar.setScheduler(Executors.newScheduledThreadPool(5));
    }
}

3. 创建scheduler,以下是没5秒触发一次,cron表达式有cron在线生成器可以用

@Component
@Slf4j
public class SchedulerTask {

    @Scheduled(cron="0/5 * * * * ? ")
    public void testTask(){
        DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        log.debug(Thread.currentThread() + "  " + sdf.format(new Date()));
    }
    @Scheduled(cron="0/5 * * * * ? ")
    public void test2Task(){
        DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        log.debug(Thread.currentThread() + "  " + sdf.format(new Date()));
    }

}

二、分开配置

如下例子,如果只有一个Bean,名字为taskScheduler,或者方法名为taskScheduler则会作为自动的Scheduler。使用 @Scheduled即对应的是此TaskScheduler。

参见文章:  https://blog.youkuaiyun.com/sinianliushui/article/details/78841713

/**
 * description: 
 * 定时任务
 * @Autor:DennyZhao
 * @Date:2019/2/15
 * @Version: 1.0.0
 */
@Component
@EnableScheduling
public class SchedulerConfig {
    /** task相关的属性文件 **/
    @Autowired
    private TaskProperties taskProperties;

    /**
     * 设备组织用Job
     * @return
     */
   @Bean("DeviceJob")
   public TaskScheduler initDeviceOrgTask(){
       ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
       //线程池大小
       scheduler.setPoolSize(taskProperties.getDeviceThreadCount());
       //线程名字前缀
       scheduler.setThreadNamePrefix("taskThread-deviceTask: ");
       scheduler.initialize();
       Trigger trigger = new CronTrigger(taskProperties.getDeviceOrgCron());
       scheduler.schedule(new DeviceOrgTask(), trigger);
       return scheduler;
   }

    /**
     * Jpush用Job
     * @return
     */
    @Bean("JpushJob")
    public TaskScheduler initJpushTask(){
        ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
        //线程池大小
        scheduler.setPoolSize(taskProperties.getJpushThreadCount());
        //线程名字前缀
        scheduler.setThreadNamePrefix("taskThread-jpushTask: ");
        scheduler.initialize();
        Trigger trigger = new CronTrigger(taskProperties.getJpushReportCron());
        scheduler.schedule(new JpushReportTask(), trigger);
        return scheduler;
    }
}

TaskPropertis

/**
 * description: 
 * JPUSH执行任务相关参数
 *
 * @Autor:DennyZhao
 * @Date:2019/2/15
 * @Version: 1.0.0
 */
@Component
@PropertySource("classpath:task-config.properties")
@ConfigurationProperties(prefix="task")
@Data
public class TaskProperties {

    /** 极光推送appKey **/
    private String jpushAppKey;
    /** 极光推送secretKey **/
    private String jpushSecretKey;



    /** 设备JOB的线程数 **/
    private int deviceThreadCount;
    /** 设备组织Cron **/
    private String deviceOrgCron;
    /** Jpush的JOB线程数 **/
    private int jpushThreadCount;
    /** Jpush的推送报告Cron **/
    private String jpushReportCron;
}

创建类实现Runable接口即可使用。

@Component
@Slf4j
public class DeviceOrgTask implements Runnable {

    @Override
    public void run() {
        DateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        log.debug(Thread.currentThread() + "  " + sdf.format(new Date()));
    }
}

 

问题: 

     1.  从以上的一简易配置中(如果不添加SchedulerConfig)也可以运行,发现如果在方法中添加Thread.sleep(),会影响下面方法的运行和下次的运行时间。

        因为默认的 ConcurrentTaskScheduler 计划执行器采用Executors.newSingleThreadScheduledExecutor() 实现单线程的执行器。

        因此要使用异步: 采用异步的方式执行调度任务,配置 Spring 的 @EnableAsync,在执行定时任务的方法上标注 @Async配置任务执行。注意线程池大小要依据单个任务时间和任务间隔。

      2. 分布式重复执行

           1.使用 redis分布式锁setnx命令 来控制是否已经存在有任务在执行。

            2.使用spring的shedLock,创建一个数据表,先更新者执行,非更新者不执行。

               参见:https://segmentfault.com/a/1190000011975027

      3. 主程序挂掉后,job停止,数据丢失

            使用redis记录执行时间。

 异常:  

[ERROR] 2019-03-21 14:00:38,757 >>> org.springframework.scheduling.support.TaskUtils$LoggingErrorHandler.handleError(TaskUtils.java:96)
[massage] Unexpected error occurred in scheduled task.
java.lang.IllegalStateException: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@8f84321 has been closed already

使用applicationContext未获取到bean异常。

因EnabledTask会使得任务在执行完后closeContext导致,在配置文件添加:

spring.cloud.task.closecontext_enable=false

 

高版本用 spring.cloud.task.close_context_enabled=false

 

参考文章: https://stackoverflow.com/questions/48933575/spring-cloud-task-scheduling-context-closed

 

转载于:https://www.cnblogs.com/DennyZhao/p/10385533.html

### 使用 Spring Boot 和 Vue 实现排班系统的示例 #### 后端部分:Spring Boot 排班服务构建 为了创建一个基于 Spring Boot 的排班系统,首先需要设置项目的结构并编写必要的代码来处理业务逻辑。 定义启动类 `ServerGatewayApplication` 来引导整个应用: ```java package com.fancy.yygh; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class ServerGatewayApplication { public static void main(String[] args) { SpringApplication.run(ServerGatewayApplication.class, args); } } ``` 此段代码初始化了 Spring Boot 应用程序[^2]。接着,在 `/api/hosp/schedule.js` 文件中添加用于获取特定日期医生排班详情的方法: ```javascript // 查询排班详情 getScheduleDetail(hoscode, depcode, workDate) { return request({ url: `/admin/hosp/schedule/getScheduleDetail/${hoscode}/${depcode}/${workDate}`, method: 'get' }) } ``` 这段 JavaScript 代码片段展示了如何通过 API 请求从服务器端检索指定医院科室某天的工作安排信息[^5]。 #### 前端部分:Vue 日历组件集成 对于前端界面的设计,则可以利用 Vue 构建交互式的用户界面。特别是针对日历视图下的排班管理模块,可以通过自定义的日历插件完成可视化操作。例如,实现一个能够显示不同时间段内可用资源(如医生)的状态,并允许管理员调整这些时间槽位上的人员分配情况的功能。 考虑到实际应用场景中的复杂度,还可以引入第三方库辅助开发,比如 Element UI 或 Ant Design of Vue 提供的成熟组件集,它们往往已经包含了丰富的样式和事件支持,有助于加快开发进度的同时也提高了用户体验的一致性和美观程度。 最后值得注意的是,当涉及到 Maven 依赖项时,确保所有必需的外部库都能顺利加载是非常重要的。如果发现某些 jar 包无法正常下载,建议按照如下方式修改 pom.xml 文件以增加额外仓库地址: ```xml <repositories> <repository> <id>spring-snapshots</id> <url>http://repo.spring.io/libs-snapshot</url> </repository> </repositories> ``` 这一步骤可以帮助解决因网络原因或其他因素造成的依赖缺失问题[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值