Dapr 知多少 | 分布式應(yīng)用運(yùn)行時(shí)

Intro

Dapr 官方團(tuán)隊(duì)已于最近(2021.2.17)正式發(fā)布Dapr v1.0,Dapr已正式生產(chǎn)可用,可以部署到自托管環(huán)境或 Kubernetes 集群。對(duì)于絕大多數(shù)開發(fā)者來說,想必對(duì)Dapr只是有所耳聞,而具體是什么(What),可以解決什么樣的問題(Why&How),有怎樣的應(yīng)用場(chǎng)景(Where),并不知悉。本文就嘗試簡(jiǎn)要梳理下Dapr,并嘗試回答以上問題。

What's Dapr

Distributed Application Runtime. An event-driven, portable runtime for building microservices on cloud and edge.
分布式應(yīng)用運(yùn)行時(shí)。一個(gè)事件驅(qū)動(dòng)、可移植的運(yùn)行時(shí)用于在云上和邊緣計(jì)算上構(gòu)建微服務(wù)。

以上是Dapr官方GitHub倉庫上對(duì)Dapr的簡(jiǎn)介。文字雖短,口氣卻很大,因?yàn)槠涑撕w了當(dāng)前所有的技術(shù)熱點(diǎn):分布式、云、微服務(wù),還自我標(biāo)榜為:分布式應(yīng)用運(yùn)行時(shí)。分布式應(yīng)用我們或多或少有些了解,運(yùn)行時(shí)也聽到不少,比如常見的語言運(yùn)行時(shí):Java 運(yùn)行時(shí),.NET 運(yùn)行時(shí),Go 運(yùn)行時(shí)等等,那運(yùn)行時(shí)又是什么東西?簡(jiǎn)要來說:運(yùn)行時(shí)是程序運(yùn)行依賴的執(zhí)行環(huán)境。以.NET 程序運(yùn)行時(shí)CLR為例,它為.NET應(yīng)用程序提供了一個(gè)托管的代碼執(zhí)行環(huán)境負(fù)責(zé)應(yīng)用程序在整個(gè)執(zhí)行期間的內(nèi)存管理、線程管理、安全管理、遠(yuǎn)程管理、即時(shí)編譯等。

那分布式應(yīng)用運(yùn)行時(shí),就是提供分布式應(yīng)用運(yùn)行所依賴的的執(zhí)行環(huán)境。那運(yùn)行分布式應(yīng)用需要哪些環(huán)境依賴呢?回答這個(gè)問題,我們要先思考開發(fā)分布式應(yīng)用的挑戰(zhàn)是什么?明確了挑戰(zhàn),那就找到了答案。

從單機(jī)到分布式,是追求更快和更高的性能,但也帶來了更多的不確定性。比如,不確定計(jì)算機(jī)何時(shí)異常,不確定磁盤何時(shí)損壞,不確定網(wǎng)絡(luò)通信的延遲,也不確定消息是否被正常消費(fèi)。這些不確定性構(gòu)成了分布式應(yīng)用的挑戰(zhàn),簡(jiǎn)而言之:

  1. 異構(gòu)的機(jī)器與網(wǎng)絡(luò):穩(wěn)定性問題
  2. 普遍的節(jié)點(diǎn)故障:可靠性問題
  3. 不可靠的網(wǎng)絡(luò):一致性問題

面對(duì)這些挑戰(zhàn),業(yè)界提出了諸多的分布式理論、協(xié)議,如CAP定理,BASE理論,一致性協(xié)議2PC/3PC/ZAB,來保證系統(tǒng)的正常運(yùn)行。雖然問題貌似是有了解決方案,但是應(yīng)用的復(fù)雜度升高了。應(yīng)用除了需要實(shí)現(xiàn)業(yè)務(wù)需求,還要兼顧非業(yè)務(wù)需求,集成諸如服務(wù)發(fā)現(xiàn)、負(fù)載均衡、失效轉(zhuǎn)移、動(dòng)態(tài)擴(kuò)容、數(shù)據(jù)分片、調(diào)用鏈路監(jiān)控等分布式系統(tǒng)的核心功能,對(duì)應(yīng)用有很強(qiáng)的侵入性,這就是以Spring Cloud為代表的微服務(wù)框架的常見做法。

