1. 程式人生 > >Azkaban新增簡訊報警功能

Azkaban新增簡訊報警功能

Azkaban本身具有郵件報警功能,但是郵件報警一般使用者不能及時響應處理。雖然使用者可以在作業中自行設計、使用簡訊報警功能,但是僅能對工作流中的一個作業執行內部過程監控,而不能監視工作流整體執行進度。為了使工作流的執行狀態更方便快捷地通知到使用者,特設計開發Azkaban的簡訊報警功能。

Azkaban的詳細介紹在前幾篇,想要新增簡訊報警功能,必須要對Azkaban的結構有所瞭解。簡單來講,Azkaban2.2由兩部分組成,一個是webserver,一個是executor,前者負責排程和顯示、後者負責執行,兩者依靠http介面通訊。已經掌握Azkaban使用方法的使用者都知道,可以在定義job檔案或者全域性配置檔案的時候,通過指定下面三種引數,可以給工作流中的每一個job分別設定

報警郵件接受者列表。

failure.emails Comma delimited list of emails to notify during a failure. *
success.emails Comma delimited list of emails to notify during a success. *
notify.emails Comma delimited list of emails to notify during either a success or failure. *

或者在web頁面手工一次執行或者設定排程執行之前通過Notification選項新增,可以將觸發條件配置成首次失敗或者整個工作流失敗的情況,一般來講,一個工作流首次失敗意味著工作流的某個節點失敗,對於依賴關係較強的工作流來說是應該立即處理的。

          
基於以上工作原理,我們希望設計一個與郵件報警配置類似的簡訊報警配置功能。通過Azkaban的程式碼可以看出,一個工作流被排程、被執行的大致過程是這樣的:

1、使用者打包上傳自己的專案檔案,被webserver解析出dag依賴關係,建立流程圖,同時專案檔案被插入mysql資料表中,並建立專案、工作流物件。

2、使用者點選執行前有時候會配置上圖中那些資訊,點選執行按鈕時,這些前段使用者配置資訊通過http介面傳送到webserver的servlet處理,webserver會將這些資訊進行處理,結合從使用者job檔案、配置檔案中設定的資訊做好準備交給執行器執行。

3、準備好的工作流會提交給執行器執行,執行器對工作流排隊,執行完畢的工作流會有一個執行結果處理的過程,郵件報警也是在那裡被執行的。

一種簡單地解決方案是,在郵件報警器上直接新增簡訊報警方法,即傳送簡訊報警必須傳送郵件報警,這種方式比較簡單,但是不符合面向物件程式設計的思想和原則;幸運地是Azkaban2.2提供了報警介面,郵件報警也實現了這個介面,並且還支援外掛方式,不得不說Azkaban2.2程式設計得實在人性,現在我們就開發一個簡訊報警器外掛。

1、外掛的開發

首先需要在webserver的conf目錄的azkaban.properties檔案中指定外掛目錄,當然我們可以不指定,直接使用預設的目錄,即plugins/alerter,跟其他外掛一樣,需要在裡邊建一個目錄,比如叫sms

sms中需要有conf  extlib  lib三個目錄。

我們在conf目錄中建立一個檔案叫做plugin.properties,我們新增引數alerter.name=sms,同時配置alerter.external.classpaths和alerter.class,這倆分別是咱們開發的編譯好的報警器的classpath和class檔案位置

相應的lib檔案放置使用到的外部jar包。

這樣的外掛就會被azkaban識別,稱為一個可用的報警器。報警器程式如何開發呢,我們可以參照Emailer,實現Alerter介面,主要實現四種方法即可。這裡不再多說,比較簡單,簡訊報警的方式我們還是採用公司的http介面,使用java呼叫shell指令碼實現。

public interface Alerter { void alertOnSuccess(ExecutableFlow exflow) throws Exception; void alertOnError(ExecutableFlow exflow, String ... extraReasons) throws Exception; void alertOnFirstError(ExecutableFlow exflow) throws Exception; void alertOnSla(SlaOption slaOption, String slaMessage) throws Exception;
}
public interface Alerter

{ void alertOnSuccess(ExecutableFlow exflow) throws Exception; void alertOnError(ExecutableFlow exflow, String ... extraReasons) throws Exception; void alertOnFirstError(ExecutableFlow exflow) throws Exception; void alertOnSla(SlaOption slaOption, String slaMessage) throws Exception; }

2、報警手機的配置

報警手機我們希望能從前段獲取,使用者可以在執行或者排程前自己在頁面配置,暫不提供job檔案配置方式,一是需要改動較多原始碼,二是也沒十分必要,排程或者手工執行前配置是比較好的方式。想要實現這個功能,必須要搞清楚前後端資料投遞方式,和頁面繪製方法。

從java程式碼的servlet方法看,Azkaban2.2使用了Velocity模板引擎,所謂模板實際上是相對於傳統的開發方式來說的,普通的jsp或者servlet開發方式原理都是往頁面列印頁面標籤和一些動態資料,這種方式有個缺點是不易維護,更改起來不方便,但是有個優點是後臺執行起來之後,jsp更改不需要重啟服務。這裡不深入比較兩者,只為說明Velocity的工作原理,Velocity的模板檔案以.vm結尾,隨java程式碼一起編譯,模板中規劃好了頁面佈局,引入了javascript指令碼作為與後臺的互動,因此新增報警手機介面需要更改vm檔案,往後臺傳遞手機號碼需要更改js檔案。

ok,我們抓一下頁面,看看那個面板叫什麼名字,execute-flow-panel,對應的模板是azkaban.webapp.servlet.velocity包下的flowexecutionpanel.vm,

Velocity模板整體結構還是html結構,我們按照郵件列表介面模仿新增手機列表,同時設定id,

現在介面有了,下一就應該考慮怎麼把咱們輸入的手機號傳遞給後臺,比較快的方式是把它關聯的js挨個看一下,最後發現在azkaban.flow.execute.view.js裡 
我們繼續看這個js,並且模仿新增手機列表,下圖可以看出,我們點執行對應的是handleExecuteFlow方法 

這裡採用的ajax往後臺打資料,看看都傳了哪些資料, 
我們模仿郵件功能,把手機列表也抓進來投遞過去,通過handleExecuteFlow我們看到這個請求是由ExecutorServlet負責處理的。

最終我們可以定位到ajaxExecuteFlow方法,Azkaban使用ExecutionOptions物件將所有的配置資訊儲存,並且在執行結果報警時從中拿出來進行相應的處理,所以我們在parseFlowOptions方法中,將手機號碼解析出來,同時更改一下ExecutionOptions物件,新增相應的成員變數即可,到這裡前端的資料就成功被新增到後臺了。

前端介面變成了這樣子:

使用:
報警格式:
[Azkaban]["azkabanName"][ERROR][ExecutionId:"flow.getExecutionId()"][FlowId:"flow.getFlowId()"]
以[Azkaban]開頭,提醒使用者這是來自azkaban的簡訊,第二個欄位是為了區分將來有可能出現的不同的azkaban的系統,第三個欄位可以是ERROR或者SUCCESS,代表成功或者失敗,之後跟上執行id和工作流id,方便使用者追查日誌,查詢失敗原因。