中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

大數據開發中定時器有哪些

發布時間:2022-01-13 09:31:46 來源:億速云 閱讀:192 作者:小新 欄目:大數據

這篇文章給大家分享的是有關大數據開發中定時器有哪些的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

前言

何為定時器,說白了就是指定一個延遲時間,到期執行,就像我們早上定的鬧鈴一樣,每天定點提醒我們起床;當然在我們各個系統中也是無處不在,比如定時備份數據,定時拉取文件,定時刷新數據等等;定時器工具也是層出不窮比如Timer,ScheduledExecutorService,Spring Scheduler,HashedWheelTimer(時間輪),Quartz,Xxl-job/Elastic-job等;本文將對這些定時器工具做個簡單介紹和對比,都在哪些場景下使用。

Timer

Timer可以說是JDK提供最早的一個定時器了,使用簡單,功能也相對來說比較簡單;可以指定固定時間后觸發,固定時間點觸發,固定頻率觸發;

Timer timer = new Timer();
timer.schedule(new TimerTask() {@Overridepublic void run() {
        System.out.println(System.currentTimeMillis() + "  === task1");
    }
}, 1000, 1000);

時間默認為毫秒,表示延遲一秒后執行任務,并且頻率為1秒執行任務;Timer內部使用TaskQueue存放任務,使用TimerThread單線程用來執行任務:

private final TaskQueue queue = new TaskQueue();private final TimerThread thread = new TimerThread(queue);

TimerThread內部是一個while(true)循環,不停的從TaskQueue中獲取任務執行;當然每次添加到TaskQueue中的任務會進行排序,通過nextExecutionTime來進行排序,這樣TimerThread每次都可以獲取到最近執行的任務;
Timer有兩大缺點:

  • TimerTask中出現未捕獲的異常,影響Timer;

  • 因為是單線程執行某個任務執行時間過長會影響其他認為的精確度;

正因為Timer存在的一些缺點,JDK1.5出現了新的定時器ScheduledExecutorService;

ScheduledExecutorService

JDK1.5提供了線程池的功能,ScheduledExecutorService是一個接口類,具體實現類是ScheduledThreadPoolExecutor繼承于ThreadPoolExecutor;

ScheduledExecutorService scheduledExecutorService = Executors.newScheduledThreadPool(2);
scheduledExecutorService.scheduleAtFixedRate(new Runnable() {@Overridepublic void run() {
        System.out.println(Thread.currentThread() + " === " + System.currentTimeMillis() + " === task1");
    }
}, 1000, 1000, TimeUnit.MILLISECONDS);

比起Timer可以配置多個線程去執行定時任務,同時異常任務并不會中斷ScheduledExecutorService,線程池的幾個核心配置:

  • corePoolSize:核心線程數量,如果線程池中的線程少于此數目,則在執行任務時創建,核心線程不會被回收;

  • maximumPoolSize:允許的最大線程數,當線程數量達到corePoolSize且workQueue隊列滿了,會創建線程;

  • keepAliveTime:超過corePoolSize空閑時間;

  • unit:keepAliveTime的單位;

  • workQueue:當線程超過corePoolSize,新的任務會被加入到隊列中等待;

  • threadFactory:創建線程的工廠類;

  • handler:線程池拒絕策略,包括:AbortPolicy,DiscardPolicy,DiscardOldestPolicy,CallerRunsPolicy策略,當然也可以自己擴展;

ScheduledExecutorService中添加的任務會被包裝成一個ScheduledFutureTask類,同時將任務放入DelayedWorkQueue隊列中是一個BlockingQueue;類似Timer也會根據加入任務觸發時間的先后進行排序,然后線程池中的Worker會到Queue中獲取任務執行;

Spring Scheduler

Spring提供了xml和注解方式來配置調度任務,如下面xml配置:

<!-- 創建一個調度器 --><task:scheduler id="scheduler" /><!-- 配置任務類的bean --><bean id="helloTask" class="com.spring.task.HelloTask"></bean><task:scheduled-tasks scheduler="scheduler"><!-- 每2秒執行一次 --><task:scheduled ref="helloTask" method="say" cron="0/2 * * * * ?" /></task:scheduled-tasks>

Spring提供了cron表達式的支持,并且可以直接配置執行指定類中的指定方法,對使用者來說更加方便和簡單;但是其內部還是使用的ScheduledThreadPoolExecutor線程池;

HashedWheelTimer

Netty提供的一個定時器,用于定時發送心跳,使用的是時間輪算法;HashedWheelTimer是一個環形結構,可以類比成一個時鐘,整個環形結構由一個個小格組成,每個小格可以存放很多任務,隨著時間的流逝,指針轉動,然后執行當前指定格子中的任務;任務通過取模的方式決定其應該放在哪個格子,有點類似hashmap;