那如何解決侵入性的問題呢?這個(gè)問題隨著容器編排技術(shù)的成熟有了新的解法。Kubernetes可以不侵入應(yīng)用層,在容器層解決問題,比如K8S Service就具有服務(wù)發(fā)現(xiàn)、負(fù)載均衡的能力,HPA具有動(dòng)態(tài)擴(kuò)容的能力。隨著K8S的快速發(fā)展,云原生的概念,也就越來越深入人心,那如何利用好K8S提供的基座能力,將更多的分布式能力下沉,讓應(yīng)用開發(fā)回歸業(yè)務(wù)呢?其中Service Mesh提出的Sidecar模式,就很好的解決了微服務(wù)架構(gòu)中網(wǎng)絡(luò)通信的問題。Sidecar主要就是用來處理諸如服務(wù)發(fā)現(xiàn)、負(fù)載均衡、請(qǐng)求熔斷等一系列非業(yè)務(wù)需求,應(yīng)用在部署時(shí)動(dòng)態(tài)插入Sidecar,服務(wù)間的通信通過Sidecar進(jìn)行代理,以完成對(duì)服務(wù)間網(wǎng)絡(luò)通信的接管。

到這里,微服務(wù)開發(fā)在Service Mesh的幫助下,已經(jīng)漸漸回歸業(yè)務(wù)本身,讓更多的開發(fā)者看到了一絲曙光。It's enough? 來看下Bilgin Ibryam在Multi-Runtime Microservices Architecture文章中提及的分布式應(yīng)用的四大需求:

分布式應(yīng)用的四大需求

從上圖可以看出,除了網(wǎng)絡(luò)(Networking)外,生命周期(Lifecycle)、狀態(tài)(State)、捆綁(Binding)也是分布式應(yīng)用要解決的問題之一。網(wǎng)絡(luò)問題可以借由Service Mesh 比如Istio予以解決。那其他三個(gè)該如何解決呢?又要應(yīng)用自行開發(fā)集成嗎?顯然不符合應(yīng)用回歸業(yè)務(wù)本身的訴求。這時(shí),Dapr登場(chǎng)了,Dapr提出的分布式應(yīng)用運(yùn)行時(shí)就是實(shí)現(xiàn)了以上四個(gè)需求并將其下沉作為分布式應(yīng)用的運(yùn)行環(huán)境。

簡(jiǎn)而言之:Dapr將分布式能力進(jìn)行封裝下沉作為運(yùn)行時(shí)以簡(jiǎn)化分布式應(yīng)用開發(fā)的技術(shù)復(fù)雜度。

How Dapr Works

那Dapr如何簡(jiǎn)化分布式應(yīng)用的開發(fā)呢?下面我們來看一看Dapr的主要特性。


Any language, any framework, anywhere

一圖勝千言:Dapr通過以HTTP/gRPC API這種與語言無關(guān)的方式暴露封裝的分布式能力供應(yīng)用調(diào)用,從而支持使用任意語言或框架進(jìn)行開發(fā)集成。目前官方已經(jīng)提供了Go,Node,Python,.NET,Java, C++,PHP,Rust,Javascript的Sdk,簡(jiǎn)化Dapr的集成。

其中Dapr的核心構(gòu)建塊(Building Block)就是用來提供各種不同的分布式能力,我們來分別看一看。


Building Block

1. Service-to-service invocation(服務(wù)調(diào)用)
提到跨服務(wù)方法調(diào)用,這個(gè)大家肯定會(huì)想,這簡(jiǎn)單啊,不就是服務(wù)暴露API就好了嘛。是,但不完全是。比如nodeapp暴露了一個(gè)API:http://10.0.0.2:8000/neworder,按照傳統(tǒng)的方式,直接HTTP POST這個(gè)API訪問就得了,但在Dapr中,其提供了服務(wù)間方法調(diào)用的接口規(guī)范,需要按照
POST/GET/PUT/DELETE http://localhost:<daprPort>/v1.0/invoke/<appId>/method/<method-name>的格式進(jìn)行訪問。那假設(shè)pythonapp需要訪問nodeapp的方法,就需要POST一個(gè)請(qǐng)求到http://localhost:3500/v1.0/invoke/nodeapp/method/neworder。你可能會(huì)想為何多此一舉呢?此舉的意義何在呢?目的很簡(jiǎn)單,就是為了實(shí)現(xiàn)對(duì)服務(wù)間網(wǎng)絡(luò)通信的控制以完成諸如服務(wù)發(fā)現(xiàn)、流量控制、重試熔斷、安全訪問等,而這相關(guān)的網(wǎng)絡(luò)控制功能就是集成在Dapr的Sidecar中,以對(duì)應(yīng)用透明的方式集成進(jìn)來的。整體的服務(wù)調(diào)用流程如下圖所示:

