微软开源微服务运行时Dapr,赋能云原生应用开发
為什么要用 Dapr?
Dapr 在線程和狀態一致性模型中是靈活的。如果愿意,則可以利用多線程,也可以選擇不同的一致性模型。這種靈活性使得實現高級方案時沒有人為的限制。您還可以選擇使用其他 Actor 框架中熟悉的單線程調用。Dapr 是獨一無二的,因為您可以在這些模型之間看似無問題地轉換,而無需重寫代碼。舉例來說,在構建包含多項服務的電子商務應用程序時,大家可能希望使用有狀態服務表示購物車功能,同時通過無狀態服務實現付款與配送功能。編寫這類應用程序往往需要使用多種語言、開發者框架以及基礎設施平臺,同時還必須與外部服務相集成。了解及管理如此復雜的技術棧需要占用大量時間與精力,導致開發人員無暇建立真正的商業價值。?
而Dapr 的目標正是要簡化各種基礎設施的集成過程和對系統的侵入,解決開發人員構建微服務應用程序所面臨的難題,讓開發人員更加專注于業務的實現。?
Dapr:面向云端與邊緣的微服務構建單元
Dapr是一套開源可移植事件驅動型運行時,能夠幫助開發人員輕松構建起能夠運行在云端及邊緣位置的高彈性、微服務、無狀態/有狀態應用程序。Dapr當中包含多種編程語言與開發者框架,同時顯著簡化了應用程序(例如示例中提到的電子商務應用)的構建流程。Dapr由一系列可通過標準HTTP或gRPC API由任意編程語言調用的基礎構建單元組成。這些構建單元為開發人員提供行之有效的行業最佳實踐,且各個組件之間彼此獨立,供您根據需求任意選用。此外,Dapr屬于開源項目,因此歡迎技術社區為項目添加新的構建單元或者貢獻新的組件。Dapr具有全面的平臺中立性,大家可以在任意Kuberenetes以及與Dapr集成的其他托管環境當中實現應用程序的原生運行。如此一來,開發人員即可快速構建起無需變更代碼即順暢運行在云端及邊緣位置上的微服務應用程序。經由標準API調用Dapr構建單元,開發人員即可使用任意語言及框架構建應用程序目標
使開發人員能夠使用任何語言或框架編寫分布式應用程序
通過提供最佳實踐構建塊,解決開發人員構建微服務應用程序所面臨的難題
成為社區驅動、開放和供應商中立者,尋找新的貢獻者
通過開放式 API 提供一致性和可移植性
跨云和邊緣,與平臺無關
擁抱可擴展性,提供可插拔組件,無需供應商鎖定
通過高性能、輕量功能實現 IoT 和邊緣方案
從現有代碼中增量采用,沒有運行時依賴項
?
工作原理
??????? Dapr 將 side-car 式的(Service Mesh中代指無侵入地擴展能力)容器/進程注入每個計算單元。通過標準 HTTP 或gRPC 協議,side-car 式地與事件觸發器交互并與計算單元通信。這使 Dapr 能夠支持所有現有甚至未來的編程語言,而無需您導入框架和庫。
??????? Dapr 通過標準HTTP 謂詞或 gRPC 接口提供內置的狀態管理、可靠的消息傳遞(至少一次傳遞)、觸發器和綁定。這允許您按照相同的編程范例編寫無狀態、有狀態和類似參與者的服務。您可以自由選擇一致性模型、線程模型和消息傳遞模式。
??????? Dapr 在Kubernetes 上原生地運行,作為獨立的二進制文件在您的機器上、 IoT 設備上、或作為容器運行,而不是將二進制文件注入到任何系統、云中或本地。
??????? Dapr 使用可插拔狀態存儲和消息總線(如 Redis 和 gRPC)來提供廣泛的通信方法,包括使用 gRPC 直接dapr 對 dapr 方式和具有保證傳遞和至少一次語義的異步發布訂閱(Pub-Sub)方式。
?
特征
事件驅動的 Pub-Sub 系統,利用可插拔的組件和“至少一次語”義實現
具有可插拔組件的輸入和輸出綁定
具有可插拔數據存儲的狀態管理
一致的服務到服務(service-to-servic)的發現和調用
可選擇的有狀態模型:強/最終一致性,或者首次寫入/最后寫入獲勝方式
跨平臺虛擬Actor(類似Orleans)
具有流量限制功能
內置了使用開放式遙測(Open Telemetry)進行分布式跟蹤
利用專用的 Operator 和 CRD 在 Kubernetes 上原生運行
通過 HTTP 和 gRPC 支持所有編程語言
支持混合云,適配來自 Azure、AWS、GCP 的各種開放組件(綁定、pub-sub、狀態)
可在任何地方運行——以進程或容器化的方式
輕量(58MB 二進制文件,4MB 物理內存)
作為Side Car運行——無需特殊的 SDK 或庫
專用 CLI——易于調試,擁有開發人員友好的體驗
擁有.NET、Java、Dotnet、Go、Java腳本和Python的客戶端
擁有可移植性與可擴展性的標準API
那么,我們要如何使用這些Dapr構建單元?舉例來說,假設大家正在使用一款已經部署在Kubernetes集群中的微服務應用程序內的Azure Functions運行時,且希望利用發布/訂閱模式在不同服務之間傳遞消息,具體該怎樣操作?目前,Azure Functions運行時尚不提供內置消息傳遞功能,但利用Dapr發布/訂閱構建單元,大家完全可以經由http輕松實現這項新功能。領先一步,就這么簡單!此外,Dapr發布/訂閱構建單元還提供一套可插拔組件模式,意味著大家可以動態選擇不同的消息發送方式,且無需進行任何代碼修改。舉例來說,您可以根據喜好或需求隨意選擇Redis、Kafka或者Azure Service Bus作為Dapr發布/訂閱組件。無論如何選擇,您的代碼都不會受到影響,消息收發機制本身可利用標準API在不同受支持基礎設施之間直接移植。為了同時實現可移植性以及與現有代碼的輕松集成,Dapr通過http或gRPC提供標準API。與發布/訂閱示例一樣,以下節點代碼所示為如何使用http://<myappaddress>/dapr/subscribe端點訂閱名稱為“A”和“B”的主題,同時在這些主題收到新消息時向您的應用程序發出通知。const express = require('express'); const bodyParser = require('body-parser'); const app = express(); app.use(bodyParser.json()); const port = 3000; app.get( '/dajgr/subscribe', (_req, res) => { res.json([ 'A', 'B' ]); }); app.post('/A', (req, res) => { console.log("A:", req.body); res.sendStatus(200); }); app.post('/B', (req, res) => { console.log("B:", req.body); res.sendStatus(200); }); app.listen(port,?()?=>?console.log('Node?App?listening?on?port?${port}!'))????????作為比較,以下為使用UseStartup()處理程序從ASP.NET Core CreateWebHostBuilder() 處調用的C#代碼。?
using System.Collections.Generic; using System.Text.Json; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Dependencylnjection; using Microsoft.Extensions.Hosting; using System.IO; namespace DaprPubSub { public class Startup { // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { app.UseRouting(); app.UseEndpoints(endpoints => { // Route called by Dapr runtime to get topics this app subscribes to. endpoints.MapGet("dagr/subscribe", async context => { // Returns list of topics to subscribe to as json in response. var topicsToSubscribe = new List<string>() { "TopicA", "TopicB" >; await JsonSerializer.SerializeAsync(context.Response.Body, topicsToSubscribe); }); // Route to handle events published to TopicA endpoints.MapPost("A", async context => { // Read the event form request body. using (var streamReader = new StreamReader(context.Request.Body)) { var json = await streamReader.ReadToEndAsync(); Console.WriteLine("Received event for TopicA."); Console.WriteLine($"Event Data: {json}'); } }); // Route to handle events published to TopicB endpoints.MapPost("B", async context => { // Read the event form request body. using (var streamReader = new StreamReader(context.Request.Body)) { var json = await streamReader.ReadToEndAsync(); Console.WriteLine("Received event for TopicB."); Console.WriteLine($"Event Data: {json}"); } }); }); } } }? ? ? ? 經由各個主題向已訂閱服務發布事件,就像使用主題名稱及載荷調用Dapr本地http發布API一樣簡單。以下節點代碼示例即為如何利用Dapr發布API(本地端口3500)實現發布,當然大家也可以使用curl命令達成同樣的效果:
curl?-X?POST?http://localhost:3500/vl.0/publish/A?\? -H?"Content-Type:?application/json"?\? -d?'{"status":?"completed"}'const express = require('express'’); const path = require('path'); const request = require('request'); const bodyParser = require('body-parser'); const app = express(); app.use(bodyParser.json()); const port = 8080; const daprllrl = 'http://localhost:${process.env.DAPR_HTTP_PORT || 3500}/vl.0'; app.post('/publish', (req, res) => { console.log("Publishing: ", req.body); const publishUrl = '${daprUrl}/publish/${req.body.messageType}'; request( { uri: publishUrl, method: ’POST', json: req.body } ); res.sendStatus(200); }); app.listen(process.env.PORT || port, ()?=> console.log('Listening on port ${port}!'????????根據以上示例,在服務中使用Dapr并不涉及編譯時間依賴性,只需要直接利用消息正文構建URL即可。Sidecar架構與受支持基礎設施
Dapr將其API作為Sidecar架構以容器或者進程的形式公開,因此不需要在應用程序代碼當中包含任何Dapr運行時代碼。正因為如此,Dapr能夠輕松與其他運行時相集成,同時通過應用程序邏輯分離顯著提高了支持能力。Dapr以side-car進程的形式運行????????在Kubernetes等容器托管環境內,Dapr以side-car容器的形式運行在應用程序容器所在的Pod當中。
Dapr以side-car容器的形式運行在Kubernetes Pod當中Dapr的CLI使得上手體驗更輕松,同時支持在開發者自有設備、任意Kubernetes集群(包括minikube),以及IoT Edge、Service Fabric等現有或即將推出的基礎設施平臺之上運行。要開始您的Dapr之旅,只需要運行:dapr init? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? (for local deployment)dapr init --kubernetes? ? ? (for Kubernetes deployment)
開發者語言SDK與框架
為了使Dapr對不同語言更自然,它還包括適用于Go、Java、JavaScript、.NET和Python的語言特定的SDK。這些 SDK 通過類型化的語言 API 公開 Dapr 構建基塊中的功能,例如保存狀態、發布事件或創建 Actor,而不是調用 http/gRPC API。這使開發人員能夠用他們選擇的語言編寫無狀態和有狀態函數與?Actor 的組合。由于這些 SDK 共享 Dapr 運行時,您甚至可以獲得跨語言執行組件和函數支持!
此外,Dapr 還可以與任何開發框架集成。例如,在 Dapr .NET SDK 中,您會發現 ASP.NET Core 的集成,它帶來了有狀態的路由控制器,可以響應來自其他服務的pub/sub事件,使ASP.NET Core 成為更好的構建微服務 Web 應用程序的框架。
參考并翻譯:https://github.com/dapr/dapr/blob/master/README.mdhttps://cloudblogs.microsoft.com/opensource/2019/10/16/announcing-dapr-open-source-project-build-microservice-applications/完。
總結
以上是生活随笔為你收集整理的微软开源微服务运行时Dapr,赋能云原生应用开发的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 北京Dotnet分享会 || 精英论坛第
- 下一篇: VSCode开发.NETCore项目入门