語境
假設我們有一個擁有多個業務的組織。在此示例中,企業 A 向大學生銷售千兆互聯網服務。企業 B 向老年人出售兆位元互聯網服務。這些企業銷售的相關產品略有不同,每種產品針對不同的人群。
乍一看,這似乎可以讓一個應用程式處理所有請求。但是,鑒于每個企業都針對特定的人群,企業之間存在分歧是很自然的——從本質上講,每個企業都有自己的業務需求。例如,企業 A 可能會公開一個移動應用程式供客戶管理他們的帳戶。企業 B 可能會公開一個電話號碼,客戶必須撥打該電話號碼才能管理他們的帳戶。名單還在繼續。
在這種情況下,利用微服務的最佳方式是什么?
問題是在不同的業務中既有共同的功能,也有不常見的功能。
我們可以保持一定程度的 DRY,并擁有一組可供不同業務使用的基礎微服務(billing-api、order-api 等)。這可行,但這會導致微服務具有更多“通用”抽象 - 導致更多復雜性。舉個具體的例子,假設 billing-api 服務有一個由企業 A 和 B 共享的 /charge 端點。企業 B 的要求是始終從訂單中打折 5 美元:
//billing-api
if (businessB) {
orderCost -= 5;
}
在這種 DRY 方法中,我們將為每個業務(BFF 模式)提供一個 API 網關,該網關將聚合不同的微服務以滿足其業務需求。所有“特定于業務”的邏輯都將從基礎微服務轉移到各自業務的 API 網關中。在這個折扣示例中if (businessB),我們可以將此控制反轉給消費者,而不是在 billing-api 端點中進行檢查:
//billing-api
const { orderDiscountAmount } = req.body; //body parameters
if (orderDiscountAmount > 0) {
orderCost -= orderDiscountAmount;
}
然后業務 B 的 API 網關中的端點在呼叫 billing-api 端點時會傳入 5 的 orderDiscountAmount:
//Business B API Gateway
billingApi({ orderDiscountAmount: 5 });
這看起來不錯,但我們所做的只是在 billing-api 端點中采用 Business B 的邏輯并創建一個通用(但強制)抽象。這是“合理的”,說也許企業 A 可能有一天會使用它——但這可能永遠不會真正發生。總體而言,對于端點的開發人員和消費者來說,這感覺像是一種不自然的練習。各方的復雜性和認知負荷都增加了。
我們可以廢棄 DRY 并避免在企業之間共享微服務,以獲得最大的靈活性和簡單性。但是,如果添加更多業務(10-20),那么可能會有大量重復的功能。
在這種情況下,團隊應該如何構建?
如果我們對上面的 DRY 方法沒意見,那么團隊應該如何構建?我們可以有垂直切片的功能團隊,但這是否意味著如果我們有 10 個業務,一個團隊就需要擁有所有業務的功能(即結賬)?這種方法的缺點是功能團隊不會成為整個業務的專家 - 團隊只會成為特定業務中一個功能的專家。沒有完整的業務背景可能會導致難以做出正確的決定。
我們可以為每個業務提供一個流對齊的團隊,專門負責 UI 和 API 網關。然后,我們將讓平臺團隊創建微服務,供流對齊的團隊使用。這樣做的缺點是流對齊團隊和平臺團隊之間有一個切換步驟,也就是依賴關系。
我不確定我是否從錯誤的角度看待這一切 - 任何反饋都將不勝感激!
uj5u.com熱心網友回復:
很抱歉,但這對于 Stackoverflow 來說不是一個好問題,因為任何答案都將基于意見,并且許多方法可能有效,并且取決于您特定用例中的更多細節。因此,如果問題在某個時候結束,請不要失望。
話雖如此,我并不羞于提供我的意見,或者至少對你所描述的情況提出一些想法。
- 我相信您關于如何建立團隊和如何建立架構的問題非常緊密地聯系在一起,因為架構無疑將有效地遵循組織結構。因此,我將首先對組織設定進行進一步的思考。
- 估計每個業務所需的總人力應該讓您了解您需要多少團隊。盡量縮小團隊規模(比如 2-8 人)將有助于減少溝通開銷。因此,如果您認為這是整個企業的規模,則無需進一步劃分責任。
- 責任是最重要的關鍵詞。您必須避免使用公共服務/庫但擁有多個所有者或沒有所有者的任何情況。應該始終只有一個組織所有者。因此,當組織認識到不同領域的功能重疊時,通常的做法是建立一個負責并向其他人提供此功能的團隊。這可以是共享庫或實際部署的服務的形式。在這兩種情況下,重要的是通過正確地對他們的作業進行版本化并將其留給消費組來使用哪些版本、何時升級、提出對新功能的請求等,從而使溝通正式化。這種方法將使使用這種方法的團隊解耦通用功能。
- 在您的問題描述中,問題的核心是業務邏輯及其復雜性/重疊。所以我認為最重要的角色是產品管理。他們必須非常好(并且至少有點技術性)并將這些確切的混亂分類為可重復使用的部分和僅針對單個業務的事物。如果你有一整個產品經理團隊,他們需要很好地溝通并一起構建這張圖片。這里最重要的是關于未來愿景的良好溝通,而不僅僅是眼前的需求(提供出色的領域視圖)。只有這樣,才能以最佳方式建立架構和團隊。
- 無論初始設定多么小心 - 都會發生變化。無論您一開始認為是最佳解決方案,都將在未來的某個時候發生變化。為了為此做好準備,我總是建議使用最簡單的方法——即使這意味著一些代碼重復或其他缺陷。作為軟體架構師,我們往往喜歡完美之美,但這在現實世界中很少是最有效的方法。
- 制作一個簡單的共享服務/庫是常識,可以通過添加一些可配置性來適應多個用例。達到一定程度的復雜性是一種有用的方法,但是您必須對該庫/服務的消費者敏感,并且在任何時候都應該易于重用。關于何時功能變得太大/復雜并且必須分成多個部分才能進行維護并不是非黑即白的,但是用維護者和消費者的眼睛來看待它會更容易做出決定。在可配置服務庫的情況下,您還可以使用不同的配置進行單獨的部署,因此使用常用開發的組件,但為每個用例部署不同的端點。
- 基礎設施和服務部署可能會也可能不會遵循服務的架構。作為一般規則,我建議尋找最簡單的方法,這通常意味著提供在服務之間共享的通用基礎架構,而部署配置是服務之間區別的開始。例如,所有服務共享一個公共集群/流/網關/資料庫/等。例外情況可能是對單個服務非常特殊的需求,例如用于機器學習的硬體加密密鑰存盤或 GPU 服務器等。這將是方法對于任何合理大小的系統。(當然,如果您要擴展到非常大的規模,那么為特定服務擁有完整的堆疊/集群也是一種非常可行的方法。)
- 持久性設計是最關鍵的。發展業務邏輯、重組業務邏輯等相對容易,而發展歷史資料則相當困難。通常,您可以選擇以兩種方式之一進行設計:
- 智能演算法,愚蠢的資料。
- 智能資料,愚蠢的演算法。
(智能指的是更精細/反映更多業務需求)第二種方法最初通常更難,但根據我的經驗,當達到一定的復雜度閾值時會有更好的結果。
所以這些只是我在閱讀你的問題時想到的一些事情。很抱歉,他們無法回答您關于如何分割計費 API 的詳細問題,但您可能還有一些其他注意事項。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/460105.html
