2. 狀態機簡介
3. 運單環節狀態機實現
4. 整體架構
業務方希望能夠對運單的攬收、干支運輸、派送等各個環節的操作規範進行監控,同時將溫濕監控、裝置監控、配置監控等孤立的報警項對映到運單環節之上。
運單環節由運單狀態對映而得,譬如干支運輸環節的典型狀態區間是封車–>解封車。
運單環節對映最大的難點在於,無論是在系統上還是運營上,運單的各個關鍵狀態都不是嚴格齊全的、有序的,存在大量的漏操作、補操作,很難甚至無法進行完全正確的環節對映——乙個環節可能永遠不會有對應的終止狀態產生。此時,系統上要盡快識別這種異常,做到今早結束。
此外,幾百種運單狀態前期難以梳理清楚,業務也在不斷的變化,這些都使得環節的對映關係隨時可能變更。
以上種種要求系統在設計上要能夠適應複雜、多變的條件判斷,傳統編碼方式會存在大量的if-else判斷,場景考慮不全、後期維護困難。
方案設計毫無眉目之時,翻看設計模式之美這本書,想從中找找靈感,萬萬沒想到居然淘到了寶——狀態機。
詳見:有限狀態機
有限狀態機(finite state machine,fsm)簡稱狀態機。狀態機有三個組成部分:狀態(state)、事件(event)、動作(action),事件**移條件)觸發狀態的轉移和動作的執行。動作的執行不是必須的,可以只轉移狀態,不指定任何動作。總體而言,狀態機是一種用以表示有限個狀態以及這些狀態之間的轉移和動作的執行等行為的數學模型。
狀態機可以用公式 state(s) x event(e) -> actions (a), state(s』)表示,即在處於狀態s的情況下,接收到了事件e,使得狀態轉移到了s』,同時伴隨著動作a的執行。
在遊戲「超級馬里奧」中,馬里奧的形態轉變就是乙個狀態機。馬里奧有小馬里奧、超級馬里奧、火焰馬里奧、斗篷馬里奧等形態,在遇到不同的遊戲情節時,會發生形態改變,同時產生積分的增減。比如小馬里奧吃了蘑菇之後會變成超級馬里奧,同時增加100積分。
在超級馬里奧中,馬里奧的不同形態就是狀態機中的「狀態」,遊戲情節就是狀態機中的「事件」,加減積分就是狀態——機中的「動作」。
其中,事件e1~e4分別表示吃蘑菇、獲得斗篷、獲得火焰、遇到怪物。
狀態
梳理出需要監控的運單環節:攬收環節、干支運輸環節、配送環節,由此派生出8個狀態:初始狀態、攬收開始/結束狀態、干支開始/結束狀態、派送開始/結束狀態、結束狀態。
事件、動作及狀態轉移
將運單狀態作為事件輸入到狀態機中,由此觸發運單環節的流轉,並執行相應的動作——建立新的環節、結束當前環節、結束當前並建立下乙個環節。環節的初始化和結束計算任務比較重量,採用了非同步任務進行計算。
環節狀態機的整體流轉從攬收到干支、派送,最後到結束狀態,處於結束狀態的狀態機不會在響應任何輸入事件。如圖所示,在攬收開始的狀態下,接收到卸車事件,那麼狀態機的狀態將會轉變到攬收結束狀態,同時執行結束環節計算任務。此外,由於干支運輸和派送環節在實際中可能存在多個,所以干支開始/結束、派送開始/結束這一對狀態可以互相轉換。
具體實現——查表法
在**實現上,狀態機常見的三種實現方式——分支邏輯法、查表法、狀態模式法,查表法比較適應當前場景:狀態、事件型別很多、狀態轉移比較複雜,利用二維陣列表示狀態轉移圖,能極大的提高**的可讀性和可維護性。當把陣列存在配置檔案中,在狀態機變更時甚至不需要修改**。
此外,由於只有在狀態機狀態發生改變時,才需要執行動作。對action_table進行了優化,縱座標由事件變化為下乙個狀態,即由當前狀態和轉移後的狀態決定執行的事件型別。
/**
* 狀態轉移矩陣,橫座標表示當前狀態,縱座標表示接收到的運單狀態變化事件,值為新狀態。
*/private
static
final waybillmajorstateenum[
] transition_table =,,
,,,,
,,};
/** * 只有在狀態發生轉移時,才有操作需要執行,故橫座標表示原狀態,縱座標表示轉移後的狀態。
*/private
static
final
int[
] action_table =
,// init_state
,// ls_start
,// ls_end
,// gz_start
,// gz_end
,// ps_start
,// ps_end
,// end_state
};
整體架構上主要分為兩層:單據狀態層和任務計算層。
單據狀態層從mq接收運單狀態變化訊息,以批次為單位進行處理狀態變化並生成環節:
從redis批量獲取快取並初始化狀態機
輸入運單變化事件產生狀態轉移、封裝待執行動作為非同步任務
資料批量落庫es、狀態機狀態批量更新回寫redis
傳送非同步批量任務
任務計算層執行上層下發的環節初始化和終止任務,計算相關的指標。
verilog 狀態機設計
一,狀態機的基本概念 硬體設計講究並行設計的思想,雖然用verilog描述的電路大都是並行實現的,但是對於實際的工程應用,往往需要讓硬體來實現一些具有一定順序的工作,這就要用到狀態機的思想,什麼是狀態機呢?簡單的說,就是通過不同的狀態遷移來完成一些特定的順序邏輯,硬體的並行性決定了用verilog描...
FPGA狀態機設計
一 狀態機應用設計 一 狀態機基本概念 1.狀態機的描述方法 狀態機描述時關鍵是要描述清楚幾個狀態機的要素,即如何進行狀態轉移,每個狀態的輸出是什麼,狀態轉移的條件等。具體描述時方法各種各樣,最常見的有三種描述方式 1 一段式 整個狀態機寫到乙個always模組裡面,在該模組中既描述狀態轉移,又描述...
基於proteus的狀態機設計
參考資料 理論上說,任何乙個需要周而復始的執行一系列任務 例如cpu中按順序從儲存器取出指令 再執行指令 的時序系統都可以用狀態機 state machine 模型來描述。時序系統的執行週期可以描述為乙個預定順序的時間週期序列,每個週期都對應狀態機中乙個指定的狀態。狀態機在每個週期中產生特定的操作,...