使用 Dapr 縮短軟件開發周期,提高工作效率


Microsoft DevOps 文檔里的文章(https://docs.microsoft.com/zh-cn/azure/devops/report/dashboards/cycle-time-and-lead-time?view=azure-devops)中的這張圖片在給我們介紹了 什么是周期時間 以及它如何影響我的項目流時非常有影響力。

image

第一次輸入 "正在進行" 或 "已解決" 狀態類別到輸入 "已完成" 狀態類別,計算周期時間。 當開發人員編寫代碼時,能夠快速驗證更改並進行修訂對於保持較短的周期時間至關重要。

豐田生產方式之父大野耐一曾經說過:我們唯一要做的就是降低從接到訂單到交付產品給客戶的周期時間。周期時間的降低可以有效保證軟件的按時交付 。所以周期時間是軟件交付的核心目標。

特別是微服務的設計和開發,通常需要達成下列4個目標:

  • 構建的API 驅動設計的微服務
  • 一切都可以在本地構建、測試和運行,而無需復雜的設置。
  • 雲端和本地依賴關系的等效性
  • 設備環境無關,可以自由在Windows,Linux,Mac 之間切換。

我們借助於Dapr 可以非常容易的達成以上4個目標, 使用 Docker Compose 和 Dapr 技巧進行本地開發,測試和生產環境運行於Kubernetes, Kubernetes現在是各大雲廠的標配服務。借助於Dapr 的語言無關性,平台無關性,我們可以在環境上盡量的縮短了時間,保持較短的周期時間交付軟件。

我們可以在大腦里面來回顧一下我們的開發過程,對於每個任務/代碼更改:

  1. 開發人員會將更改部署到生產環境
  2. 如果發現任何錯誤,請重新部署舊 鏡像
  3. 在本地修復所有更改
  4. 推動其分支以生成可部署的內部版本,然后返回到 (1)

只有當開發人員脫離這個循環時,他們才能將他們的代碼簽入主程序。這個過程太瘋狂了!僅第 4 步在鏡像創建和部署之間就花費了大約 20 分鍾。兩三個遺漏的錯誤可能會使開發人員在一天中花掉大約1個小時,並且考慮到除了日常工作之外,我們都在從事這項工作,這扼殺了生產力。還有可能要考慮到部署對依賴項的更改所需的周期,此處的部署花費了更長的時間。

下面我們從 提高軟件開發生產力角度來聊聊,Dapr所提供的主要生產力提高優勢是:

  • 減少技術債務 - 通過生產和使用軟件來實現,該軟件封裝了具有高變化率的領域,具有出色的關注點分離性,並具有廣泛的解耦。
  • 減少所需的編碼工作量 — 通過使用"低代碼"方法實現,方法是提供許多通常需要的預構建軟件部件,尤其是實現較低業務價值的商品管道功能的部件,例如將服務連接在一起的代碼。
  • 開發人員更加專注於生成高價值的業務邏輯 — 通過減少花費大量時間生成商品管道代碼和/或使用可以使用自動化代碼的手動流程和工具來實現。
  • 共享狀態的並發訪問的有效協調 — 分布式系統中這個眾所周知的困難區域在許多情況下可以使用 Actor 模型來生成此結果。

將分布式系統的服務彼此分離,可以使軟件開發、擴展和維護軟件更具時間和成本效益,也更容易。為什么?將軟件片段彼此分離可以使其內部代碼內容和代碼結構彼此獨立地變化,從而大大減少了需求更改時代碼更改所需的工作量。這種脫鈎是減少技術債務的最佳方法之一,並隨着歲月的流逝保持低水平,從而從長遠來看提高生產率。

Dapr 產生解耦的一個關鍵方式是通過其構建塊,每個構建塊都定義了分布式系統常用功能的概念接口。對於大多數構建塊,Dapr 還提供了許多預構建的插件組件,每個組件都為構建塊概念的特定實例實現構建塊接口的全部或部分。使用預構建的插件組件還可以減少所需的編碼工作量。如果沒有 Dapr,開發人員不知道有多少次必須一遍又一遍地編寫大致相同的低級管道代碼,才能連接到我們的代碼使用的每個數據庫或雲服務並與之交互?使用Dapr的構建塊/組件方法,答案為零!使用預構建的插件組件可節省大量時間,使開發人員能夠專注於更高價值的工作。

如果我告訴你,Dapr是一個用於分布式系統的瑞士軍刀實用程序服務,你很可能會想發現Dapr的許多功能,因為它既是中介又是解耦者。Dapr 提供的主要功能如下,其中許多功能通過構建塊和組件實現,但不是全部:

  • 狀態存儲 — Dapr 為鍵/值對狀態存儲構建塊定義一個概念接口,然后提供了許多預構建的插件狀態存儲提供程序組件,每個組件都連接到特定的外部鍵值對狀態存儲,如 Redis 存儲或其他流行的鍵/值對數據庫。Dapr State Store 的目的是提供低延遲存儲,如緩存。有關對通用存儲或數據庫管理系統的支持,請參閱下面的資源綁定和觸發器。
  • Pub/Sub — 與狀態存儲類似,Dapr 為發布/訂閱構建基塊定義了一個概念接口,此外還提供了許多預構建的插件發布/訂閱組件,每個組件都連接到外部發布/訂閱消息傳送服務,例如 Azure 服務總線主題或 Redis 流。
  • 安全機密訪問 — 與上述想法相同,但適用於各種外部機密存儲,如密鑰保管庫。
  • 資源綁定和觸發器 — 與上述想法相同,但應用於各種外部資源(許多是雲資源),如隊列、事件中心、服務網格、Blob 存儲、某些數據庫等。
  • 服務到服務調用 — 此構建基塊允許"Daprized"服務通過 RPC 使用服務名稱加方法名稱尋址(而不是通過 HTTP 或 gRPC 地址)相互通信。這會將服務到服務的通信與特定網絡終結點分離。使用集群計算主機時需要這樣做,並且使用其他主機也可以節省時間。
  • Actor — 此構建塊允許每個"Daprized"服務使用 Actor 模型來利用其獨特的特征:1) 保持狀態和在同一實體內操作狀態的代碼,以及 2) "基於回合的並發",以防止當多個客戶端同時使用同一個 Actor 時狀態不同步。
  • 可觀察性 — 可觀察性構建基塊概念界面提供分布式系統中服務到服務交互流(包括各種組件的詳細信息)的跟蹤、指標和運行狀況監視,以及將數據發送到外部聚合器,例如 Azure Monitor、Application Insights 和 Zipkin。
  • 有效安全性 — 在"Daprized"服務的廣度和深度以及整個協作"Daprized"服務系統中提供高級別的通常可配置的安全性。
  • 中間件管道 — 允許以聲明方式將自定義"中間件管道組件"代碼"插入"到 Dapr 請求/響應處理管道。這允許 Dapr 編排開發人員定義的服務與 Dapr 之間通信的自定義處理,反之亦然。例如,Dapr 提供了一個現成的 OAuth 2.0 中間件管道組件。
  • 巨大的可擴展性 — 這是由於 Dapr 的解耦、基於接口的設計,以及它的組件化插件架構。請注意,在給定的構建基塊中,開發人員可以編寫自己的代碼來實現針對其特定需求定制的 Dapr 組件。
  • HTTP 和 gRPC 通信,以及對流行的編程語言雲提供商的支持

