tbschedule源碼解讀

tbschedule源碼解讀

tbschedule部署包括兩部分是越,一個是負責(zé)配置管理的后臺程序,一個是客戶端接入包倚评,這兩個程序依賴zk進行信息交互。

zk數(shù)據(jù)的大致結(jié)構(gòu)

factory部分

/app1/factory
/app1/factory/facotoryUUID1
/app1/strategy
/app1/strategy/strategy1
/app1/strategy/strategy1/factoryUUID1

可以有多個facotory盔性,每個factory對應(yīng)一個客戶端啟動的TBScheduleManagerFactory實例呢岗,每個JVM可以有多個factory實例,factory實例也可以存在于不同的JVM中悉尾。
strategy是在后臺配置的任務(wù)策略挫酿,每個factory啟動時候回去檢查自己能處理哪幾個strategy,如果能處理則在/app1/strategy/strategy1/路徑下注冊自己早龟,注冊的這個信息在tbschedule源碼里叫做FactoryRunningInfo

ScheduleServer部分

/app1/baseTaskType
/app1/baseTaskType/task1
/app1/baseTaskType/task1/task1
/app1/baseTaskType/task1/task1/server
/app1/baseTaskType/task1/task1/server/scheduleServerUUID1
/app1/baseTaskType/task1/task1/taskItem
/app1/baseTaskType/task1/task1/taskItem/taskItem1
/app1/baseTaskType/task1/task1/taskItem/taskItem1/cur_server
/app1/baseTaskType/task1/task1/taskItem/taskItem1/deal_desc
/app1/baseTaskType/task1/task1/taskItem/taskItem1/parameter
/app1/baseTaskType/task1/task1/taskItem/taskItem1/req_server
/app1/baseTaskType/task1/task1/taskItem/taskItem1/sts

task1是在后臺配置的任務(wù)壹店。
/app1/baseTaskType/task1/task1/server/scheduleServerUUID1表示可以用來處理任務(wù)的調(diào)度器芝加,每個factory實例可以有多個ScheduleServer實例。
/app1/baseTaskType/task1/task1/taskItem表示配置任務(wù)時老赤,每個任務(wù)可以拆分成幾個小的任務(wù)項制市。該節(jié)點的子節(jié)點,表示這個任務(wù)項運行時的信息开财,例如cur_server表示這個taskItem正在被哪個ScheduleServer處理误褪。這些在tbschedule源碼里也叫作runningInfo。

核心類圖


TBScheduleManagerFactoryfactory實例對象历葛,管理這個factory內(nèi)部所有的事情嘀略。
ZKManager負責(zé)與zk之間的連接,數(shù)據(jù)交換帜羊。
IScheduleDataManager負責(zé)/app1/baseTaskType及其子節(jié)點所有數(shù)據(jù)模型維護讼育。
ScheduleDataManger4ZK負責(zé)/app1/factory``/app1/strategy及其字節(jié)點數(shù)據(jù)模型維護。
IStrategyTask每個實例代表一個線程組奶段,每個strategy可對應(yīng)多個IStrategyTask實例,來真正處理配置的任務(wù)扛伍。

關(guān)于這幾個類的組合關(guān)系如下圖:


一個Factory處理多個strategy词裤,每個strategy下有多個IStrategyTask對象。
TBScheduleManager實現(xiàn)IStrategyTask接口逆航,一個TBScheduleManager實例跟ScheduleServer渔肩、ScheduleProcessorIScheduleTaskDeal的關(guān)系都是一比一的關(guān)系。ScheduleServer是針對某一個task的的調(diào)度器撑帖。IScheduleTaskDeal是我們自己代碼里需要實現(xiàn)的任務(wù)對象澳眷。ScheduleProcessor是處理任務(wù)的多線程任務(wù)處理器,代表一個線程組衷敌⊥氐桑可以包含多個線程,線程的最大數(shù)量取決于后臺配置的task身上的threadNum字段面氓。
一個Factory有多個IStrategyTask的原因是沟堡,任務(wù)需要分片處理,每個分片對應(yīng)一個IStrategyTask實例航罗。
一個ScheduleProcessor有多個Thread的原因是,一個任務(wù)分片下一次可以取出多個任務(wù)柏锄,開啟多線程可以并發(fā)處理這些任務(wù)复亏。

初始化流程


整個初始化過程大量使用Thread缔御、Timer,很多工作都是異步進行的耕突,且這些線程之間通過了狀態(tài)對象、鎖等方式進行了協(xié)調(diào)炕泳。
整個初始化過程粗略來看包括以下幾步:

  1. 創(chuàng)建ZKManager對象
  2. 啟動初始化線程InitalThread上祈,然后立即返回
    接著便是InitalThread異步做的初始化工作:
  3. 準(zhǔn)備好ZKManager浙芙、ScheduleDataManager4ZK籽腕、ScheduleStrategyDataManager4ZK對象
  4. 啟動定時Timer對象ManagerFactoryTimerTask
    接著便是ManagerFactoryTimerTask定時執(zhí)行的工作,主要是去掃描strategy配置晤锥,重新分配factory去處理這些strategy廊宪。分配完factory女轿,會創(chuàng)建StrategyTask進行任務(wù)的處理。

