Dapr 交通流量控制示例

張善友發表於2021-02-14

前面幾篇文章都是從大的方面給大家分享Dapr 能幫助我們解決什麼問題,微軟從開源到1.0 也是經過2年的時間開發,因此我寫了這幾篇文章也只能是帶領大家對Dapr 有個大的印象,真正對Dapr 有認知上的直觀感受還是要從示例程式碼中去體驗了,因此今天給大家分享一個交通控制的示例程式,幫助大家對Dapr 的理解更進一步。 2020年的中國.NET開發者峰會朱永光有專門介紹了Dapr,他的演講中也引用了這個示例,朱永光的演講視訊請看:https://live.csdn.net/room/dotnetconf/1v1d3YbH 。這個示例是github上的一位荷蘭的 MVP 寫的 https://github.com/EdwinVW/dapr-traffic-control ,我把它翻譯成中文介紹給大家,示例的場景是用於使用 Dapr 模擬流量控制系統。對於此示例,我們將使用超速攝像頭裝置,該裝置可在多個荷蘭高速公路上找到。在某條高速公路的整個長度上,將測量車輛的平均速度,如果該平均速度高於該高速公路上的超速極限,則該車輛的駕駛員會收到超速罰單。

概述

這是我在此示例中模擬的虛構設定的概述:

speed-trap-overview

每個泳道有1個進入相機和1個離開相機。當汽車通過入口攝像機時,將註冊該汽車的車牌號。

在後臺,通過呼叫汽車部門的Dvd服務(DMV(或荷蘭語中的RDW))獲取有關車輛的資訊。

當汽車通過出口攝像機時,系統會對其進行記錄。然後,系統根據進出時間戳記計算汽車的平均速度。如果檢測到超速違規,則會向中央司法徵收機構傳送一條訊息-CJCA(或荷蘭語中的CJIB)會將超速罰單傳送給車輛駕駛員。

模擬

為了在程式碼中進行模擬,可以使用以下服務:

services

  • Simulation 是一個 .NET Core 控制檯程式模擬過路車.
  • TrafficControlService 是一個ASP.NET Core的WebAPI的應用程式,提供2個端點: EntrycamExitCam.
  • Government 服務是一個ASP.NET Core的WebAPI的應用程式,提供2個端點:RDW(檢索車輛資訊)和CJIB(用於傳送超速罰單)

下面的序列圖描述了模擬的工作方式:

sequence

  1. Simulation 模擬生成汽車車牌號併傳送一個訊息 VehicleRegistered (包含汽車車牌號, 一個隨機的泳道 (1-3) 和時間戳) 到服務 TrafficControlService 的端點 EntryCam .
  2. TrafficControlService 呼叫 GovernmentService 服務的 RDW 的端點 檢索對應的汽車號牌車輛的品牌和型號
  3. TrafficControlService 在 state-store 裡 儲存VehicleState (車輛資訊和進入時間戳) .
  4. 一些隨機間隔之後, Simulation 傳送 VehicleRegistered 訊息到 TrafficControlService 服務的端點 ExitCam (含有在步驟1中產生的汽車號牌,隨機出口車道(1-3)和出口時間戳).
  5. TrafficControlService 從state-store中獲取 VehicleState .
  6. TrafficControlService使用 進入和出去的時間戳 計算平均速度.
  7. 如果平均速度高於速度極限時, TrafficControlService 將傳送 SpeedingViolationDetected 訊息 (包含車輛的車票,路面的識別符號,高速化違反KMH和違規的時間戳) 到 GovernmentService 的端點 CJIB .
  8. GovernmentService 計算超速違章罰款和模擬傳送超速票給車主

在執行過程中,此序列中描述的所有操作都會記錄到控制檯,因此您可以按照流程進行操作。

Dapr

此示例使用 Dapr 實現應用程式的多個方面。在下面的圖中,看到的是架構概述

dapr-setup

  1. 對於通訊訊息, 使用 釋出和訂閱 構建塊來實現.
  2. 對於 request/response 型的服務通訊 ,使用 服務到服務呼叫 構建塊來實現.
  3. 對於車輛狀態的儲存,使用 狀態管理 構建塊來實現.
  4. 服務GovernmentService 中的 VehicleInfoController 有一個操作 GetVehicleInfo 使用VehicleInfoRepository 獲取車輛資料. 這個 repository 的建構函式需要一個連線字串作為引數。 這個連線字串儲存在一個secrets 檔案裡。 服務 GovernmentService 使用 secrets management 構建塊帶一個本地檔案元件來獲取連線字串.

在這個例子裡, Redis 元件既用於狀態管理,又用於 pub/sub.

使用 Dapr 的 self-hosted 模式執行示例

執行以下步驟以在自託管模式下執行示例應用程式:

  1. 確保你已經在你的計算機上 安裝Dapr的 self-hosted 模式,具體參考文件 Dapr documentation,中文的請看朱永光寫的 Dapr微服務應用開發系列1:環境配置.

  2. 開啟三個獨立的命令列視窗.

  3. 在第一個命令列Shell, 切換當前路徑到 倉庫 的 src/GovernmentService 資料夾 執行下面的命令列(使用Dapr CLI)執行 GovernmentService:

    dapr run --app-id governmentservice --app-port 6000 --dapr-grpc-port 50002 --config ../dapr/config/config.yaml --components-path ../dapr/components dotnet run
    
  4. 在第二個命令列Shell, 切換當前路徑到倉庫的 src/TrafficControlService 資料夾 執行下面的命令(使用Dapr CLI) TrafficControlService:

    dapr run --app-id trafficcontrolservice --app-port 5000 --dapr-grpc-port 50001 --config ../dapr/config/config.yaml --components-path ../dapr/components dotnet run
    
  5. 在第三個命令列Shell, 切換當前路徑到倉庫的 src/Simulation 資料夾 執行下面的命令執行 Simulation:

    dapr run --app-id simulation --dapr-grpc-port 50003 --config ../dapr/config/config.yaml --components-path ../dapr/components dotnet run
    

現在,您應該會看到每個 shell 中的日誌記錄,類似於如下所示的日誌記錄:

Simulation:

logging-simulation

TrafficControlService:

logging-trafficcontrolservice

GovernmentService:

logging-governmentservice

相關文章