quartz mysql索引_分布式系统中的定时任务全解(二)
在實際項目中,通常需要用到定時任務(定時作業(yè)),spring框架提供了很好的實現(xiàn)。 1、? 下載spring-quartz插件包 這里默認當前系統(tǒng)中是集成了spring框架的基本功能的。去網(wǎng)上下載spring定時器的jar包,這里用的是quartz-all-1.8.4.jar,下載完成之后添加的項
概述
上一篇分布式系統(tǒng)中的定時任務全解(一)中對定時任務和定時任務的基礎使用方式進行了說明。這一小節(jié),把分布式場景下的定時任務進行一個大致的講解。
什么是分布式場景呢,當單臺服務器服務能力不夠的時候,就需要更多的服務器進行水平向的擴展,由多臺服務器分工(任務量上的水平劃分,而非業(yè)務線上的垂直劃分)的方式來增強服務能力,提供更強的并發(fā)請求處理,更短的時間響應。
像第一節(jié)說到的定時任務使用場景,大多是一次任務執(zhí)行僅能有一個服務器在執(zhí)行,如果是所有服務器都在執(zhí)行相同的任務,一個是會造成錯誤,就算不會造成錯誤,很多服務器在做重復的工作也是極大的浪費。
所以,分布式場景下定時任務要做的一個基本難點就是:怎么讓某一個定時任務,在一個觸發(fā)時點上僅有一臺服務器在執(zhí)行。
更進一步,如果,你的定時任務涉及到很多同類型的數(shù)據(jù)要處理,比如說要處理100個輸入文件,處理方式相同;再比如說你的數(shù)據(jù)庫已經(jīng)做了分庫處理,業(yè)務數(shù)據(jù)被寫入到了10個數(shù)據(jù)庫實例中,處理方式相同。那么此時,可以讓更多臺服務器執(zhí)行定時任務,每臺執(zhí)行其中的一部分,比如10個輸入文件;再比如1個數(shù)據(jù)庫實例中的業(yè)務數(shù)據(jù)。
以上兩種場景怎么辦呢?第一種很簡單,后續(xù)會提供三種方式去做:1.設置某一臺為任務執(zhí)行服務器,其他服務器不執(zhí)行;2.使用quartz的集群功能,實現(xiàn)某一臺執(zhí)行;3.使用當當開源的elastic-job,實現(xiàn)某一臺執(zhí)行。第二種場景只有第一種場景中的第3中方式可以做到。
接下來逐個看一下。
實現(xiàn)分布式的方式
設置某一臺為任務執(zhí)行服務器
這種方式可以采用環(huán)境變量的方式來實現(xiàn),定時任務運行時檢查本機的環(huán)境變量值是否為可執(zhí)行,如果是則執(zhí)行定時任務,如果不是則直接返回。
@Value("${ISTIMERRUNNER}")
private String isTimerRunner;
@Scheduled(cron="0 0 0 * * ? ")
public void task(){
try {
if("true".equals(isTimerRunner)){
//do something.....
}
} catch (Exception e) {
e.printStackTrace();
}
}
這里有一個需要注意的事項,如果集群環(huán)境下,你使用了腳本部署的方式,而且是類似于作者的方式。也就是先把文件拷貝到一臺服務器,啟動好后,調(diào)用腳本(腳本參見:http://blog.csdn.net/buqutianya/article/details/51062384),逐個部署到其他服務器。那么,你就需要注意一下了。
遠程ssh調(diào)用startup.sh時,tomcat取不到環(huán)境變量,這里需要把startup.sh的頂部進行修改:
#!/bin/sh --login
當然這里還有另外一種方式,就是在tomcat的bin目錄中添加一個setenv.sh文件,startup.sh執(zhí)行時會加載其中的內(nèi)容。
export ISTIMERRUNNER=true
這種方式有十分明顯的缺陷:1.單點,當任務執(zhí)行節(jié)點出現(xiàn)問題時,整個定時任務全部over;2.資源分配不均衡,隨著定時任務的增多,任務執(zhí)行服務器的資源占用壓力會越來越大。
當然了,這是在技術能力不夠的時候,最簡單有效的實現(xiàn)方式。
使用quartz的集群功能
quartz這個老牌的定時任務執(zhí)行工具,在集群方面也提供了很好的支持。quartz的集群是借助數(shù)據(jù)庫來實現(xiàn)的,所有的服務器實例共享一套數(shù)據(jù)庫表中存儲的任務、觸發(fā)器和調(diào)度器信息,實現(xiàn)一個時間點,同一個任務僅有一臺服務器在執(zhí)行。而且提供了負載均衡和failover失敗轉(zhuǎn)移功能。
quartz的負載均衡大概是這樣的策略:對于需要調(diào)度很多任務的調(diào)度器,會近似隨機的選擇服務器執(zhí)行;對于調(diào)度的任務數(shù)比較少的(1個或者2個)的觸發(fā)器,會盡量的在同一臺服務器上執(zhí)行。(可以參見這里:http://www.quartz-scheduler.org/documentation/quartz-2.2.x/tutorials/tutorial-lesson-11.html)一、Quartz的特點 按作業(yè)類的繼承方式來分,主要有以下兩種: 作業(yè)類繼承org.springframework.scheduling.quartz.QuartzJobBean類的方式作業(yè)類不繼承org.springframework.scheduling.quartz.QuartzJobBean類的方式 注:個人比較推崇第二種,因為這種方式下的
quartz的集群使用也不復雜,接下來一起看一下:
1.導入數(shù)據(jù)庫表
quartz的集群是基于數(shù)據(jù)庫實現(xiàn)的,所以首先要把數(shù)據(jù)庫表結構創(chuàng)建好。創(chuàng)建腳本在quartz的完整下載包里可以找到(官網(wǎng)下載地址:http://www.quartz-scheduler.org/downloads/)。
解壓之后,在docs/dbTable目錄下可以找到你想要的所有常見數(shù)據(jù)庫類型的創(chuàng)建腳本。
我使用的是sql數(shù)據(jù)庫,所以使用了tables_mysql_innodb.sql。
這里導入的時候遇到了一個問題,就是創(chuàng)建索引時索引字段過長。這里我采用的方法是把所有的scheduler的長度變成了50,修改之后也就是會限制所有的scheduler的名字在50個字節(jié)以內(nèi)。
2.創(chuàng)建支持集群的scheduler
集群和非集群的配置不同,關鍵就在于scheduler,集群時需要給scheduler配置數(shù)據(jù)源、將org.quartz.jobStore.isClustered設置為true、以及配置quartz.properties屬性文件。詳細的實現(xiàn)方式可以參見:http://sundoctor.iteye.com/blog/486055
使用elastic-job
elastic-job是基于quartz實現(xiàn)的,最大的不同點是elastic-job把做為共享中心的數(shù)據(jù)庫換成了zookeeper。所以要使用elastic-job首先要安裝zookeeper。
安裝好zookeeper之后,使用elastic-job也不難,它做了很好的spring集成支持,只需要配置注冊中心和執(zhí)行任務的job即可。
以下是一個配置文件的示例:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:reg="http://www.dangdang.com/schema/ddframe/reg"
xmlns:job="http://www.dangdang.com/schema/ddframe/job"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.dangdang.com/schema/ddframe/reg http://www.dangdang.com/schema/ddframe/reg/reg.xsd http://www.dangdang.com/schema/ddframe/job http://www.dangdang.com/schema/ddframe/job/job.xsd ">
這里簡單的說一下elastic-job相對于quartz的優(yōu)勢:
1.使用zookeeper做為協(xié)調(diào),更加輕量級,這一點對于使用者來說也是一個困難項,因為無論再小的服務也有一個數(shù)據(jù)庫,所以定時任務也使用數(shù)據(jù)庫,那么用起來省事一點。但使用zookeeper一方面速度快,另一方面是不占用現(xiàn)有數(shù)據(jù)庫的連接和計算資源。
2.支持任務的分片,quartz同一時點,同一任務只能在一臺機器上運行,但是elastic-job可以在多臺機器上運行,并且能夠指定每臺服務器上運行的輸入分片。比如業(yè)務數(shù)據(jù)在10個數(shù)據(jù)庫,這里總共有5臺服務器,那么每臺服務器在同一個時點,僅處理其中的2個數(shù)據(jù)庫。做到將可縱向切分的任務,切分給不同的服務器,充分利用資源,加快計算速度。
elastic-job怎么做到的分片,在不同的場景下我們該怎么使用elastic-job,接下來的一節(jié)將從源代碼的角度進行講解。
總結
以上是生活随笔為你收集整理的quartz mysql索引_分布式系统中的定时任务全解(二)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: 特斯拉大规模裁员:数百名自动辅助驾驶系统
 - 下一篇: java生日正则表达式_java之正则表