響應(yīng)式架構(gòu)簡(jiǎn)介

為什么企業(yè)級(jí)軟件難以開發(fā)

??在介紹響應(yīng)式編程技術(shù)會(huì)使軟件開發(fā)工作變得簡(jiǎn)單之前,讓我們先了解一下開發(fā)企業(yè)級(jí)軟件為何如此之難。當(dāng)然,你可能在開發(fā)企業(yè)級(jí)軟件時(shí)遇到過各種難題,如需要經(jīng)常使用的數(shù)據(jù)庫出問題、應(yīng)用程序服務(wù)器拖慢了你開發(fā)的軟件的運(yùn)行速度,或者更為嚴(yán)重的情況,你使用的編程語言帶來了問題。這些問題是普遍存在的。

??根據(jù)領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)(DDD)實(shí)踐,使用端口和適配器(也稱為六邊形)架構(gòu),可以簡(jiǎn)化開發(fā)企業(yè)級(jí)軟件的工作。要實(shí)現(xiàn)完整的企業(yè)級(jí)應(yīng)用程序,必須考慮架構(gòu)、設(shè)計(jì)、配置、實(shí)現(xiàn)和組件的詳細(xì)部署工作,如圖所示

??事實(shí)上,即使對(duì)于大多數(shù)資深架構(gòu)師和開發(fā)者來說,這也是一項(xiàng)需要花費(fèi)數(shù)個(gè)月才能完成的工作,更何況那些初中級(jí)開發(fā)者呢?將這項(xiàng)工作交給初中級(jí)開發(fā)者完成,你是否會(huì)放心?將這樣復(fù)雜的工作交給初中級(jí)開發(fā)者來做顯然是有風(fēng)險(xiǎn)的。每位開發(fā)者都需要從頭至尾了解并熟練掌握的工作的數(shù)量是驚人的。

領(lǐng)域事件

??持久存儲(chǔ)的領(lǐng)域事件代表了業(yè)務(wù)領(lǐng)域中發(fā)生的事情。它們能夠傳輸領(lǐng)域模型中出現(xiàn)過的情況,它們的信息量很大,而且只要你處理領(lǐng)域事件,就需要用到它們。領(lǐng)域事件僅是一種結(jié)果。每個(gè)領(lǐng)域事件都是作為在領(lǐng)域中執(zhí)行的某個(gè)命令的輸出結(jié)果而被創(chuàng)建的。在命令模式(GoF)中,應(yīng)用程序中的對(duì)象表達(dá)了用戶或應(yīng)用程序的目的,從而實(shí)現(xiàn)業(yè)務(wù)操作。一旦該目的被實(shí)現(xiàn),那么獲得的結(jié)果就是領(lǐng)域事件。如果你向系統(tǒng)(如瀏覽器、智能手機(jī)、云計(jì)算、消息系統(tǒng)等)輸入命令,就會(huì)獲得Actor對(duì)象和領(lǐng)域事件。因而,你最終實(shí)現(xiàn)的是“響應(yīng)式堆?!焙虯ctor模型,如下圖所示。

什么是Actor模型?

??使Actor對(duì)象能夠像第一類值一樣被處理,并通過消息傳遞功能加強(qiáng)了Actor對(duì)象之間的通信操作。Actor是一種無鎖的并發(fā)代理對(duì)象,而且執(zhí)行它們的線程通常不會(huì)被阻塞,所以使用Actor對(duì)象設(shè)計(jì)的應(yīng)用程序能夠完美地利用系統(tǒng)的基礎(chǔ)線程資源。

Actor模型應(yīng)用程序僅需要關(guān)注下列幾個(gè)重要概念。

  • 接收哪些類型的消息一一命令和/或事件?發(fā)出哪些類型的消息一一命令和/或事件?
  • 為了回應(yīng)接收到的消息,應(yīng)用程序應(yīng)對(duì)其當(dāng)前狀態(tài)做出哪些改變?

響應(yīng)式應(yīng)用程序簡(jiǎn)介

??定義:響應(yīng)式應(yīng)用程序具有較好的響應(yīng)性、韌性和靈活性,而且應(yīng)該是由消息驅(qū)動(dòng)的,從而能夠使用戶獲得實(shí)時(shí)操作的感覺。