服務(wù)間調(diào)用

PS:如果對(duì)Istio熟悉的同學(xué)需要注意,二者雖然都是通過Sidecar的模式進(jìn)行網(wǎng)絡(luò)控制,但二者是有有區(qū)別的。Dapr是以API的方式,而Istio是以代理的方式(不改變HTTP請(qǐng)求URI)。

2. State management(狀態(tài)管理)
在進(jìn)行微服務(wù)開發(fā)時(shí),繞不開的話題就是服務(wù)間的狀態(tài)共享、并發(fā)一致性問題。對(duì)于狀態(tài)共享,你可能會(huì)說,各個(gè)服務(wù)連接到同一個(gè)Redis實(shí)例就OK了。是,但不得不考慮潛在的更新沖突的問題。Dapr 以更友好的HTTP API的方式進(jìn)行狀態(tài)的存儲(chǔ)和讀取,同時(shí)支持通過ETags進(jìn)行并發(fā)控制,并支持通過選項(xiàng)設(shè)置并發(fā)和一致性行為。

  • 存儲(chǔ):POST http://localhost:<daprPort>/v1.0/state/<storename>
  • 讀取:GET http://localhost:<daprPort>/v1.0/state/<storename>/<key>
  • 刪除:DELETE http://localhost:<daprPort>/v1.0/state/<storename>/<key>

以下是保存狀態(tài)的舉例:

  • concurrency用于指定并發(fā)選項(xiàng):first-write-wins/last-write-wins(以第一次寫入為準(zhǔn)/以最后一次寫入為準(zhǔn)),默認(rèn)以最后一次寫入為準(zhǔn)。
  • consistency用于指定一致性選項(xiàng):strong/eventual(強(qiáng)一致性/最終一致性),默認(rèn)為最終一致性。
curl -X POST http://localhost:3500/v1.0/state/starwars \
  -H "Content-Type: application/json" \
  -d '[
        {
          "key": "weapon",
          "value": "DeathStar",
          "etag": "xxxxx",
          "options": {
            "concurrency": "first-write",
            "consistency": "strong"
          }
        }
      ]'

目前支持使用Azure CosmosDB、 Azure SQL Server、 PostgreSQL,、AWS DynamoDB、Redis 作為狀態(tài)存儲(chǔ)介質(zhì)。

3. Publish and subscribe(消息發(fā)布及訂閱)
發(fā)布訂閱模式,老生常談了,主要是用于微服務(wù)間基于消息進(jìn)行相互通信。你可能也會(huì)說,這也要拿出來說,我搞個(gè)RabbitMQ/RocketMQ就是了。是的,但我還是要說,Dapr提供了一致性的消息發(fā)布、訂閱API,而無需關(guān)注具體使用的是何種Message Broker,從而和底層基礎(chǔ)設(shè)施解耦。

  • 發(fā)布:POST http://localhost:<daprPort>/v1.0/publish/<pubsubname>/<topic>[?<metadata>]
  • 獲取可訂閱主題:GET http://localhost:<appPort>/dapr/subscribe
  • 訂閱:POST http://localhost:<appPort>/<path>
發(fā)布訂閱

4. Resource bindings and triggers (資源綁定及事件觸發(fā))
Dapr的Bindings與Azure Functions很類似,其是建立在事件驅(qū)動(dòng)架構(gòu)的基礎(chǔ)之上的。通過建立觸發(fā)器與資源的綁定,可以從任何外部源(例如數(shù)據(jù)庫,隊(duì)列,文件系統(tǒng)等)接收和發(fā)送事件,而無需借助消息隊(duì)列,即可實(shí)現(xiàn)靈活的業(yè)務(wù)場(chǎng)景。Dapr的Bindings分為兩種:

  1. Input Bindings(輸入綁定):當(dāng)外部資源的事件發(fā)生時(shí),借助輸入綁定,你的應(yīng)用即可通過特定的API:POST http://localhost:<appPort>/<name>收到外部資源的事件,用于處理特定邏輯。
  2. Output Bindings(輸出綁定):輸出綁定允許你調(diào)用外部資源。比如,在訂單處理場(chǎng)景中,在訂單創(chuàng)建成功后,可以將訂單信息通過Dapr的綁定API:POST/PUT http://localhost:<daprPort>/v1.0/bindings/<name>輸出到Kafka特定隊(duì)列上。
