在「鬆耦合的關鍵」一文中,我提到了鬆耦合的關鍵是訊息(message)。現在我要更清楚地說:鬆耦合的真正關鍵是「事件」。

我把訊息分為兩大類:命令(Command)和事件(Event)。當一個模組要通知其他模組「去做某件事」,送出去的訊息就是命令,例如「請讓用戶登錄」;當一個模組要通知其他模組「某個事實已經發生了」,送出去的訊息就是事件,例如「用戶已經登錄了」。這裡的重點在於:命令是「希望發生,但還沒有發生」的,事件是「已經發生」的。

關於命令和事件還有另一個重點:對於命令的發送者來說,命令的接收對象很明確,是某一個模組;而對於事件的發送者來說,事件的接收對象不明確,可以沒有,也可以一個或很多個。模組如果想接收某類事件,只要符合權限,就可以去登記要在某類事件發生時接到通知。本文章一開始提到鬆耦合的真正關鍵是事件,原因就是在於:事件的產生者不需要知道事件的接收者是誰。

命令的接收者直接執行命令,但事件的接收者不一定直接做出反應。有些事件的接收者,接收事件只是為了觀察某些「大事」的「端倪」,在累積許多端倪之後,才認定「大事」發生了,這時候才做出反應。一件「大事」是由許多小事和其他大事累積起來而形成的。大事的專業術語是「複雜事件」(Complex Event),小事的專業術語是「簡單事件」(Simple Event)。把簡單事件累積成複雜事件,再去做處理,這個機制叫做「複雜事件處理」(CEP)。

在過往的年代,CEP主要是用在核心系統或業務系統的「旁邊」,主要目的是風險控制、商業機會挖掘。這時候通常是採用中央集權式的CEP系統,也就是說,事件會從許多系統匯集過來,在一個集中點做判斷是否複雜事件發生了。有些CEP系統允許產生的複雜事件回流,成為其他複雜事件的端倪;有些CEP系統不允許這麼做,因為怕出現意外的循環。上一次的文章「技術架構設計12原則(下)」說過了:循環依賴不好。

早期的這些CEP系統通常是建構在關聯型資料庫管理系統(RDBMS)之上的,利用RDBMS的觸發器(trigger)機制,來達到複雜事件的判斷。事件先進入資料庫的表,掃描是否符合某些模式(pattern),來判斷是否發生複雜事件。有些掃描的時機是發生在每個事件來到時(耗費計算能力),有些掃描的時機是發生在事件累積了一個批次的時候(節省計算能力)。所以大多數描述複雜事件的語言,都長得很像資料庫的語言。但還是有廠商設計出抽象程度更高的語言,接近通用的程式語言。

除了我們自己描述複雜事件是如何構成的,也可以用AI來做這件事。每個簡單事件攜帶的資訊量不多,但簡單事件的數量非常龐大(尤其是物聯網),非常適合拿來做AI。

上述的傳統CEP,獨立於業務系統之外,但可能會回過頭去影響業務系統。例如:CEP發現洗錢的跡象,發命令給帳戶系統去凍結帳戶。我們在鬆耦合的微服務設計中,大量使用事件,但這是業務系統本身,不能算是CEP系統。CEP的重點不在於處理業務,而是在於把各種簡單事件合併起來得到複雜事件,透過複雜事件的出現,發現某個危機、機會、趨勢,並據以做出反應。

對於在分散式網路邊陲的系統來說,單一個簡單事件往往無足輕重,需要複雜事件才值得中央伺服器注意。隨著許多終端設備(包括各種感應器)也紛紛聯網,現在CEP又出現了新的應用價值:在邊緣計算上。試想,這些瑣碎的訊息如果大量湧入中央的雲伺服器,網路頻寬和伺服器叢集都會無法負荷。比較合理的設計,是在靠近終端設備的地方,透過邊緣計算的方式,把大量的簡單事件處理成少量的複雜事件,再遞送給中央的雲伺服器。完美!

寫這篇文章的過程,我產生一個疑惑:誰說CEP必須獨立於業務系統之外,而不能作為業務系統本身的基礎?

作者簡介


Advertisement

更多 iThome相關內容