factory刷新工作詳解

整個過程源碼入口在ManagerFactoryTimerTask#run()中傅寡,而主要的邏輯集中在TBScheduleManagerFactory#refresh()北救。這里不去關(guān)心stop factory的逆向流程,只來看正向流程托启,見TBScheduleManagerFactory #reRegisterManagerFactory攘宙。

  1. 遍歷strategy,重新計算factory實例跟strategy的匹配關(guān)系
  2. 找到當(dāng)前factory實例不能處理的strategy蹭劈,并停止掉正在運行的StrategyTask
  3. 遍歷跟當(dāng)前factory實例相關(guān)的strategy铺韧,選舉出每個strategy的leader factory實例,由leader重新計算每個factory實例能夠分到的reqNum哈打,即根據(jù)strategy身上的assignNum``numOfSingleServer,將assignNum平分給每個factory實例患雏。
  4. 調(diào)整當(dāng)前factory實例分配到每個strategy的的StrategyTask的數(shù)量罢维,確保數(shù)量等于上一步分配給自己的數(shù)量丙挽。

factory線程組數(shù)量分配算法

ScheduleUtil#assignTaskNumber

/**
   * 分配任務(wù)數(shù)量
   * @param serverNum 總的服務(wù)器數(shù)量
   * @param taskItemNum 任務(wù)項數(shù)量
   * @param maxNumOfOneServer 每個server最大任務(wù)項數(shù)目
   * @return
   */
  public static int[] assignTaskNumber(int serverNum,int taskItemNum,int maxNumOfOneServer){
    int[] taskNums = new int[serverNum];
    int numOfSingle = taskItemNum / serverNum;
    int otherNum = taskItemNum % serverNum;
    //20150323 刪除, 任務(wù)分片保證分配到所有的線程組數(shù)上颜阐。 開始
//    if (maxNumOfOneServer >0 && numOfSingle >= maxNumOfOneServer) {
//      numOfSingle = maxNumOfOneServer;
//      otherNum = 0;
//    }
    //20150323 刪除, 任務(wù)分片保證分配到所有的線程組數(shù)上吓肋。 結(jié)束
    for (int i = 0; i < taskNums.length; i++) {
      if (i < otherNum) {
        taskNums[i] = numOfSingle + 1;
      } else {
        taskNums[i] = numOfSingle;
      }
    }
    return taskNums;
  }

TBScheduleManagerStatic的初始化流程

  1. 找到task配置的用戶實現(xiàn)的IScheduleTaskDeal對象
  2. 將當(dāng)前ScheduleServer實例注冊到/app1/baseTaskType/task1/task1/server/scheduleServerUUID1位置
  3. 啟動心跳TimerHearBeatTimerTask
  4. 啟動初始化線程

心跳Timer

這里主要做的事情就是重新將taskItem分配到每個SchedueServer是鬼,源碼位置在TBScheduleManagerStatic#assignScheduleTask()。首先選舉出當(dāng)前ScheduleServer對應(yīng)的task對應(yīng)的所有ScheduleServer實例均蜜,選舉出一個leader囤耳,由leader進行分配工作。

  1. 等到初始化線程完成initialRunningInfo的工作
  2. clearTaskItem充择,遍歷所有taskItem,查看對應(yīng)的cur_server是否還能找到宰僧,找不到則將cur_server置為null
  3. assignTaskItem铃剔,給每個taskItem分配合適的ScheduleServer實例。

初始化線程

  1. initialRunningInfo凤类,由當(dāng)前task的leader ScheduleServer實例初始化這個task下所有的taskItem子節(jié)點的數(shù)據(jù)普气,此時還沒有分配每個taskItem由哪個ScheduleServer實例執(zhí)行(見心跳Timer)
  2. getCurrentScheduleTaskItemListNow,重新加載當(dāng)前ScheduleServer能處理的taskItem項目
  3. computerStart现诀,創(chuàng)建兩個Timer,一個用來計算任務(wù)下次執(zhí)行開始時間坐桩,一個用來計算任務(wù)下次終止執(zhí)行時間封锉。停止跟恢復(fù)通過TBScheduleManager身上的isPauseSchedule字段來標(biāo)識膘螟。
  4. 恢復(fù)的時候去創(chuàng)建TBScheduleProcessorSleep``TBScheduleProcessorNotSleep對象碾局;停止的時候净当,會將已經(jīng)在執(zhí)行的任務(wù)處理完余爆,但是緩存在隊列中待執(zhí)行的任務(wù)將被丟棄尖阔。

TBScheduleProcessorSleep多線程工作原理

啟動task配置的threadNum數(shù)量的線程去處理任務(wù)庶诡。由其中某一個線程去獲取任務(wù)全陨,將入taskList隊列中甚颂,所有的線程從這個隊列中獲取任務(wù)執(zhí)行秀菱,如果是Multi任務(wù)衍菱,可以一次取多個任務(wù)執(zhí)行。在一個線程獲取任務(wù)的過程中脊串,其他線程處于休眠狀態(tài),任務(wù)獲取完畢喚醒其他線程放闺。獲取任務(wù)代碼在TBScheduleProcessorSleep#loadScheduleData缕坎,每次獲取都是調(diào)用一次IScheduleTaskDeal對象selectTasks方法獲取一批任務(wù)放到taskList中。
兩次loadScheduleData有一個休眠時間匾寝,即在task上配置的SleepTimeInterval荷腊。
一旦TBScheduleProcessorSleep啟動了,會一直循環(huán)執(zhí)行女仰,知道PauseTimer讓其停止,如果你沒有配置結(jié)束時間码倦,則不會停止,而是一直運行勿璃;也可以通過后臺配置將任務(wù)停止推汽。

總結(jié)

tbschdule通過任務(wù)分片,將一個任務(wù)分配給多個線程組(即ScheduleServer實例)執(zhí)行莲组,這些線程組可以分布在相同或者不同的JVM上暖夭。而每個線程組支持多線程處理某一個分片的任務(wù)。
tbschedule同時支持失效任務(wù)轉(zhuǎn)移功能迈着,并且可以通過管理后臺對任務(wù)進行調(diào)度管理裕菠。
不過官方文檔實在太少。

參考:
tbschedule
關(guān)于TbSchedule任務(wù)調(diào)度管理框架的整合部署


進入博主個人站點奴潘,閱讀更多文章

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末画髓,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子杖小,更是在濱河造成了極大的恐慌愚墓,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,204評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件扫腺,死亡現(xiàn)場離奇詭異村象,居然都是意外死亡攒至,警方通過查閱死者的電腦和手機躁劣,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,091評論 3 395
  • 文/潘曉璐 我一進店門账忘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人鳖擒,你說我怎么就攤上這事〈粱” “怎么了期升?”我有些...
    開封第一講書人閱讀 164,548評論 0 354
  • 文/不壞的土叔 我叫張陵播赁,是天一觀的道長。 經(jīng)常有香客問我行拢,道長诞吱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,657評論 1 293
  • 正文 為了忘掉前任沼瘫,我火速辦了婚禮咙俩,結(jié)果婚禮上阿趁,老公的妹妹穿的比我還像新娘。我一直安慰自己脖阵,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,689評論 6 392
  • 文/花漫 我一把揭開白布呜呐。 她就那樣靜靜地躺著,像睡著了一般洋机。 火紅的嫁衣襯著肌膚如雪洋魂。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,554評論 1 305
  • 那天刁标,我揣著相機與錄音址晕,去河邊找鬼。 笑死启搂,一個胖子當(dāng)著我的面吹牛刘陶,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播匙隔,決...
    沈念sama閱讀 40,302評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼纷责,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了挺勿?” 一聲冷哼從身側(cè)響起喂柒,我...
    開封第一講書人閱讀 39,216評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蚊丐,沒想到半個月后艳吠,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,661評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡泥兰,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,851評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了膀捷。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片削彬。...
    茶點故事閱讀 39,977評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡融痛,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出雁刷,到底是詐尸還是另有隱情,我是刑警寧澤责语,帶...
    沈念sama閱讀 35,697評論 5 347
  • 正文 年R本政府宣布目派,位于F島的核電站,受9級特大地震影響白筹,放射性物質(zhì)發(fā)生泄漏谅摄。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,306評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望它呀。 院中可真熱鬧纵穿,春花似錦、人聲如沸谓媒。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,898評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至各墨,卻和暖如春启涯,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背结洼。 一陣腳步聲響...
    開封第一講書人閱讀 33,019評論 1 270
  • 我被黑心中介騙來泰國打工松忍, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人挽铁。 一個月前我還...
    沈念sama閱讀 48,138評論 3 370
  • 正文 我出身青樓叽掘,卻偏偏與公主長得像,于是被迫代替她去往敵國和親更扁。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,927評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 一溃列、前言 上一篇文章iOS多線程淺匯-原理篇中整理了一些有關(guān)多線程的基本概念膛薛。本篇博文介紹的是iOS中常用的幾個多...
    nuclear閱讀 2,050評論 6 18
  • 不足的地方請大家多多指正哄啄,如有其它沒有想到的常問面試題請大家多多評論,一起成長咨跌,感謝!~ String可以被繼承嗎...
    啟示錄是真的閱讀 2,937評論 3 3
  • 一 基礎(chǔ)篇 1.1 Java基礎(chǔ) 面向?qū)ο蟮奶卣鞒橄?將一類對象的共同特征總結(jié)出來構(gòu)建類的過程锌半。繼承:對已有類的一...
    essential_note閱讀 695評論 0 0
  • 25號回家,這一周很平穩(wěn)殉摔,參加了賣車,扮老虎钦勘,打吃雞游戲,情緒很好腐缤!自己買藥肛响。看到這樣我很開心特笋。
    荷塘魚閱讀 129評論 0 0
  • 為人耳熟能詳?shù)氖荢FBT各種具代表性的焦點解決問題蔫磨,包括成果問句、奇跡問句堤如、假設(shè)問句、例外問句蝗岖、差異問句榔至、應(yīng)對問句...
    風(fēng)清霜潔閱讀 127評論 0 2