響應(yīng)式應(yīng)用程序的目的:

  • 對(duì)用戶和其他應(yīng)用程序組件做出回應(yīng):響應(yīng)式應(yīng)用程序的響應(yīng)時(shí)間應(yīng)符合或高于非功能性需求。
  • 對(duì)失效情況做出回應(yīng):響應(yīng)式軟件應(yīng)通過使韌性成為本身的重要特征,從而獲得恢復(fù)任何類型組件的能力。
  • 對(duì)加載操作做出回應(yīng):響應(yīng)式程序應(yīng)通過以獨(dú)立方式管理離散資源(如系統(tǒng)實(shí)體),努力避免出現(xiàn)資源爭(zhēng)用情況。這種設(shè)計(jì)方式能夠使系統(tǒng)擁有韌性和高吞吐量。
  • 對(duì)消息做出回應(yīng):響應(yīng)式應(yīng)用程序的基礎(chǔ)設(shè)計(jì)思想是通過其核心的異步消息傳遞模式,實(shí)現(xiàn)消息驅(qū)動(dòng)模式。

響應(yīng)式應(yīng)用程序的關(guān)鍵特性

響應(yīng)性

??響應(yīng)式應(yīng)用程序必須像用戶界面的功能需求一樣具備響應(yīng)性。這些功能需求包括實(shí)時(shí)用戶界面的功能需求,實(shí)時(shí)用戶界面允許多個(gè)用戶同時(shí)執(zhí)行重疊的編輯操作。而且,即使出現(xiàn)故障,響應(yīng)性也必須仍然存在。通過被觀察者和觀察者模型可以實(shí)現(xiàn)響應(yīng)性;被觀察者和觀察者模型是指當(dāng)系統(tǒng)發(fā)生改變時(shí),系統(tǒng)有能力通知對(duì)該改變感興趣的一方或多方。該模型需要使用能夠根據(jù)用戶消耗資源的數(shù)量進(jìn)行調(diào)整的事件流和可視化模型,而不是使用根據(jù)業(yè)務(wù)操作調(diào)整的系統(tǒng)模型。

韌性

??應(yīng)用程序擁有故障恢復(fù)的能力。響應(yīng)式應(yīng)用程序通過監(jiān)督較低層級(jí)的響應(yīng)式組件來預(yù)測(cè)故障情況。這種模式擁有異步操作邊界,而且能夠?qū)⒐收暇唧w化為消息,并通過重要的專用消息通道發(fā)送[Read-Write]。監(jiān)督者會(huì)被賦予對(duì)被監(jiān)督組件的故障做出回應(yīng)的能力。正確的回應(yīng)可能是徹底停止故障組件,也可能是重新啟動(dòng)故障組件,還可能是通過忽略故障原因來命令故障組件繼續(xù)運(yùn)行。監(jiān)督者甚至可以選擇使本身失效,從而使它的監(jiān)督者能夠選擇上述恢復(fù)操作之一。
??這種方式傾向于將故障隔離在它們出現(xiàn)的應(yīng)用程序區(qū)域中,從而使程序員能夠以對(duì)癥下藥的方式處理它們。同時(shí)這還能夠保護(hù)應(yīng)用程序的其他組成部分,避免故障以連鎖反應(yīng)的方式影響一個(gè)或多個(gè)不相關(guān)的應(yīng)用程序區(qū)域。

靈活性

??每當(dāng)我們思考可伸縮性時(shí),總是會(huì)橫向或縱向擴(kuò)展思考范圍??v向可伸縮性可以通過添加擁有更多中央處理器(CPU)的高性能計(jì)算機(jī)實(shí)現(xiàn),每臺(tái)計(jì)算機(jī)都擁有多核處理器(如IntelXeon Phi處理器)和大量的內(nèi)存。橫向可伸縮性可以通過添加多臺(tái)提供日常服務(wù)的服務(wù)器實(shí)現(xiàn),每臺(tái)服務(wù)器都應(yīng)擁有中等性能的CPU(如一塊或兩塊Intel i7 Quad Core 4700HQ處理器)。
??當(dāng)然,為了滿足特定的可伸縮性需求,也可以同時(shí)使用這兩種擴(kuò)展方式。但從實(shí)踐的觀點(diǎn)看,靈活性比可伸縮性更為重要,因?yàn)殪`活性還意味著通過調(diào)整滿足當(dāng)前應(yīng)用程序的需求。也就是說,可能需要在非高峰時(shí)間通過調(diào)整使用較少的計(jì)算資源。不論增加計(jì)算資源還是減少計(jì)算資源,你編寫的軟件都應(yīng)該全天候提供與預(yù)期相符的響應(yīng)性。靈活性能夠提供這項(xiàng)支持,因?yàn)殪`活性意味著根據(jù)需求進(jìn)行調(diào)整,這種調(diào)整方式是響應(yīng)性的核心。
??響應(yīng)式組件的消息驅(qū)動(dòng)特性和它們的位置透明性都為根據(jù)需求調(diào)整應(yīng)用程序提供了幫助,即實(shí)現(xiàn)了應(yīng)用程序的靈活性。

