欧美vvv,亚洲第一成人在线,亚洲成人欧美日韩在线观看,日本猛少妇猛色XXXXX猛叫

新聞資訊

    我們在實(shí)際開發(fā)中,多多少少都會用到定時(shí)任務(wù)來處理一些問題。

    比如金融項(xiàng)目中的對賬,每天定時(shí)對昨天的賬務(wù)進(jìn)行核對,每個(gè)月初對上個(gè)月的賬務(wù)進(jìn)行核對等。

    還比如,我們需要處理一些老數(shù)據(jù)遷移,修復(fù)一些新項(xiàng)目和老項(xiàng)目數(shù)據(jù)不兼容的問題等等。

    學(xué)習(xí)資料的:0 基礎(chǔ) Java 自學(xué)之路(配套教程)

    常規(guī)實(shí)現(xiàn)方案

    方案1:Timer

    這個(gè)目前在項(xiàng)目中用得較少,直接貼demo代碼。

    具體的介紹可以查看api ,但是在某些框架中是有用到。

    public class TestTimer {
    
        public static void main(String[] args) {
    
            TimerTask timerTask=new TimerTask() {
                @Override
                public void run() {
                    System.out.println("task  run:"+ new Date());
                }
            };
    
            Timer timer=new Timer();
            //安排指定的任務(wù)在指定的時(shí)間開始進(jìn)行重復(fù)的固定延遲執(zhí)行。這里是每3秒執(zhí)行一次
            timer.schedule(timerTask,10,3000);
        }
    }
    

    執(zhí)行結(jié)果:

    task  run:Sun Dec 11 21:23:47 CST 2022
    task  run:Sun Dec 11 21:23:50 CST 2022
    task  run:Sun Dec 11 21:23:53 CST 2022
    

    這么使用,阿里代碼檢查插件會提示:

    從提示中可以看出,在多線程并行處理定時(shí)任務(wù)時(shí),Timer運(yùn)行多個(gè)TimerTask時(shí),只要有其中之一沒有捕獲拋出的異常,其他任務(wù)會自動(dòng)終止運(yùn)行。

    方案2:ScheduledExecutorService

    和Timer類型,也就是阿里代碼檢查插件推薦的方案:

    public class TestScheduledExecutorService {
    
        public static void main(String[] args) {
    
            ScheduledExecutorService service=Executors.newSingleThreadScheduledExecutor();
            // 參數(shù):1、任務(wù)體 2、首次執(zhí)行的延時(shí)時(shí)間
            // 3、任務(wù)執(zhí)行間隔 4、間隔時(shí)間單位
            service.scheduleAtFixedRate(()->System.out.println("task ScheduledExecutorService "+new Date()), 0, 3, TimeUnit.SECONDS);
        }
    }
    

    運(yùn)行結(jié)果:

    task ScheduledExecutorService Sun Dec 11 21:30:06 CST 2022
    task ScheduledExecutorService Sun Dec 11 21:30:09 CST 2022
    task ScheduledExecutorService Sun Dec 11 21:30:12 CST 2022
    

    阿里代碼檢查插件也會提示:

    這里提示的是我們創(chuàng)建線程池的方式,建議我們使用手動(dòng)創(chuàng)建線程池,不要使用Executors工廠類,因?yàn)槭謩?dòng)創(chuàng)建更能有效規(guī)劃資源的使用。

    方案3:spring task

    用起來也非常簡單:

    @Slf4j
    @Component
    public class ScheduledService {
    
        @Scheduled(cron="0/5 * * * * *")
        public void scheduled(){
            log.info("=====>>>>>使用cron  {}",System.currentTimeMillis());
        }
    
        @Scheduled(fixedRate=5000)
        public void scheduled1() {
            log.info("=====>>>>>使用fixedRate{}", System.currentTimeMillis());
        }
    
        @Scheduled(fixedDelay=5000)
        public void scheduled2() {
            log.info("=====>>>>>fixedDelay{}",System.currentTimeMillis());
        }
    
    }
    

    運(yùn)行結(jié)果:

    2022-12-11 21:36:25.001  INFO 10660 --- [   scheduling-1] com.tian.utils.ScheduledService          :=====>>>>>使用cron  1670765785001
    2022-12-11 21:36:28.212  INFO 10660 --- [   scheduling-1] com.tian.utils.ScheduledService          :=====>>>>>使用fixedRate1670765788212
    2022-12-11 21:36:28.212  INFO 10660 --- [   scheduling-1] com.tian.utils.ScheduledService          :=====>>>>>fixedDelay1670765788212
    2022-12-11 21:36:30.001  INFO 10660 --- [   scheduling-1] com.tian.utils.ScheduledService          :=====>>>>>使用cron  1670765790001
    2022-12-11 21:36:33.212  INFO 10660 --- [   scheduling-1] com.tian.utils.ScheduledService          :=====>>>>>使用fixedRate1670765793212
    2022-12-11 21:36:33.213  INFO 10660 --- [   scheduling-1] com.tian.utils.ScheduledService          :=====>>>>>fixedDelay1670765793213
    2022-12-11 21:36:35.001  INFO 10660 --- [   scheduling-1] com.tian.utils.ScheduledService          :=====>>>>>使用cron  1670765795001
    2022-12-11 21:36:38.214  INFO 10660 --- [   scheduling-1] com.tian.utils.ScheduledService          :=====>>>>>使用fixedRate1670765798214
    2022-12-11 21:36:38.214  INFO 10660 --- [   scheduling-1] com.tian.utils.ScheduledService          :=====>>>>>fixedDelay1670765798214
    2022-12-11 21:36:40.001  INFO 10660 --- [   scheduling-1] com.tian.utils.ScheduledService          :=====>>>>>使用cron  1670765800001
    2022-12-11 21:36:43.214  INFO 10660 --- [   scheduling-1] com.tian.utils.ScheduledService          :=====>>>>>使用fixedRate1670765803214
    2022-12-11 21:36:43.215  INFO 10660 --- [   scheduling-1] com.tian.utils.ScheduledService          :=====>>>>>fixedDelay1670765803215
    

    方案4:多線程執(zhí)行

    基于注解設(shè)定多線程定時(shí)任務(wù) :

    @Component
    @EnableScheduling   // 1.開啟定時(shí)任務(wù)
    @EnableAsync        // 2.開啟多線程
    public class MultithreadScheduleTask {
    
        @Async
        @Scheduled(fixedDelay=5000)  //間隔5秒
        public void first() throws InterruptedException {
            System.out.println("第一個(gè)定時(shí)任務(wù)開始 : " + LocalDateTime.now().toLocalTime() + "\r\n線程 : " + Thread.currentThread().getName());
            System.out.println();
            Thread.sleep(1000 * 10);
        }
    
        @Async
        @Scheduled(fixedDelay=5000)
        public void second() {
            System.out.println("第二個(gè)定時(shí)任務(wù)開始 : " + LocalDateTime.now().toLocalTime() + "\r\n線程 : " + Thread.currentThread().getName());
            System.out.println();
        }
    }
    

    運(yùn)行結(jié)果:

    第一個(gè)定時(shí)任務(wù)開始 : 21:44:02.800
    線程 : 入庫操作日志記錄表 線程1
    
    第二個(gè)定時(shí)任務(wù)開始 : 21:44:02.801
    線程 : 入庫操作日志記錄表 線程2
    
    第一個(gè)定時(shí)任務(wù)開始 : 21:44:07.801
    線程 : 入庫操作日志記錄表 線程3
    
    第二個(gè)定時(shí)任務(wù)開始 : 21:44:07.802
    線程 : 入庫操作日志記錄表 線程4
    
    第一個(gè)定時(shí)任務(wù)開始 : 21:44:12.807
    線程 : 入庫操作日志記錄表 線程5
    
    第二個(gè)定時(shí)任務(wù)開始 : 21:44:12.812
    線程 : 入庫操作日志記錄表 線程6
    ......
    

    方案5:quartz

    我們需要引入依賴:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-quartz</artifactId>
    </dependency>
    

    實(shí)現(xiàn)類:

    public class Myquartz extends QuartzJobBean {
        @Override
        protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
            System.out.println("這是我的 quartz 定時(shí)任務(wù)");
        }
    }
    

    配置類:

    /**
     * @author tianwc  公眾號:java后端技術(shù)全棧、面試專欄
     * @version 1.0.0
     * @date 2022年12月11日 21:48
     */
    @Configuration
    public class QuartzConfig {
    
        @Bean
        public JobDetail teatQuartzDetail(){
            return JobBuilder.newJob(MyQuartz.class).withIdentity("myQuartz").storeDurably().build();
        }
    
        @Bean
        public Trigger testQuartzTrigger(){
            SimpleScheduleBuilder scheduleBuilder=SimpleScheduleBuilder.simpleSchedule()
    
                    .withIntervalInSeconds(10)  //設(shè)置時(shí)間周期單位秒
                    .repeatForever();
    
            return TriggerBuilder.newTrigger().forJob(teatQuartzDetail())
    
                    .withIdentity("testQuartz")
                    .withSchedule(scheduleBuilder)
                    .build();
        }
    }
    

    只要啟動(dòng)Spring Boot項(xiàng)目,就會輸出:

    這是我的 quartz 定時(shí)任務(wù)
    這是我的 quartz 定時(shí)任務(wù)
    這是我的 quartz 定時(shí)任務(wù)
    

    其他方案

    我們在項(xiàng)目,可能會涉及動(dòng)態(tài)調(diào)整定時(shí)任務(wù)執(zhí)行core表達(dá)式、動(dòng)態(tài)關(guān)閉開啟定時(shí)任務(wù),我們可以使用SchedulingConfigurer來實(shí)現(xiàn)(使用數(shù)據(jù)庫結(jié)合來搞):

    比如:

    @Configuration
    public class ScheduledConfig implements SchedulingConfigurer {
        @Autowired
        private ApplicationContext context; 
        @Override
        public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
            for (SpringScheduledCron springScheduledCron : cronRepository.findAll()) {
                Class<?> clazz;
                Object task;
                try {
                    clazz=Class.forName(springScheduledCron.getCronKey());
                    task=context.getBean(clazz);
                } catch (ClassNotFoundException e) {
                    throw new IllegalArgumentException("spring_scheduled_cron表數(shù)據(jù)" + springScheduledCron.getCronKey() + "有誤", e);
                } catch (BeansException e) {
                    throw new IllegalArgumentException(springScheduledCron.getCronKey() + "未納入到spring管理", e);
                }
                Assert.isAssignable(ScheduledOfTask.class, task.getClass(), "定時(shí)任務(wù)類必須實(shí)現(xiàn)ScheduledOfTask接口");
                // 可以通過改變數(shù)據(jù)庫數(shù)據(jù)進(jìn)而實(shí)現(xiàn)動(dòng)態(tài)改變執(zhí)行周期
                taskRegistrar.addTriggerTask(((Runnable) task),
                        triggerContext -> {
                            //這個(gè)可以使用持久層,比如Mybatis來實(shí)現(xiàn),從數(shù)據(jù)庫中獲取
                            String cronExpression="0/10 * * * * ? "                       
                            return new CronTrigger(cronExpression).nextExecutionTime(triggerContext);
                        }
                );
            }
        }
        @Bean
        public Executor taskExecutor() {
            return Executors.newScheduledThreadPool(10);
        }
    }
    

    如果項(xiàng)目中用得到類似的,可以網(wǎng)上搜搜SchedulingConfigurer便可實(shí)現(xiàn)。

    進(jìn)而再擴(kuò)展,那就來到分布式任務(wù)調(diào)度了。

    什么是分布式任務(wù)調(diào)度?

    任務(wù)調(diào)度是指基于給定的時(shí)間點(diǎn),給定的時(shí)間間隔或者給定執(zhí)行次數(shù)自動(dòng)得執(zhí)行任務(wù)。任務(wù)調(diào)度是是操作系統(tǒng)的重要組成部分,而對于實(shí)時(shí)的操作系統(tǒng),任務(wù)調(diào)度直接影響著操作系統(tǒng)的實(shí)時(shí)性能。任務(wù)調(diào)度涉及到多線程并發(fā)、運(yùn)行時(shí)間規(guī)則定制及解析、線程池的維護(hù)等諸多方面的工作。

    WEB服務(wù)器在接受請求時(shí),會創(chuàng)建一個(gè)新的線程服務(wù)。但是資源有限,必須對資源進(jìn)行控制,首先就是限制服務(wù)線程的最大數(shù)目,其次考慮以線程池共享服務(wù)的線程資源,降低頻繁創(chuàng)建、銷毀線程的消耗;然后任務(wù)調(diào)度信息的存儲包括運(yùn)行次數(shù)、調(diào)度規(guī)則以及運(yùn)行數(shù)據(jù)等。一個(gè)合適的任務(wù)調(diào)度框架對于項(xiàng)目的整體性能來說顯得尤為重要。

    分布式任務(wù)調(diào)度框架有:cronsun、Elastic-job、saturn、lts、TBSchedule、xxl-job 等。

    另外,就是cron表達(dá)式,推薦 http://www.pppet.net/

    可以根據(jù)自己業(yè)務(wù)情況來,手動(dòng)選擇,自動(dòng)生成表達(dá)式。

    好了,今天就分享這么多。

    感謝您的關(guān)注、點(diǎn)贊、分享!

    概述

    前面有介紹過Oracle schedule的一些用法,不過很多朋友說還是不太清楚怎么用,剛好最近打算調(diào)整下定時(shí)任務(wù)的時(shí)間,所以這里順便演示下,也記錄下!


    一、檢查目前定時(shí)任務(wù)情況

    1、查看job具體定義

    select owner,job_name,job_type,job_action,comments,enabled,to_char(last_start_date,'yyyy-mm-dd hh24:mi:ss'),to_char(next_run_date,'yyyy-mm-dd hh24:mi:ss') from dba_scheduler_jobs;
    

    2、查找PROGRAM_NAME 的內(nèi)容(沒太大意義)

    select owner,type,text,name from dba_source where name like '%ARCHIVE%';
    

    3、查看歷史記錄

     select log_id,log_date ,owner,job_name,job_subname,status from DBA_SCHEDULER_JOB_LOG order by log_date desc;
    

    這里主要看之前定時(shí)任務(wù)跑的結(jié)果,是不是正常運(yùn)行。


    二、修改定時(shí)任務(wù)時(shí)間

    需求:修改定時(shí)任務(wù)為每周六1點(diǎn)進(jìn)行

    1、disable it

    begin
     dbms_scheduler.disable('SYSTEM.ARCHIVE_120_TABLES');
    end;
    /
    

    2、unschedule it (you are changing the schedule)

    begin
     dbms_scheduler.SET_ATTRIBUTE_NULL('SYSTEM.ARCHIVE_120_TABLES','SCHEDULE_NAME'); /* SCHEDULE_NAME 字段名 */
    end;
    /
    

    3、custom schedule it(星期六1點(diǎn))

    begin
     DBMS_SCHEDULER.SET_ATTRIBUTE ( name=> 'SYSTEM.ARCHIVE_120_TABLES', attribute=> 'repeat_interval', value=> 'freq=daily;byday=SAT;byhour=1;byminute=0; bysecond=0');
    end;
    /
    

    4、 enable it

    begin
     dbms_scheduler.enable('SYSTEM.ARCHIVE_120_TABLES');
    end;
    /
    

    5、查看定時(shí)任務(wù)情況

    select owner,
     job_name,
     job_type,
     job_action,
     comments,
     enabled,
     to_char(last_start_date, 'yyyy-mm-dd hh24:mi:ss'),
     to_char(next_run_date, 'yyyy-mm-dd hh24:mi:ss')
     from dba_scheduler_jobs;
    

    可以看到下一次執(zhí)行日期是下個(gè)周六1點(diǎn)。


    三、set_attribute

    attribute:是指設(shè)置job的屬性,屬性有:

    logging_level——記錄的日志信息,有三個(gè)值(DBMS_SCHEDULER.LOGGING_OFF,DBMS_SCHEDULER.LOGGING_RUNS,

    DBMS_SCHEDULER.LOGGING_FULL)

    restartable——設(shè)置job失敗是否要重啟

    max_failures——允許job失敗的次數(shù),范圍1到1000000,默認(rèn)為空。

    max_runs——job執(zhí)行的最大次數(shù),范圍1到1000000,默認(rèn)為空(即意味著job會重復(fù)執(zhí)行,或者到達(dá)job執(zhí)行的end_date,或者達(dá)到指定失敗的次數(shù))。

    一旦達(dá)到設(shè)置的最大值,job將會disable并且狀態(tài)變更為COMPLETED

    max_run_duration——設(shè)置job運(yùn)行的有效時(shí)間,如果設(shè)置了某個(gè)值,則在到達(dá)該值時(shí)調(diào)度會報(bào)JOB_OVER_MAX_DUR事件,然后由事件處理器決定是否要繼續(xù)

    instance_stickiness——只用于rac數(shù)據(jù)庫。默認(rèn)為true,設(shè)置為true,則job會運(yùn)行在負(fù)載最輕的節(jié)點(diǎn)上;如果某節(jié)點(diǎn)關(guān)閉或負(fù)載太重,則不會啟動(dòng)新job,而是有另一個(gè)節(jié)點(diǎn)來執(zhí)行該job。

    stop_on_window_close——window關(guān)閉的時(shí)候停止job,默認(rèn)為false。因此默認(rèn)情況下關(guān)閉了window,job還是會繼續(xù)執(zhí)行,但是要注意,window關(guān)閉則意味著資源使用計(jì)劃就會變化。

    job_priority——在同一個(gè)class,job執(zhí)行的優(yōu)先級,默認(rèn)為3.

    schedule_limit——允許啟動(dòng)job延遲的時(shí)間,設(shè)置值從1分鐘到99天。超過了延遲的時(shí)間則不再啟動(dòng)job。如果不設(shè)置該值,則只要得到允許所需的資源就會啟動(dòng)。另外,在延遲的這段時(shí)間里,job的執(zhí)行次數(shù)或失敗次數(shù)會跳過,不計(jì)算這段時(shí)間的。

    program_name——job執(zhí)行的對象。如果設(shè)置了該屬性,則job_action, job_type,number_of_arguments要設(shè)置為空。

    job_action——job執(zhí)行對象內(nèi)容

    job_type——job執(zhí)行對象類型('PLSQL_BLOCK', 'STORED_PROCEDURE', 'EXECUTABLE', and 'CHAIN')。如果設(shè)置了該值,那么program_name參數(shù)必須設(shè)置為空 。

    number_of_arguments——參數(shù)個(gè)數(shù)。如果設(shè)置了該值,那么program_name參數(shù)必須設(shè)置為空。

    schedule_name——調(diào)度名,如果設(shè)置了該值,則end_date, start_date和repeat_interval需設(shè)置為空。

    repeat_interval——執(zhí)行間隔,設(shè)置了該值,則schedule_name需為空。

    start_date——執(zhí)行開始時(shí)間,設(shè)置了該值,則schedule_name需為空。

    end_date——不再執(zhí)行job的時(shí)間,設(shè)置了該值,則schedule_name需為空。

    job_class——jobclass

    comments——備注

    auto_drop——當(dāng)job狀態(tài)為completed則自動(dòng)刪除該job

    event_spec——需含兩個(gè)值(event condition和queue specification)

    raise_events——設(shè)置當(dāng)job為什么狀態(tài)時(shí)拋出,具體的時(shí)間類型見event類型。


    很多時(shí)候我們在數(shù)據(jù)庫都會設(shè)置定時(shí)任務(wù),當(dāng)數(shù)量一多時(shí)時(shí)間就很容易堆積到一起,所以建議生產(chǎn)環(huán)境定時(shí)任務(wù)的時(shí)間還是要做好規(guī)劃。后面會分享更多devops和DBA方面的內(nèi)容,感興趣的朋友可以關(guān)注一下~

網(wǎng)站首頁   |    關(guān)于我們   |    公司新聞   |    產(chǎn)品方案   |    用戶案例   |    售后服務(wù)   |    合作伙伴   |    人才招聘   |   

友情鏈接: 餐飲加盟

地址:北京市海淀區(qū)    電話:010-     郵箱:@126.com

備案號:冀ICP備2024067069號-3 北京科技有限公司版權(quán)所有