請注意,上述所有預構建的插件組件也是可配置的。"插入"特定組件的行為只是在標准組件目錄中提供聲明性配置文件。Dapr 負責加載組件代碼和"掛接"所需的工作。

如果我告訴你Dapr是一個Sidecar,你就會知道,通常Dapr的單個實例與服務的單個實例配對,每個實例都在自己的進程中運行。Dapr 目前不是代碼庫。Dapr Sidecar 實例和使用它的服務實例通過 HTTP 或 gRPC(使用 HTTP2)跨其進程邊界相互通信,如下圖 所示。當您將服務實例與 Dapr Sidecar 配對時,您實質上是"Daprize"您的服務。

此外,每個 Dapr Sidecar 實例都知道協作"Daprized"服務系統中的所有其他 Dapr Sidecar 實例。所有這些協作 Dapr Sidecar 實例都使用 gRPC 在單獨的 Sidecar 專用通信通道上完全在后台相互通信,如下圖所示。以這種方式在Dapr Sidecars之間進行通信是Dapr的Pub / Sub,服務調用和Actor模型功能的關鍵。Dapr Sidecar 和使用 Dapr Sidecar 實例的服務通常在單獨的容器中運行,或作為單獨的獨立進程運行。

image

"Daprized"服務通常只與其單個私有 Dapr Sidecar 交互,如上圖 所示,將所有凌亂的管道細節以及如何與其他服務、存儲、機密等通信的知識留給 Dapr Sidecar 本身,以及 Dapr Sidecar 實例中使用的 Dapr 組件。這使得服務代碼變得不那么復雜,並且在服務中的業務邏輯代碼與 Dapr Sidecar 及其組件中的管道邏輯代碼(也稱為基礎結構代碼)之間提供了很好的關注點分離。在上面的圖 中,黃色服務包含所有業務邏輯,而粉紅色的 Dapr Sidecar 包含大部分(如果不是全部)管道代碼。業務邏輯代碼和管道邏輯代碼之間的這種關注點分離是使用Dapr導致的技術債務顯着減少的關鍵之一。因此,當需求不可避免地發生變化時,通常需要更改的代碼比管道代碼與業務邏輯代碼混合和交織的情況要少得多