消息驅(qū)動(dòng)

??系統(tǒng)組件僅會(huì)在收到消息時(shí)做出回應(yīng),所以系統(tǒng)能夠使用可用線程運(yùn)行應(yīng)用程序中必須立刻對(duì)消息做出回應(yīng),當(dāng)前沒有正在對(duì)消息做出回應(yīng)的組件不會(huì)占用寶貴的CPU資源。消息的類型包括命令消息、文檔消息和事件消息。響應(yīng)式應(yīng)用程序中的組件會(huì)通過異步消息傳遞模式,接收其他組件發(fā)送的消息,所以能夠自然而然地降低各種組件之間的接口和時(shí)間耦合性。響應(yīng)式組件能夠選擇以獨(dú)立方式對(duì)每條消息做出回應(yīng)的方式,所以它們能夠做好接收預(yù)期內(nèi)消息的準(zhǔn)備工作。這就進(jìn)一步降低了發(fā)送消息組件和接收消息組件接口的耦合性,因?yàn)榭蛻舳藷o須知道發(fā)送消息的次序。響應(yīng)式組件本身是小型的類似原子的單元,而且它們?cè)谕粫r(shí)刻僅會(huì)對(duì)一條異步消息做出回應(yīng),所以它們能夠排除所有鎖策略。

企業(yè)級(jí)應(yīng)用程序

??也許你所在的企業(yè)項(xiàng)目正處在項(xiàng)目的初始階段。使用“普通”企業(yè)級(jí)軟件開發(fā)工具可能已經(jīng)獲取了一些成果,但為了達(dá)到策略應(yīng)用程序的目標(biāo),還必須進(jìn)一步擴(kuò)大這些成果。可以考慮使用Actor型來滿足剛性和之前看起來遙不可及的需求。除了性能和可伸縮性需求外,還需要?jiǎng)?chuàng)建軟件模型,以便反映業(yè)務(wù)預(yù)測(cè)的心智模型。領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)(DDD)就是專門用于支持SIS(DDD)開發(fā)的。
??此外,當(dāng)你面對(duì)新的企業(yè)策略挑戰(zhàn)時(shí),必定需要整合企業(yè)中已經(jīng)存在的系統(tǒng)。開發(fā)企業(yè)策略解決方案和整合各種企業(yè)系統(tǒng)工作中的一個(gè)要點(diǎn)是對(duì)工具的選擇。通常,架構(gòu)師會(huì)選擇不使任何人失去工作的解決方案。這些解決方案通常是膨脹的、緩慢的、不具備可伸縮性的、無彈性的并且昂貴的。當(dāng)前這些常見的解決方案已經(jīng)受到了挑戰(zhàn),而你的目標(biāo)就是在這類膨脹的解決方案中,尋找精煉的、成本效益高的處理方式。

了解Actor模型

Actor是一種計(jì)算實(shí)體,它會(huì)對(duì)收到的消息做出回應(yīng),并且可以做下列事情:

  • 向其他Actor對(duì)象發(fā)送一定數(shù)量的消息。
  • 創(chuàng)建一定數(shù)量的新Actor對(duì)象,設(shè)定對(duì)下一條消息做出的回應(yīng)方式。

??執(zhí)行這些操作的次序不分先后,而且可以通過并行方式執(zhí)行它們。在功能齊全的Actor系統(tǒng)中,所有事物都是Actor對(duì)象。這意味著我們通常使用的基本數(shù)據(jù)類型(如字符串和整型)都是Actor對(duì)象。最實(shí)用的模式是設(shè)計(jì)一種將Actor對(duì)象用作特殊類型系統(tǒng)組件的Actor系統(tǒng)。在這種系統(tǒng)中,Actor對(duì)象的尺寸比整型值大,但也不會(huì)比整型值的尺寸超出太多。要確定Actor對(duì)象的適當(dāng)尺寸,可將它們視為專門化的應(yīng)用服務(wù),如單個(gè)的領(lǐng)域模型實(shí)體或小型的領(lǐng)域模型集合