資源綁定及事件觸發(fā)

5. Actors
Dapr中的Actor模型,和Orleans的Virtual Actor一脈相傳,之前寫過一篇文章Orleans 知多少 | .NET Core 分布式框架介紹過。簡(jiǎn)單來講:Actor模型 = 狀態(tài) + 行為 + 消息。一個(gè)應(yīng)用/服務(wù)由多個(gè)Actor組成,每個(gè)Actor都是一個(gè)獨(dú)立的運(yùn)行單元,擁有隔離的運(yùn)行空間,在隔離的空間內(nèi),其有獨(dú)立的狀態(tài)和行為,不被外界干預(yù),Actor之間通過消息進(jìn)行交互,而同一時(shí)刻,每個(gè)Actor只能被單個(gè)線程執(zhí)行,這樣既有效避免了數(shù)據(jù)共享和并發(fā)問題,又確保了應(yīng)用的伸縮性。

Actor模型大大簡(jiǎn)化了并發(fā)編程的復(fù)雜度,Dapr在Actor運(yùn)行時(shí)中提供了許多功能,包括并發(fā)控制,狀態(tài)管理,生命周期管理如Actor的激活/停用以及用于喚醒Actor的Timer(計(jì)時(shí)器)和Reminder(提醒)。這些功能同樣也是通過API的方式予以提供。

  • 調(diào)用Actor 方法:POST/GET/PUT/DELETE http://localhost:3500/v1.0/actors/<actorType>/<actorId>/method/<method>
  • 創(chuàng)建 Timer:POST/PUT http://localhost:3500/v1.0/actors/<actorType>/<actorId>/timers/<name>
  • 創(chuàng)建 Reminder:POST/PUT http://localhost:3500/v1.0/actors/<actorType>/<actorId>/reminders/<name>

6. Observability(遙測(cè))
Dapr記錄指標(biāo),日志,鏈路以調(diào)試和監(jiān)視Dapr和用戶應(yīng)用的運(yùn)行狀況。 Dapr支持分布式跟蹤,其使用W3C跟蹤上下文標(biāo)準(zhǔn)和開放式遙測(cè)技術(shù),可以輕松地診斷在生產(chǎn)環(huán)境中服務(wù)間的網(wǎng)絡(luò)調(diào)用,并發(fā)送到不同的監(jiān)視工具,如Prometheus。

7. Secrets(安全)
Dapr 提供了Secret管理,不過不同于K8S中的Secret,其支持與公有云和本地的Secret存儲(chǔ)集成,以供應(yīng)用檢索使用。

What Can We Do With Dapr

了解了Dapr是什么,以及其提供的特性,那Dapr的應(yīng)用場(chǎng)景就一目了然了。也就是官網(wǎng)首頁的Slogan:Simplify cloud-native application development--Focus on your application’s core logic and keep your code simple and portable。
簡(jiǎn)化云原生應(yīng)用的開發(fā),確保應(yīng)用專注于業(yè)務(wù),并保證代碼簡(jiǎn)單可移植。

因此,在考慮云原生應(yīng)用開發(fā)的技術(shù)選型時(shí),盡情嘗試吧,目前在國內(nèi)阿里云也已采用。

Last

在云原生如火如荼發(fā)展之際,Dapr V1.0 的正式發(fā)布,為開發(fā)者指明了云原生時(shí)代微服務(wù)的開發(fā)方向。相信Dapr 在未來的微服務(wù)架構(gòu)選型中必將占有一席之地!

參考:
什么是分布式系統(tǒng),如何學(xué)習(xí)分布式系統(tǒng)
Mecha:將Mesh進(jìn)行到底

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,501評(píng)論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,673評(píng)論 3 429
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,610評(píng)論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,939評(píng)論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,668評(píng)論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,004評(píng)論 1 329
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,001評(píng)論 3 449
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,173評(píng)論 0 290
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,705評(píng)論 1 336
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,426評(píng)論 3 359
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,656評(píng)論 1 374
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,139評(píng)論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,833評(píng)論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,247評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,580評(píng)論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,371評(píng)論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,621評(píng)論 2 380

推薦閱讀更多精彩內(nèi)容