有限狀態機(英語:finite-state machine,縮寫:FSM)又稱有限狀態自動機,簡稱狀態機,是表示有限個狀態(State)以及在這些狀態之間的轉移(Transition)和動做(Action)等行爲的數學模型。git
狀態機有三個特徵:github
從有限狀態機的定義和特徵咱們能夠看到它的幾個重要概念:正則表達式
因爲有限狀態機的這些特徵,咱們能夠把狀態轉移的過程作成相似這樣的狀態轉移表。spring
條件\當前狀態 | 狀態A | 狀態B | 狀態C | 狀態D |
---|---|---|---|---|
條件X | 狀態B | 狀態C | 狀態D | ... |
條件Y | 狀態C | 狀態D | ... | ... |
條件Z | ... | 狀態A | 狀態A | 狀態A |
能夠概括爲一個公式。
Old State + Event = New State編程
把上面的狀態轉移表用公式表達就是
狀態A + 條件X = 狀態B
狀態A + 條件Y = 狀態C
...restful
咱們小時候都應該玩過貪吃蛇這個遊戲,遊戲規則沒必要再說,咱們看看使用有限狀態機來實現這個遊戲。網絡
狀態轉移表:微服務
條件\當前狀態 | GAME_OVER | UP | DOWN | LEFT | RIGHT |
---|---|---|---|---|---|
EAT | ... | UP | DOWN | LEFT | RIGHT |
HIT | ... | GAME_OVER | GAME_OVER | GAME_OVER | GAME_OVER |
TURN_UP | UP | ... | ... | UP | UP |
TURN_DOWN | DOWN | ... | ... | DOWN | DOWN |
TURN_LEFT | LEFT | LEFT | LEFT | ... | ... |
TURN_RIGHT | RIGHT | RIGHT | RIGHT | ... | ... |
EAT:吃掉食物
HIT:撞牆或本身
TURN_UP:向上轉向事件
...
GAME_OVER: 爲了簡便一點,咱們讓它既是開始又是結束的狀態,當按下上下左右任一鍵時開始遊戲。
UP: 向上前進狀態,此時能夠吃掉食物,也能夠撞到牆或本身,同時能夠向左向右轉向,但按下向上或向下是不會觸發任何動做。
...ui
當咱們把狀態轉移表定義好以後就會發現這個遊戲剩下的部分很是好寫,並且邏輯很是清楚,這就是有限狀態機的好處。編碼
筆者目前所在的部門是正在使用OpenStack作電子網絡靶場的一個項目,必然少不了對虛擬機各項指標的採集,所以對採集進行監控也是必要的措施,以便在採集故障以後及時預警。
整個監控流程是由客戶端(Java微服務)往Kafka中發一條採集配置,採集端(Python)收到這條配置後進行解析配置,而後進行指標採集,同時往Kafka回傳一些運行信息,當想要中止採集時須要客戶端再次下發一條關閉配置,採集端進行執行並回傳至Kafka關閉信息。
看似這個過程十分簡單,像把大象裝進冰箱同樣簡單。
使用有限狀態機來作其中的狀態轉移時真的就像是把大象塞進冰箱同樣簡單(其中使用restful接口接收客戶端的開始關閉配置,監聽kafka指定topic來處理採集端消息)。
條件\當前狀態 | Idle | processing | wait_close | exception | timeout | closed |
---|---|---|---|---|---|---|
start_conf | ||||||
error_conf | closed | |||||
pro_start | processing | |||||
heartbeat | processing | processing | ||||
error_runtime | exception | |||||
stop_conf | wait_close | wait_close | wait_close | |||
pro_stop | closed | closed | closed | |||
msg_timeout | timeout | timeout | timeout | timeout | ||
fix | closed |
事件
狀態
筆者這裏使用的庫是squirrel-foundation,支持多實例狀態機而且和spring進行整合也比較簡單。
有限狀態機能使咱們從複雜的狀態轉移判斷中脫離出來,專心業務邏輯,而且避免狀態轉移過程的判斷錯誤,是一種很強大的模型。