Actor系統(tǒng)和Actor對(duì)象具有下列基本特點(diǎn)

  • 直接通過異步消息傳遞方式進(jìn)行通信:如果Actor對(duì)象A1要向Actor對(duì)象A2發(fā)送消息M1,那么Actor對(duì)象A1就必須知道Actor對(duì)象A2的地址。如果Actor對(duì)象A1知道Actor對(duì)象A2的地址,那么它就能夠直接向Actor對(duì)象A2發(fā)送消息M1,但Actor對(duì)象A2會(huì)使用獨(dú)立線程接收和處理消息M1。換言之,消息M1是通過異步方式被發(fā)送給Actor對(duì)象A2的。實(shí)際上,在發(fā)送者Actor對(duì)象和接收者Actor對(duì)象之間還存在一個(gè)間接處理層——郵箱(消息緩存單元)。
  • 狀態(tài)機(jī):Actor模型支持有限狀態(tài)機(jī)。當(dāng)Actor對(duì)象轉(zhuǎn)換為某個(gè)預(yù)設(shè)狀態(tài)時(shí),就能夠改變對(duì)未來接收到的信息的處理模式。通過變?yōu)榱硪环N消息處理器,Actor對(duì)象就成了一種有限狀態(tài)機(jī)。
  • 無共享:一個(gè)Actor對(duì)象不會(huì)與其他Actor對(duì)象或相關(guān)組件共享可變狀態(tài)。
  • 無鎖的并發(fā)處理方式:因?yàn)锳ctor對(duì)象不會(huì)共享它們的可變狀態(tài),而且它們?cè)谕粫r(shí)刻僅會(huì)接收一條消息,所以在對(duì)消息做出回應(yīng)前,Actor對(duì)象永遠(yuǎn)都不需要嘗試鎖定它們的狀態(tài)。
  • 并行性:并發(fā)處理方式和并行處理方式是不同的概念。并發(fā)處理方式是指多個(gè)計(jì)算操作同時(shí)出現(xiàn)。并行處理方式是指以并發(fā)處理方式完成單個(gè)目標(biāo)。并行性是通過將單個(gè)的復(fù)雜處理過程拆分成較小的任務(wù)并以并發(fā)處理方式執(zhí)行它們實(shí)現(xiàn)的。當(dāng)?shù)燃?jí)較高的Actor對(duì)象能夠?qū)⒍鄠€(gè)任務(wù)分派給多個(gè)下級(jí)Actor對(duì)象,或者任務(wù)中含有復(fù)雜的處理層級(jí)時(shí),就適合通過Actor模型使用并行處理方式。
  • Actor對(duì)象的系統(tǒng)性:?jiǎn)蝹€(gè)Actor對(duì)象不具備并行性。Actor對(duì)象的量級(jí)非常輕,因此在單個(gè)系統(tǒng)中創(chuàng)建許多Actor對(duì)象是受推薦的處理方式。任何問題都可以通過添加Actor對(duì)象來解決。