HashedWheelTimer hashedWheelTimer = new HashedWheelTimer(1000, TimeUnit.MILLISECONDS, 16);
hashedWheelTimer.newTimeout(new TimerTask() {@Overridepublic void run(Timeout timeout) throws Exception {
        System.out.println(System.currentTimeMillis() + "  === executed");
    }
}, 1, TimeUnit.SECONDS);

其中初始化的三個參數分別是:

  • tickDuration:每一格的時長;

  • unit:tickDuration的單位;

  • ticksPerWheel:時間輪總共有多少格;

如上面實例配置的參數,每一格時長1秒,時間輪總共16格,如果延遲1秒執行,那就放到編號1的格子中,從0開始;如果延遲18秒,那么會放到編號為2的格子中,同時指定remainingRounds=1,表示第幾輪被調用,每轉一輪remainingRounds-1,知道remainingRounds=0才會被執行;

Quartz

以上介紹的幾種定時器都是進程內的調度,而Quartz提供了分布式調度,所有被調度的任務都可以存放到數據庫中,每個業務節點通過搶占式的方式去獲取需要執行的任務,其中一個節點出現問題并不影響任務的調度;

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"destroy-method="close"><property name="driverClass" value="com.mysql.jdbc.Driver" /><property name="jdbcUrl" value="jdbc:mysql://localhost:3306/quartz" /><property name="user" value="root" /><property name="password" value="root" /></bean><bean id="scheduler"class="org.springframework.scheduling.quartz.SchedulerFactoryBean"><property name="schedulerName" value="myScheduler"></property><property name="dataSource" ref="dataSource" /><property name="configLocation" value="classpath:quartz.properties" /><property name="triggers"><list><ref bean="firstCronTrigger" /></list></property></bean>

更多關于Quartz的介紹可以參考本人之前的文章:

  • Spring整合Quartz分布式調度

  • Quartz數據庫表分析

  • Quartz調度源碼分析

  • 基于Netty+Zookeeper+Quartz調度分析

當然Quartz本身也有不足的地方:底層調度依賴數據庫的悲觀鎖,誰先搶到誰調度,這樣會導致節點負載不均衡;還有調度和執行耦合在一起,導致調度器會受到業務的影響;

Xxl-job/Elastic-job

正因為Quartz存在著很多不足的地方,基于Quartz實現的分布式調度解決方案出現了包括Xxl-job/Elastic-job等;
整體思路:調度器和執行器拆成不同的進程,調度器還是依賴Quartz本身的調度方式,但是調度的并不是具體業務的QuartzJobBean,而是統一的一個RemoteQuartzJobBean,在此Bean中通過遠程調用執行器去執行具體業務Bean;具體的執行器在啟動時注冊到注冊中心(如Zookeeper)中,調度器可以在注冊中心(如Zookeeper)獲取執行器信息,并通過相關的負載算法指定具體的執行器去執行;
還提供了運維管理界面,可以管理任務,比如像xxl-job:
大數據開發中定時器有哪些

當然還有更多其他的功能,此處就不在介紹了,可以直接去查看官網;

選擇合適的定時器

其實整體可以分為兩大類:進程內定時器包括和分布式調度器;
進程內定時器:Timer,ScheduledExecutorService,Spring Scheduler,HashedWheelTimer(時間輪);
分布式調度器:Quartz,Xxl-job/Elastic-job;
所以首先根據需要僅僅只需要進程內的定時器,還是需要分布式調度;
其次在進程內Timer基本可以被淘汰了,完全可以使用ScheduledExecutorService來代替,如果系統使用了Spring那當然應該使用Spring Scheduler;
下面重點看看ScheduledExecutorService和HashedWheelTimer,ScheduledExecutorService內部使用的是DelayedWorkQueue,任務的新增、刪除會導致性能下降;而HashedWheelTimer并不受任務數量限制,所以如果任務很多并且任務執行時間很短比如心跳,那么HashedWheelTimer是最好的選擇;HashedWheelTimer是單線程的,如果任務不多并且執行時間過長,影響精確度,而ScheduledExecutorService可以使用多線程這時候選擇ScheduledExecutorService更好;
最后分布式調度器里面Quartz和Xxl-job/Elastic-job,對分布式調度要求不高的情況下才會選擇Quartz,不然都應該選擇Xxl-job/Elastic-job

感謝各位的閱讀!關于“大數據開發中定時器有哪些”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

天全县| 宜州市| 浦北县| 东乌珠穆沁旗| 项城市| 梧州市| 邵阳市| 大埔区| 凤冈县| 洮南市| 柳林县| 滨州市| 洛南县| 潞城市| 赤峰市| 古田县| 浠水县| 舟山市| 章丘市| 漳平市| 万载县| 辽中县| 霍州市| 平山县| 和平区| 鹤庆县| 唐山市| 麟游县| 米易县| 嘉定区| 乌兰察布市| 石景山区| 余江县| 通城县| 金华市| 乐昌市| 浠水县| 长兴县| 图木舒克市| 固始县| 南丹县|