如果說Actor是dapr有狀態服務的內部體現的話,那綁定應該是dapr對serverless這部分的體現了。我們可以通過綁定極大的擴展應用的能力,甚至未來會成為serverless的基礎。最開始接觸dapr的時候,會在其官方首頁看到這么一句話“Dapr is a portable, serverless, event-driven runtime ” 一個可移植的,服務器的,事件驅動的運行時。可移植很容易理解,事件驅動也有所體現。那這個無服務器(serverless)呢?今天我們就講講dapr是如何serverless的。
目錄:
一、通過Dapr實現一個簡單的基於.net的微服務電商系統
二、通過Dapr實現一個簡單的基於.net的微服務電商系統(二)——通訊框架講解
三、通過Dapr實現一個簡單的基於.net的微服務電商系統(三)——一步一步教你如何擼Dapr
四、通過Dapr實現一個簡單的基於.net的微服務電商系統(四)——一步一步教你如何擼Dapr之訂閱發布
五、通過Dapr實現一個簡單的基於.net的微服務電商系統(五)——一步一步教你如何擼Dapr之狀態管理
六、通過Dapr實現一個簡單的基於.net的微服務電商系統(六)——一步一步教你如何擼Dapr之Actor服務
七、通過Dapr實現一個簡單的基於.net的微服務電商系統(七)——一步一步教你如何擼Dapr之服務限流
八、通過Dapr實現一個簡單的基於.net的微服務電商系統(八)——一步一步教你如何擼Dapr之鏈路追蹤
九、通過Dapr實現一個簡單的基於.net的微服務電商系統(九)——一步一步教你如何擼Dapr之OAuth2授權 && 百度版Oauth2
十、通過Dapr實現一個簡單的基於.net的微服務電商系統(十)——一步一步教你如何擼Dapr之綁定
十一、通過Dapr實現一個簡單的基於.net的微服務電商系統(十一)——一步一步教你如何擼Dapr之自動擴/縮容
十二、通過Dapr實現一個簡單的基於.net的微服務電商系統(十二)——istio+dapr構建多運行時服務網格
十三、通過Dapr實現一個簡單的基於.net的微服務電商系統(十三)——istio+dapr構建多運行時服務網格之生產環境部署
十四、通過Dapr實現一個簡單的基於.net的微服務電商系統(十四)——開發環境容器調試小技巧
十五、通過Dapr實現一個簡單的基於.net的微服務電商系統(十五)——集中式接口文檔實現
十六、通過Dapr實現一個簡單的基於.net的微服務電商系統(十六)——dapr+sentinel中間件實現服務保護
十七、通過Dapr實現一個簡單的基於.net的微服務電商系統(十七)——服務保護之動態配置與熱重載
十八、通過Dapr實現一個簡單的基於.net的微服務電商系統(十八)——服務保護之多級緩存
十九、通過Dapr實現一個簡單的基於.net的微服務電商系統(十九)——分布式事務之Saga模式
二十、通過Dapr實現一個簡單的基於.net的微服務電商系統(二十)——Saga框架實現思路分享
附錄:(如果你覺得對你有用,請給個star)
一、電商Demo地址
serverless還是有必要提兩嘴,知道的同學可以直接略過。直接翻開CNCF對serverless的定義:“Serverless 是指構建和運行不需要服務器管理的應用程序的概念”,這個概念說起來非常的大哈,實際上根據各家雲平台提供的serverless服務來看,其主要作用是將開發者的應用程序和服務器操作系統環境進行了隔離,讓開發人員不再關心服務器(而不是完全不需要服務器!),只需要通過雲函數的方式編寫特定的業務代碼即可對外提供服務。每一個函數會被編譯成一個容器鏡像,當外部請求過來時Serverless會激活這個函數運行我們的鏡像實例,當請求量激增時,Serverless會幫我們橫向擴容多個實例來抗住請求。當一段時間沒有請求后,Serverless又會幫我們逐步縮容雲函數實例直到實例變為0。這樣當沒有請求時的大部分時間里雲服務商不會收取你的CPU/內存/網絡的費用,僅僅收取一個磁盤費用(托管雲函數鏡像需要)。這里面涉及到兩個問題,一個是雲函數的擴容/縮容機制,一個就是雲函數本身如何調用其他服務比如我要持久化數據/發送郵件/寫短信/訂閱?在各家雲商提供的Serverless架構里,擴容縮容自然是通過k8s來實現的,而調用外部服務則被封裝成了自家的雲服務(比如阿里雲可以調用RDS讀寫數據庫。調用OSS讀寫對象,相應的自家的Serverless架構都提供了相關函數的功能)。
那Dapr如何實現Serverless的呢?但凡熟悉k8s的同學應該對自動化擴容、縮容這部分比較容易理解,其基於k8s的HPA機制運作,dapr通過對KEDA集成實現了這部分的功能,不過這不是今天我們要講的重點。另外一個問題,雲函數如何調用外部服務?這就是今天我們要講的重點——綁定機制的實現。dapr的綁定提供了非常多的外部組件訪問支持,訪問這個列表可以查詢具體的支持情況,隨着dapr的逐步迭代我相信這個列表還會逐步增加最終將覆蓋主流的大部分我們會用到的服務組件。這樣最終我們將無需和某個雲服務商的Serverless做技術綁定,只需要dapr即可實現Serverless!而我們的應用程序將會變得非常輕量級,幾乎不需要集成特定組件sdk(比如數據庫訪問sdk、sms短信sdk、ios消息推送sdk等等等等)。只需要提供一個對外服務的restapi,內部完成業務操作后其余的部分交給dapr幫我們完成即可。
今天就來看看我們通過dapr是如何完成對數據庫訪問的,這里依然使用我們的eshop進行舉例,在eshop中我們試着訪問我們的用戶數據庫的Account表。首先我們需要創建一個bingding類型的component,比較簡單只需要申明這是一個bindings.postgres的Component,包含一個鏈接字符串指向我們的infrastructure下的postgres這個k8s service。
apiVersion: dapr.io/v1alpha1 kind: Component metadata: name: accountpostgres namespace: dapreshop spec: type: bindings.postgres version: v1 metadata: - name: url value: user=postgres password=Mytestpwd#123 host=postgres.infrastructure port=5432 dbname=AccountDb sslmode=disable
接着我們編寫代碼來實現對該component進行訪問,通過查詢Account獲取用戶信息並打印到postman中
首先我們實現一個簡單的http請求用於查詢我們的綁定服務:
public class HttpHelper { private static async Task<string> GetResultAsync(string componentName, string sql) { var req = new HttpRequestMessage(HttpMethod.Post, $"http://localhost:3500/v1.0/bindings/{componentName}"); req.Content = new StringContent(JsonSerializer.Serialize(new { operation = "query", metadata = new { sql = sql } })); var resp = await new HttpClient().SendAsync(req); if (resp.IsSuccessStatusCode) { var result = await resp.Content.ReadAsStringAsync(); return result; } else throw new NotSupportedException($"component無效或不支持的sql查詢語句"); } public static async Task<List<T>> GetResultAsync<T>(string componentName, string sql) where T:class { var str = await GetResultAsync(componentName, sql); var obj = JsonSerializer.Deserialize<List<object>>(str); var result = new List<T>(); foreach (JsonElement item in obj) { result.Add(AccountConvetor(item) as T); } return result; } static Infrastructure.PersistenceObject.Account AccountConvetor(JsonElement item) { var t = new Infrastructure.PersistenceObject.Account(); t.Id = Guid.Empty;//由於不知名的原因uuid的鍵讀取出來的值並不是uuid而是一個數組 t.LoginName = item[1].GetString(); t.Password = item[2].GetString(); t.NickName = item[3].GetString(); t.State = (Domain.Enums.AccountState)item[4].GetInt32(); return t; } }
接着在AccountQueryService中創建一個GetAccountListByDapr用於暴露該服務到外部:
[AuthenticationFilter(false)] public async Task<ApiResult> GetAccountListByDapr() { var result = await HttpHelper.GetResultAsync<Infrastructure.PersistenceObject.Account>("accountpostgres", "select * from public.\"Account\""); return ApiResult.Ok(result); }
然后我們通過postman發起一個訪問:
可以看到成功的通過httpclient調用dapr獲取到了數據庫里的數據。這里還有些小的問題比如我的id是一個uuid格式,通過dapr讀取出來變成了一個數組,還不知道是什么原因。不過大體思路就是這樣了,至少目前通過dapr可以和阿里雲oss、ios消息推送、mysql、kafka、mqtt、postgresql、rabbitmq、redis等等等等我們常用的耳熟能詳的服務/組件進行集成,而你唯一需要關心的只是通過訪問dapr的api來發送操作/獲取數據僅此而已,dapr將組件集成的復雜度從應用層面遷移后,對於開發者來講通過dapr要實現一個serverless至少從技術層面來看已經沒有多少阻礙了。好了,今天的分享就到這里~