這篇文章給大家分享的是有關(guān)大數(shù)據(jù)開發(fā)中定時(shí)器有哪些的內(nèi)容。小編覺得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過來看看吧。
創(chuàng)新互聯(lián)建站專注為客戶提供全方位的互聯(lián)網(wǎng)綜合服務(wù),包含不限于網(wǎng)站設(shè)計(jì)制作、成都網(wǎng)站建設(shè)、資源網(wǎng)絡(luò)推廣、微信平臺(tái)小程序開發(fā)、資源網(wǎng)絡(luò)營銷、資源企業(yè)策劃、資源品牌公關(guān)、搜索引擎seo、人物專訪、企業(yè)宣傳片、企業(yè)代運(yùn)營等,從售前售中售后,我們都將竭誠為您服務(wù),您的肯定,是我們最大的嘉獎(jiǎng);創(chuàng)新互聯(lián)建站為所有大學(xué)生創(chuàng)業(yè)者提供資源建站搭建服務(wù),24小時(shí)服務(wù)熱線:028-86922220,官方網(wǎng)址:chinadenli.net
何為定時(shí)器,說白了就是指定一個(gè)延遲時(shí)間,到期執(zhí)行,就像我們?cè)缟隙ǖ聂[鈴一樣,每天定點(diǎn)提醒我們起床;當(dāng)然在我們各個(gè)系統(tǒng)中也是無處不在,比如定時(shí)備份數(shù)據(jù),定時(shí)拉取文件,定時(shí)刷新數(shù)據(jù)等等;定時(shí)器工具也是層出不窮比如Timer,ScheduledExecutorService,Spring Scheduler,HashedWheelTimer(時(shí)間輪),Quartz,Xxl-job/Elastic-job等;本文將對(duì)這些定時(shí)器工具做個(gè)簡單介紹和對(duì)比,都在哪些場(chǎng)景下使用。
Timer可以說是JDK提供最早的一個(gè)定時(shí)器了,使用簡單,功能也相對(duì)來說比較簡單;可以指定固定時(shí)間后觸發(fā),固定時(shí)間點(diǎn)觸發(fā),固定頻率觸發(fā);
Timer timer = new Timer(); timer.schedule(new TimerTask() {@Overridepublic void run() { System.out.println(System.currentTimeMillis() + " === task1"); } }, 1000, 1000);
時(shí)間默認(rèn)為毫秒,表示延遲一秒后執(zhí)行任務(wù),并且頻率為1秒執(zhí)行任務(wù);Timer內(nèi)部使用TaskQueue存放任務(wù),使用TimerThread單線程用來執(zhí)行任務(wù):
private final TaskQueue queue = new TaskQueue();private final TimerThread thread = new TimerThread(queue);
TimerThread內(nèi)部是一個(gè)while(true)循環(huán),不停的從TaskQueue中獲取任務(wù)執(zhí)行;當(dāng)然每次添加到TaskQueue中的任務(wù)會(huì)進(jìn)行排序,通過nextExecutionTime來進(jìn)行排序,這樣TimerThread每次都可以獲取到最近執(zhí)行的任務(wù);
Timer有兩大缺點(diǎn):
TimerTask中出現(xiàn)未捕獲的異常,影響Timer;
因?yàn)槭菃尉€程執(zhí)行某個(gè)任務(wù)執(zhí)行時(shí)間過長會(huì)影響其他認(rèn)為的精確度;
正因?yàn)門imer存在的一些缺點(diǎn),JDK1.5出現(xiàn)了新的定時(shí)器ScheduledExecutorService;
JDK1.5提供了線程池的功能,ScheduledExecutorService是一個(gè)接口類,具體實(shí)現(xiàn)類是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可以配置多個(gè)線程去執(zhí)行定時(shí)任務(wù),同時(shí)異常任務(wù)并不會(huì)中斷ScheduledExecutorService,線程池的幾個(gè)核心配置:
corePoolSize:核心線程數(shù)量,如果線程池中的線程少于此數(shù)目,則在執(zhí)行任務(wù)時(shí)創(chuàng)建,核心線程不會(huì)被回收;
maximumPoolSize:允許的最大線程數(shù),當(dāng)線程數(shù)量達(dá)到corePoolSize且workQueue隊(duì)列滿了,會(huì)創(chuàng)建線程;
keepAliveTime:超過corePoolSize空閑時(shí)間;
unit:keepAliveTime的單位;
workQueue:當(dāng)線程超過corePoolSize,新的任務(wù)會(huì)被加入到隊(duì)列中等待;
threadFactory:創(chuàng)建線程的工廠類;
handler:線程池拒絕策略,包括:AbortPolicy,DiscardPolicy,DiscardOldestPolicy,CallerRunsPolicy策略,當(dāng)然也可以自己擴(kuò)展;
ScheduledExecutorService中添加的任務(wù)會(huì)被包裝成一個(gè)ScheduledFutureTask類,同時(shí)將任務(wù)放入DelayedWorkQueue隊(duì)列中是一個(gè)BlockingQueue;類似Timer也會(huì)根據(jù)加入任務(wù)觸發(fā)時(shí)間的先后進(jìn)行排序,然后線程池中的Worker會(huì)到Queue中獲取任務(wù)執(zhí)行;
Spring提供了xml和注解方式來配置調(diào)度任務(wù),如下面xml配置:
<!-- 創(chuàng)建一個(gè)調(diào)度器 --><task:scheduler id="scheduler" /><!-- 配置任務(wù)類的bean --><bean id="helloTask" class="com.spring.task.HelloTask"></bean><task:scheduled-tasks scheduler="scheduler"><!-- 每2秒執(zhí)行一次 --><task:scheduled ref="helloTask" method="say" cron="0/2 * * * * ?" /></task:scheduled-tasks>
Spring提供了cron表達(dá)式的支持,并且可以直接配置執(zhí)行指定類中的指定方法,對(duì)使用者來說更加方便和簡單;但是其內(nèi)部還是使用的ScheduledThreadPoolExecutor線程池;
Netty提供的一個(gè)定時(shí)器,用于定時(shí)發(fā)送心跳,使用的是時(shí)間輪算法;HashedWheelTimer是一個(gè)環(huán)形結(jié)構(gòu),可以類比成一個(gè)時(shí)鐘,整個(gè)環(huán)形結(jié)構(gòu)由一個(gè)個(gè)小格組成,每個(gè)小格可以存放很多任務(wù),隨著時(shí)間的流逝,指針轉(zhuǎn)動(dòng),然后執(zhí)行當(dāng)前指定格子中的任務(wù);任務(wù)通過取模的方式?jīng)Q定其應(yīng)該放在哪個(gè)格子,有點(diǎn)類似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);
其中初始化的三個(gè)參數(shù)分別是:
tickDuration:每一格的時(shí)長;
unit:tickDuration的單位;
ticksPerWheel:時(shí)間輪總共有多少格;
如上面實(shí)例配置的參數(shù),每一格時(shí)長1秒,時(shí)間輪總共16格,如果延遲1秒執(zhí)行,那就放到編號(hào)1的格子中,從0開始;如果延遲18秒,那么會(huì)放到編號(hào)為2的格子中,同時(shí)指定remainingRounds=1,表示第幾輪被調(diào)用,每轉(zhuǎn)一輪remainingRounds-1,知道remainingRounds=0才會(huì)被執(zhí)行;
以上介紹的幾種定時(shí)器都是進(jìn)程內(nèi)的調(diào)度,而Quartz提供了分布式調(diào)度,所有被調(diào)度的任務(wù)都可以存放到數(shù)據(jù)庫中,每個(gè)業(yè)務(wù)節(jié)點(diǎn)通過搶占式的方式去獲取需要執(zhí)行的任務(wù),其中一個(gè)節(jié)點(diǎn)出現(xiàn)問題并不影響任務(wù)的調(diào)度;
<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>
更多關(guān)于Quartz的介紹可以參考本人之前的文章:
Spring整合Quartz分布式調(diào)度
Quartz數(shù)據(jù)庫表分析
Quartz調(diào)度源碼分析
基于Netty+Zookeeper+Quartz調(diào)度分析
當(dāng)然Quartz本身也有不足的地方:底層調(diào)度依賴數(shù)據(jù)庫的悲觀鎖,誰先搶到誰調(diào)度,這樣會(huì)導(dǎo)致節(jié)點(diǎn)負(fù)載不均衡;還有調(diào)度和執(zhí)行耦合在一起,導(dǎo)致調(diào)度器會(huì)受到業(yè)務(wù)的影響;
正因?yàn)镼uartz存在著很多不足的地方,基于Quartz實(shí)現(xiàn)的分布式調(diào)度解決方案出現(xiàn)了包括Xxl-job/Elastic-job等;
整體思路:調(diào)度器和執(zhí)行器拆成不同的進(jìn)程,調(diào)度器還是依賴Quartz本身的調(diào)度方式,但是調(diào)度的并不是具體業(yè)務(wù)的QuartzJobBean,而是統(tǒng)一的一個(gè)RemoteQuartzJobBean,在此Bean中通過遠(yuǎn)程調(diào)用執(zhí)行器去執(zhí)行具體業(yè)務(wù)Bean;具體的執(zhí)行器在啟動(dòng)時(shí)注冊(cè)到注冊(cè)中心(如Zookeeper)中,調(diào)度器可以在注冊(cè)中心(如Zookeeper)獲取執(zhí)行器信息,并通過相關(guān)的負(fù)載算法指定具體的執(zhí)行器去執(zhí)行;
還提供了運(yùn)維管理界面,可以管理任務(wù),比如像xxl-job:
當(dāng)然還有更多其他的功能,此處就不在介紹了,可以直接去查看官網(wǎng);
其實(shí)整體可以分為兩大類:進(jìn)程內(nèi)定時(shí)器包括和分布式調(diào)度器;
進(jìn)程內(nèi)定時(shí)器:Timer,ScheduledExecutorService,Spring Scheduler,HashedWheelTimer(時(shí)間輪);
分布式調(diào)度器:Quartz,Xxl-job/Elastic-job;
所以首先根據(jù)需要僅僅只需要進(jìn)程內(nèi)的定時(shí)器,還是需要分布式調(diào)度;
其次在進(jìn)程內(nèi)Timer基本可以被淘汰了,完全可以使用ScheduledExecutorService來代替,如果系統(tǒng)使用了Spring那當(dāng)然應(yīng)該使用Spring Scheduler;
下面重點(diǎn)看看ScheduledExecutorService和HashedWheelTimer,ScheduledExecutorService內(nèi)部使用的是DelayedWorkQueue,任務(wù)的新增、刪除會(huì)導(dǎo)致性能下降;而HashedWheelTimer并不受任務(wù)數(shù)量限制,所以如果任務(wù)很多并且任務(wù)執(zhí)行時(shí)間很短比如心跳,那么HashedWheelTimer是最好的選擇;HashedWheelTimer是單線程的,如果任務(wù)不多并且執(zhí)行時(shí)間過長,影響精確度,而ScheduledExecutorService可以使用多線程這時(shí)候選擇ScheduledExecutorService更好;
最后分布式調(diào)度器里面Quartz和Xxl-job/Elastic-job,對(duì)分布式調(diào)度要求不高的情況下才會(huì)選擇Quartz,不然都應(yīng)該選擇Xxl-job/Elastic-job
感謝各位的閱讀!關(guān)于“大數(shù)據(jù)開發(fā)中定時(shí)器有哪些”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!
網(wǎng)站欄目:大數(shù)據(jù)開發(fā)中定時(shí)器有哪些
分享路徑:http://chinadenli.net/article34/ihccpe.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供靜態(tài)網(wǎng)站、企業(yè)網(wǎng)站制作、移動(dòng)網(wǎng)站建設(shè)、定制網(wǎng)站、標(biāo)簽優(yōu)化、外貿(mào)網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)