吊打面試官!應用間互動如何設計?

架构师汤师爷發表於2024-10-18

大家好,我是湯師爺~

應用互動是指不同應用結構之間的資料交換和通訊方式。

在一個複雜的系統中,各個應用並不是孤立存在的,它們往往需要相互協作,才能完成更復雜的業務流程。

應用互動的設計就是為了確保這些系統和元件能夠順暢地“對話”,實現系統整體目標。

應用互動的形式有多種,包括同步呼叫、非同步訊息通訊等。每種互動方式都有其特定的應用場景和優缺點。

透過合理的互動設計,系統中的各個部分能夠高效協同,減少耦合度,增加系統的靈活性。

同時,良好的互動設計還能顯著提升系統的效能和容錯能力,即使在大流量訪問、業務需求複雜的情況下,也依然保持穩定執行。

應用服務的上下游

應用服務是系統對外提供的核心業務功能。

應用服務也是如此,應用服務可以獨立演化和實現,但它們並非完全獨立,必須相互互動,才能實現整體系統目標。

如何設計應用服務之間的互動?首先需要了解清楚服務上下游的概念。

1、服務上下游的概念

服務的上下游關係可以透過DDD(領域驅動設計)的建模方法來定義,主要使用限界上下文(bounded context)和上下文對映(context mapping)這兩個概念。

上下游表示上下文之間的依賴方向,下游需要了解上游的領域知識來實現業務,而上游不需要了解下游。

換句話說,上游服務不需要關心下游服務的存在,但下游服務的實現卻依賴於上游服務提供的能力。

這個概念聽起來有些抽象,確實讓許多人犯迷糊。讓我們透過線上商城的幾個應用服務來具體說明:

  • 使用者服務:管理使用者的賬戶資訊,包括註冊、登入、認證、個人資料等。處理使用者的許可權和角色管理。
  • 商品服務:管理商品的基本資訊,包括名稱、描述、價格、圖片、分類等。提供商品的查詢、篩選和瀏覽功能。
  • 庫存服務:管理商品的庫存數量。處理庫存的預佔、扣減和回補操作。
  • 交易服務:處理訂單的建立、修改、取消和查詢。管理訂單的狀態和生命週期。
  • 支付服務:處理支付事務,支援多種支付方式。管理支付狀態。
  • 履約服務:處理訂單的履約,包括揀貨、包裝、發貨等。管理物流資訊和配送狀態。

如圖所示,我們可以看出各個服務的上下游關係。

商品服務和使用者服務是上游服務,它們提供基礎資料,其他服務依賴於這些資料。

交易服務位於中間位置。對使用者服務和商品服務而言,交易服務是下游,因為它依賴於這兩個服務的基礎資料。

對庫存服務來說,交易服務也是下游,因為交易下單過程中,需要庫存服務來預佔、扣減庫存。

對履約服務而言,交易服務是上游,因為它提供訂單資料,驅動後續的訂單履約流程。

2、為什麼要區分上下游?

區分上下游關係的核心目標是為了解耦。

"解耦"這個詞相信大家都不陌生,但它的含義往往過於抽象和模糊。在這裡,我們探討一下解耦到底指什麼。

耦合是指兩個或多個結構之間的相互作用和影響。在軟體開發中,這可以理解為不同模組、系統或團隊之間的相互依賴和影響。

隨著軟體需要解決的業務問題越來越複雜,單個系統或團隊很難獨立實現業務目標。因此,解耦的目的並非完全消除耦合,而是減少不必要的依賴關係。

在上文中我們提到,上游服務不需要關心下游服務的存在,但下游服務的實現卻依賴於上游服務提供的能力。

因此,當下遊服務的團隊迭代新功能時,無需評估是否影響上游服務,因為基於明確的上下游關係,能快速判斷出不會影響上游服務。只需評估是否影響自己的下游服務。

例如,交易服務的功能發生變更時,只需通知履約服務的團隊,評估是否會影響到他們,上游服務團隊則無需知曉。

這種方式能大大減少影響面的評估工作,提高團隊協作效率。

相反,如果上下游關係混亂,存在各種迴圈依賴,那麼任何一個服務的改動都難以準確評估影響面。此時就需要召集所有服務的團隊,逐一評估是否有影響。