Action擴(kuò)展特性(Akka系統(tǒng))

  • 位置透明性:使用抽象引用代表Actor對(duì)象的地址。如果Actor對(duì)象A1獲得了Actor對(duì)象A2的引用,Actor對(duì)象A1就能夠向Actor對(duì)象A2發(fā)送消息。提供支持的Actor系統(tǒng)會(huì)負(fù)責(zé)處理傳送消息的操作,不論Actor對(duì)象A2是位于本地Actor系統(tǒng)還是位于遠(yuǎn)程Actor系統(tǒng)中。
  • 監(jiān)督:在Actor對(duì)象之間建立依賴關(guān)系,父Actor對(duì)象監(jiān)督子(下級(jí))Actor對(duì)象。當(dāng)監(jiān)督者Actor對(duì)象向下級(jí)Actor對(duì)象分派任務(wù)時(shí),就必須對(duì)這些下級(jí)Actor對(duì)象出現(xiàn)的失效情況做出回應(yīng)。合法的回應(yīng)包括繼續(xù)運(yùn)行、重啟和停止下級(jí)Actor對(duì)象。監(jiān)督者還可以通過使本身失效從而使失效情況升級(jí),這會(huì)將失效控制權(quán)上交給監(jiān)督者的父對(duì)象(監(jiān)督者的監(jiān)督者)。監(jiān)督機(jī)制適于在并行處理方式中使用,在該方式中監(jiān)督者會(huì)將多個(gè)任務(wù)分派給多個(gè)下級(jí)對(duì)象,從而形成任務(wù)處理層級(jí)。
  • Future/Promise對(duì)象:這兩種對(duì)象提供了接收異步操作結(jié)果的手段,不論該結(jié)果是代表異步操作成功完成還是異步操作出現(xiàn)失效情況。為了管理接收到的結(jié)果,系統(tǒng)需要使用特殊的Actor對(duì)象(如Future和Promise)。擁有Future對(duì)象的組件可以選擇以等待/阻塞方式接收結(jié)果,也可以選擇以異步方式接收結(jié)果。

管理不確定性系統(tǒng)

??什么是不確定性,為什么我們要關(guān)心它呢?在應(yīng)用程序開發(fā)過程中,不確定性系統(tǒng)是指當(dāng)使用相同的輸入數(shù)據(jù)多次執(zhí)行程序時(shí),會(huì)輸出不同結(jié)果的系統(tǒng)。事件驅(qū)動(dòng)的響應(yīng)式應(yīng)用程序天生就具有不確定性,實(shí)際上,不應(yīng)將不確定性和不可靠混為一談,只要你了解了應(yīng)用程序產(chǎn)生不確定輸出結(jié)果的情況,就不必過于擔(dān)心程序的不確定性。具有天生不確定性的是由事件驅(qū)動(dòng)的架構(gòu),而Actor模型只不過恰好是一種由事件驅(qū)動(dòng)的架構(gòu)。而且,通過引入Actor對(duì)象(Actor對(duì)象本身是一種具有原子確定性的單元),Actor 模型還能夠幫助我們推導(dǎo)天生具有不確定性的并發(fā)業(yè)務(wù)系統(tǒng)。因此,真正的決策點(diǎn)是使用無法伸縮的單線程架構(gòu)設(shè)計(jì)程序,還是使用可管理的、多線程的、由事件驅(qū)動(dòng)的架構(gòu)設(shè)計(jì)程序。

對(duì)象性能模型

Actor對(duì)象只能根據(jù)發(fā)送消息才能交互??赏ㄟ^下列方式獲得引用。

  • 初始情況:Actor對(duì)象A可能一開始就已經(jīng)擁有Actor對(duì)象B的引用。
  • 父子關(guān)系:當(dāng)Actor對(duì)象A創(chuàng)建了Actor對(duì)象B后,Actor對(duì)象A立刻就獲得了Actor對(duì)象B的唯一引用。
  • 贈(zèng)予:當(dāng)Actor對(duì)象A創(chuàng)建了Actor對(duì)象B后,Actor對(duì)象A可以將Actor對(duì)象B的引用贈(zèng)予其他Actor對(duì)象。
  • 介紹:如果Actor對(duì)象A擁有Actor對(duì)象B和Actor對(duì)象C的引用,那么Actor對(duì)象A可以通過發(fā)送消息使Actor對(duì)象B獲得Actor對(duì)象C的引用。

??Actor對(duì)象B可以保留該引用并在將來使用該引用。

Actor模型的明晰性

??利用Actor模型可以大幅度簡(jiǎn)化企業(yè)級(jí)應(yīng)用程序。領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)(DDD)的主要目標(biāo)之一,是在軟件模型(DDD)中使業(yè)務(wù)概念變得明確和清晰。另一方面,精簡(jiǎn)的架構(gòu)僅含有用戶界面和清晰的軟件模型。據(jù)此甚至能夠推斷出用戶界面也是軟件模型的組成部分,因?yàn)樗从澈捅憩F(xiàn)了業(yè)務(wù)專家的心智模型(SIS),通過這種方式幫助用戶做出重要決策。下圖進(jìn)一步突出了軟件模型具有明晰性的重要性。指定消息的接收者是明確的,不論這條消息是命令消息還是事件消息。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容