通過Dapr實現一個簡單的基於.net的微服務電商系統(四)——一步一步教你如何擼Dapr之訂閱發布


  之前的章節我們介紹了如何通過dapr發起一個服務調用,相信看過前幾章的小伙伴已經對dapr有一個基本的了解了,今天我們來聊一聊dapr的另外一個功能——訂閱發布

目錄:
一、通過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的微服務電商系統(十七)——服務保護之動態配置與熱重載

附錄:(如果你覺得對你有用,請給個star)
一、電商Demo地址

二、通訊框架地址

  慣例我們還是再老生常談一下什么是訂閱發布,訂閱發布是根據設計模式之觀察者模式發展出來的一種軟件系統設計思想,它的核心是指“多個對象間存在一對多的依賴關系,當一個對象的狀態發生改變時,所有依賴於它的對象都得到通知並被自動更新”。假設一個系統有ABC三個模塊其中BC依賴於A,當A進行改變后需要A主動調用BC進行相應改變,而觀察者模式則將A的控制權剝離,A改變之后只是發送一個事件給消息總線“我改變了”,BC通過預先訂閱該主題而獲取到A的狀態變化,再進行自身的狀態變更。

強耦合調用模式

通過消息中間件訂閱發布模式

  聰明的同學應該發現了,通過訂閱發布其實我們是將以往強耦合的ABC通過巧妙的控制權轉移的方式進行了解耦,由之前的BC依賴於A改為了BC依賴於消息組件,通過消息組件接受到A的消息后進行分發,這樣設計系統的目的當然有好有壞,好處是這會大大提高A的吞吐量,假設以往操作ABC總耗時300ms平均單個操作耗時100ms,通過解耦后A耗時100ms后就可以馬上返回線程。那壞處是什么呢,由於對BC進行了解耦往往狀態的一致性就得不到保障了。當ABC處於同一個粗粒度的原子操作里(比如數據庫事務操作、比如lock鎖),我們很容易控制ABC的強一致性,ABC有一個操作失敗可以很輕松的進行回滾而不用影響我們持久化設備的數據一致。另外由於需要依賴第三方中間件,整個系統的健壯性是會有一定影響的。另外還需要考慮訂閱方消費失敗、異常后如何處理。關於這部分內容這里我們就不展開了,如果大家確實感興趣,推薦大家看看國內開源作者@楊曉東寫的.netcore分布式一致性解決方案CAP,地址:https://github.com/dotnetcore/cap

  OK,老生常談的部分嘮完,咱今天就來嘮嘮在Dapr中如何實現訂閱發布的。通過上面的部分大家應該知道如果要實現一個進程間的訂閱發布系統,我們需要准備很多東西,其中一個是事件總線,事件總線的作用是讓事件發布者可以通過該模塊進行事件發布。第二個需要選型一個消息組件,第三需要訂閱器對訂閱特定類型組件的技術支持。由於每一種組件其協議和接口實現方式都不同,在傳統的訂閱發布設計中我們往往需要對某種特定類型的消息組件在基礎設施層進行相應的SDK集成,通過為業務層提供事件總線接口和訂閱接口來進行技術解耦。就算做到了業務系統中不耦合技術實現,往往我們也很難替換消息組件。而Dapr在這方面為開發者集成了相當一部分的主流訂閱發布組件(通過該支持列表可預覽支持)。同時在業務層面是完全基於http+謂詞的形式來實現訂閱發布的。這就大大降低了引入SDK產生的成本。

  訂閱發布的API如下:

POST http://localhost:<daprPort>/v1.0/publish/<pubsubname>/<topic>[?<metadata>]
GET http://localhost:<appPort>/dapr/subscribe

  稍微說一下這兩個接口的含義,第一個接口告訴sidecar,我們將會調用某個已申明的類型為pubsub的component發送我們的事件到特定的topic

  第二個接口是告訴sidecar我們當前這個服務會訂閱哪些topic,我們提供的訂閱器入口地址是什么,我們只接受哪一個component發布的數據

  也就是說和服務調用一樣,我們只需要一個weapi+httpclient就可以實現一個訂閱發布模式而,其他的一切都交給dapr好了。

  現在我們來看看如何實現它,首先我們還是需要選一個特定的訂閱發布組件,這里我就選擇redis,通過redis5.0新增的stream來做訂閱發布。搭建redis這里不贅述,搭建好之后,我們需要創建一個dapr的特定CRD Component來申明引用該組件,其申明yaml文件如下

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: pubsub
spec:
  type: pubsub.redis
  version: v1
  metadata:
  - name: redisHost
    value: redis.infrastructure.svc.cluster.local:6379

  其中的type是由Dapr預定義的,可以參考這里,不要隨意改變。metadata是對組件的一組描述包括其地址、賬號密碼等等,由於是演示這里我就直接使用k8s創建了一個無密碼的redis pod並暴露其6379端口到svc。當我們創建好並通過kubectl apply -f x.yaml后,可以在dashboard的Componsents頁面觀察是否已經創建成功

  基礎設施准備完畢,接下來就是打開我們的項目看看如何實現訂閱發布了。首先我們還是要把上一章的解決方案打開,上一章不是通過client發起一個對service的調用嗎,今天我們反着來演示,我們在client創建一個訂閱器,當clientsample調用servicesample時讓servicesample發布一個事件,由該訂閱器訂閱並打印出文本到控制台。

  首先我們在clientsample創建一個訂閱器,訂閱器類必須繼承ieventhandle接口,其訂閱方法體必須添加EventHandlerFunc注解並申明需要訂閱的主題(topic),訂閱器接收參數必須以EventHandleRequest<T>的方式接收,否則反序列化器可能會收不到請求。最后ack必須以DefaultEventHandlerResponse.Default的方式返回,否則事件總線會認為本次訂閱器消費失敗,會重復推送。

   需要在我們的hostbuilder里注冊這個對象到ioc容器:

  接着我們在RPC接口項目創建事件Data HelloEventData,其中之包含一個演示用的words字段(圖略)。

  接下來我們在上一章的HelloServiceImpl中注入一個事件總線,並發送事件:

 

   一切就緒,我們重新按照上一章的內容打包並部署,然后開啟postman和控制台日志觀看結果,可以看到我們的clientsample發起一個服務調用后,我們的serversample回調並發送了事件,而clientsample成功訂閱到了該事件並消費掉了。

 

   今天的分享到此為止,demo只是對dapr訂閱發布最基礎功能的演示,真正到生產環境還需要客服諸多問題來提高系統健壯,系統建設是一個長期持續的過程。歡迎大家評論區留言討論~ 下期我們將講一下dapr里如何做狀態管理以及actor模型

  


免責聲明!

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



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