實際場景中,每次專案會議都需要一屋子人才能評估出影響面,這樣的協作效率極低。

3、上下游關係的核心使用場景

在軟體研發過程中,上下游關係在許多關鍵場景中發揮著重要作用。

  • 明確服務之間的依賴關係:上下游關係讓開發者清晰地瞭解服務間的依賴。這有助於減少不合理的依賴,確保服務的獨立性和模組化設計。同時,它也避免了服務間的迴圈依賴,降低了一個服務出現故障引發連鎖反應的風險。
  • 評估影響面:當上遊服務變更時,可以預見其對下游服務的影響,從而制定相應的應對策略。
  • 指導團隊協作:上下游關係有助於明確各團隊的職責和工作範圍。上游團隊需要考慮下游團隊的需求,提供穩定的介面和服務;下游團隊則需要適應上游的變化。

應用服務的互動方式

應用服務的互動方式多種多樣,其中最主要的兩種是同步呼叫和非同步訊息。

1、同步呼叫

同步呼叫是一種通訊方式,其中呼叫方(客戶端)向被呼叫方(服務端)傳送請求,並等待服務端處理完成後返回結果。在此期間,呼叫方會阻塞,直到收到服務端的響應。這種方式要求呼叫方和被呼叫方同時線上,且呼叫方在等待響應期間無法執行其他操作。

在微服務架構中,同步呼叫的典型技術實現協議包括HTTP、REST API、Dubbo、Thrift、gRPC和SOAP等。

同步呼叫適用於下游服務需要立即獲取上游服務的資料或功能的場景。這種通訊方式簡單直接,但需要處理服務之間的可用性問題。

例如,使用者下單時,訂單服務需要同步呼叫商品服務,獲取商品的最新價格和庫存資訊,以確保訂單有效。

通常來說,上游服務不應同步呼叫下游服務。如果上游服務同步呼叫下游服務,會導致上游需要了解下游的領域知識,違背DDD上下游的設計原則,加深系統耦合,並增加團隊協作複雜性。

此外,這種做法還可能引發級聯故障,降低系統可靠性。如果上下游直接互相呼叫,那下游服務發生故障也將直接影響上游服務的可用性,可能導致整個系統都不可用。

2、非同步訊息

非同步訊息是另一種通訊方式,其中訊息的傳送者(生產者)和接收者(消費者)透過訊息佇列或訊息中介軟體進行通訊。

傳送者無需等待接收者處理完成即可繼續其他操作。訊息被髮送到訊息佇列後,接收者從佇列中非同步獲取並處理。這種方式將傳送者和接收者的時間依賴解除,讓兩者能夠獨立運作,提高了系統的靈活性和可擴充套件性。

在微服務架構中,非同步訊息通常透過訊息中介軟體實現,如RabbitMQ、Kafka和RocketMQ等。

非同步訊息適用於上游服務向下遊服務釋出事件或通知的場景,能有效解耦服務,提高系統的彈性和可靠性。下游服務也可透過非同步訊息向上遊服務反饋資訊,實現雙向通訊。

例如,當使用者提交訂單後,訂單服務呼叫支付服務發起支付。使用者完成支付後,支付服務釋出"支付成功"訊息,訂單服務接收該訊息後,更新訂單狀態併傳送通知。

3、其他互動方式

1)共享資料庫方式

多個服務訪問同一個資料庫,直接讀取或寫入資料。

在微服務架構中,通常不建議採用共享資料庫的方式,因為它違反了服務自治原則,增加了服務間的耦合度。

2)檔案傳輸

服務之間透過共享檔案系統或FTP等方式交換資料檔案。這種互動方式通常是批處理的,實時性較差。

3)服務匯流排(ESB)

使用統一的通訊匯流排來連線不同的服務和系統。服務之間不直接通訊,而是透過匯流排中介,適用於需要整合多種異構系統和服務的大型企業級系統。

然而,這種方式引入了額外的架構層,增加了系統複雜性。所有服務都耦合到匯流排上,存在單點故障風險。

本文已收錄於,我的技術網站:tangshiye.cn 裡面有,演算法Leetcode詳解,面試八股文、BAT面試真題、簡歷模版、架構設計,等經驗分享。

相關文章