最后,在業務邏輯和管道代碼之間實現高度的關注點分離,再加上組件,開發人員將更多的時間集中在高價值的業務邏輯上,而將更少的時間集中在低價值的組件管道代碼上。雖然低級管道規范是絕對必要的,但開發低級管道規范既復雜又耗時,並且需要高水平的經驗 - 所有這些都需要時間和金錢。相反,使用預構建的"插件"組件可以將開發人員的大部分時間和技能重新定向到開發業務邏輯上,從而產生與軟件最終用戶最直接相關的價值。

現在可以看到Dapr Sidecar(加上它使用的組件)如何站在使用Sidecar的服務和分布式系統中的所有其他服務之間,以及"Daprized"服務可以連接到的所有可能的雲服務或本地服務之間。這可能是很多服務!因此,在理解"Daperized"服務的以下3個主要使用場景時,Dapr作為中介的角色至關重要。

  • 可移植服務 — 一次寫入/隨處運行。Dapr 在此方案中表現出色,允許開發人員只需插入服務用於與外部服務和資源交互的不同組件(以聲明方式配置)。將服務與 Dapr Sidecar 實例放在單獨的容器中一起放入容器中,可以高度隔離硬編碼的外部依賴項。這允許相同的"Daprized"和容器化服務在本地、雲中或邊緣設備(如 IoT 現場網關)上運行,而無需更改服務代碼。相反,可能只需要對與外部依賴項接口的 Dapr 組件的聲明性定義進行更改。從本質上講,將容器化的Dapr Sidecar與容器化服務集成實際上將服務的所有外部依賴關系分離,從而以較低的工作成本實現最大的可移植性,以將端口移植到不同的托管環境或連接到不同的外部服務。
  • 多語言服務系統。借助 Dapr 的服務調用、發布/訂閱、機密以及狀態存儲以及資源綁定和觸發器,用各種語言編寫的服務可以相互通信,而無需重寫大量代碼,開發人員也不必學習許多其他語言。為了便於理解,Dapr 為許多流行的語言(如 .NET C#、Java、JavaScript、Python 和 Go 等)提供了軟件開發工具包 (SDK)。從本質上講,使用任何受支持語言和 SDK 的開發人員將針對相同的標准化 Dapr 接口進行編程,而不是針對一堆特定於臨時語言或外部服務接口進行編程。這也方便了其他2個使用場景。
    • 延長舊版軟件的使用壽命也屬於此使用場景。但請注意,舊版軟件絕對必須支持與其Dapr Sidecar的HTTP交互。如果是這種情況,那么"Daprize"遺留軟件可能是可行的,以允許它更經濟高效地成為服務系統的一部分,通過Dapr Sidecar及其構建塊和組件與其他服務和資源進行通信。
  • 具有動態依賴項的靜態服務。需要將發布/訂閱消息主干從 Redis 更改為 Azure 服務總線?當組織需要適應變化時,通常會發生這種情況。使用"Daprized"服務系統,與在不使用 Dapr 的情況下重寫許多行代碼(在許多單個服務中實現發布/訂閱消息傳遞)的成本相比,進行此更改(即更改聲明性組件定義)的每個服務的成本可能相當小。這同樣適用於其他構建基塊及其組件。

另請注意,"Daprized"服務可以托管在Kubernetes上的容器中,也可以托管在支持Docker等容器的其他主機上,包括在適當的情況下使用Docker Compose。"Daprized"服務也可以托管,而無需在各種計算主機(包括您自己的開發系統)上使用容器作為獨立進程。

縱觀軟件的歷史,Dapr的潛在節省時間和勞動力的特點真的是一件大事!到目前為止,還沒有像Dapr這樣的東西,它幾乎可以在任何地方運行,並且還提供了與分布式系統服務的大規模解耦,以及組件化和出色的關注點分離。所有這些都減少了初始開發所需的工作,並且從長遠來看,還導致技術債務明顯低於平時。從短期和長期來看,所有這些都可以顯著提高軟件開發生產力從而減少需要完成的工作量,節省時間和金錢


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM