Dapr 交通控制示例

前面幾篇文章都是從大的方面給大家分享Dapr 能幫助我們解決什麼問題,微軟從開源到1.0 也是經過2年的時間開發,因此我寫了這幾篇文章也只能是帶領大家對Dapr 有個大的印象,真正對Dapr 有認知上的直觀感受還是要從示例代碼中去體驗了,因此今天給大家分享一個交通控制的示例程序,幫助大家對Dapr 的理解更進一步。 2020年的中國.NET開發者峰會朱永光有專門介紹了Dapr,他的演講中也引用了這個示例,朱永光的演講視頻請看://live.csdn.net/room/dotnetconf/1v1d3YbH 。這個示例是github上的一位荷蘭的 MVP 寫的//github.com/EdwinVW/akka-net-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