Dapr 是一個可移植的、事件驅動的執行時,它使任何開發人員能夠輕鬆構建出彈性的、無狀態和有狀態的應用程式,並可執行在雲平臺或邊緣計算中,它同時也支援多種程式語言和開發框架。Dapr 確保開發人員專注於編寫業務邏輯,不必分神解決分散式系統難題,從而顯著提高了生產力。Dapr 降低了構建微服務架構類現代雲原生應用的門檻。
MacOS & Dapr 1.8:
sudo curl -fsSL https://raw.githubusercontent.com/dapr/cli/master/install/install.sh | /bin/bash
Linux/Windows 安裝方式:
Dapr 初始化包括:
dapr init
dapr -v
CLI version: 1.8.0
Runtime version: 1.8.0
如前所述,dapr init
命令會啟動幾個容器,這些容器將幫助您開始使用 Dapr
。 驗證您有執行 daprio/dapr
、openzipkin/zipkin
和 redis
映像的容器範例:
在 dapr init
上,CLI
還會建立一個預設元件資料夾,其中包含幾個 YAML
檔案,其中包含狀態儲存、Pub/sub
和 Zipkin
的定義。Dapr sidecar
將讀取這些元件並使用:
通過開啟您的元件目錄進行驗證:
%UserProfile%\.dapr
下~/.dapr
下ls $HOME/.dapr
bin components config.yaml
執行 Dapr sidecar 並試用 state API
dapr run
命令啟動一個應用程式,以及一個 sidecar。
啟動一個 Dapr sidecar,它將在埠 3500 上偵聽名為 myapp
的空白應用程式:
dapr run --app-id myapp --dapr-http-port 3500
由於沒有使用上述命令定義自定義元件資料夾,因此 Dapr 使用在 dapr init
流程期間建立的預設元件定義。
使用物件更新狀態。新狀態將如下所示:
[
{
"key": "name",
"value": "Bruce Wayne"
}
]
請注意,包含在狀態中的每個物件都有一個分配有值為 name
的 key
。您將在下一步中使用該 key
。
使用以下命令儲存新的狀態物件:
curl -X POST -H "Content-Type: application/json" -d '[{ "key": "name", "value": "Bruce Wayne"}]' http://localhost:3500/v1.0/state/statestore
使用帶有 key 為 name
的狀態檢索您剛剛儲存在 state 中的物件。在同一終端視窗中,執行以下命令:
curl http://localhost:3500/v1.0/state/statestore/name
docker exec -it dapr_redis redis-cli
列出 Redis 鍵以檢視 Dapr 如何使用您提供給 dapr run 的 app-id 作為 key
的字首建立鍵值對:
keys *
"myapp||name"
執行以下命令檢視狀態值:
hgetall "myapp||name"
1) "data"
2) "\"Bruce Wayne\""
3) "version"
4) "1"
使用以下命令退出 Redis CLI:
exit
在同一終端視窗中,從狀態儲存中刪除 name
狀態物件。
curl -v -X DELETE -H "Content-Type: application/json" http://localhost:3500/v1.0/state/statestore/name
所有官方範例筆者均在 MacOS/NodeJs v16.16.0
下實戰完成。
使用 Dapr 的服務呼叫構建塊,您的應用程式可以與其他應用程式可靠且安全地通訊。
git clone https://github.com/dapr/quickstarts.git
從 quickstarts 的根目錄導航到 order-processor
目錄。
cd service_invocation/javascript/http/order-processor
安裝依賴項:
npm install
與 Dapr sidecar 一起執行 order-processor
服務。
dapr run --app-port 5001 --app-id order-processor --app-protocol http --dapr-http-port 3501 -- npm start
app.post('/orders', (req, res) => {
console.log("Order received:", req.body);
res.sendStatus(200);
});
在新的終端視窗中,從 quickstarts 根目錄導航到 checkout
目錄。
cd service_invocation/javascript/http/checkout
安裝依賴項:
npm install
與 Dapr sidecar 一起執行 checkout
服務。
dapr run --app-id checkout --app-protocol http --dapr-http-port 3500 -- npm start
在 checkout
服務中,您會注意到無需重寫您的應用程式程式碼即可使用 Dapr 的服務呼叫。您可以通過簡單地新增 dapr-app-id
header 來啟用服務呼叫,該 header 指定目標服務的 ID。
let axiosConfig = {
headers: {
"dapr-app-id": "order-processor"
}
};
const res = await axios.post(`${DAPR_HOST}:${DAPR_HTTP_PORT}/orders`, order , axiosConfig);
console.log("Order passed: " + res.config.data);
Dapr 在任何 Dapr 範例上呼叫應用程式。在程式碼中,sidecar 程式設計模型鼓勵每個應用程式與其自己的 Dapr 範例通訊。Dapr 範例隨後發現並相互通訊。
checkout
& order-processor
服務輸出:
讓我們看一下 Dapr 的狀態管理構建塊。您將使用 Redis 進行狀態儲存,來儲存、獲取和刪除你的狀態,您也可以將其換成任何一種受 Dapr 支援的狀態儲存。
在終端視窗中,導航到 order-processor
目錄。
cd state_management/javascript/sdk/order-processor
安裝依賴項,其中將包括 JavaScript SDK 中的 dapr-client
包:
npm install
驗證您在服務目錄中包含以下檔案:
package.json
package-lock.json
與 Dapr sidecar 一起執行 order-processor
服務。
dapr run --app-id order-processor --components-path ../../../components/ -- npm run start
order-processor
服務將 orderId key/value
寫入、讀取和刪除到 statestore.yaml
元件中定義的 statestore
範例。一旦服務啟動,它就會執行一個迴圈。
const client = new DaprClient(DAPR_HOST, DAPR_HTTP_PORT);
// 將 state 儲存到 state store 中
client.state.save(STATE_STORE_NAME, [
{
key: orderId.toString(),
value: order
}
]);
console.log("Saving Order: ", order);
// 從 state store 中獲取 state
var result = client.state.get(STATE_STORE_NAME, orderId.toString());
result.then(function(val) {
console.log("Getting Order: ", val);
});
// 從 state store 中刪除 state
client.state.delete(STATE_STORE_NAME, orderId.toString());
result.then(function(val) {
console.log("Deleting Order: ", val);
});
請注意,正如上面程式碼中所指定的,程式碼將應用程式狀態儲存
在 Dapr 狀態儲存中,讀取
它,然後將其刪除
。
Order-processor 輸出:
statestore.yaml
元件檔案
當你執行 dapr init
時,Dapr 會建立一個預設的 Redis statestore.yaml 並在你的本地機器上執行一個 Redis 容器,它位於:
%UserProfile%\.dapr\components\statestore.yaml
~/.dapr/components/statestore.yaml
使用 statestore.yaml
元件,您可以輕鬆切換狀態儲存,而無需更改程式碼。
本快速入門包含的 Redis statestore.yaml
檔案包含以下內容:
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: statestore
spec:
type: state.redis
version: v1
metadata:
- name: redisHost
value: localhost:6379
- name: redisPassword
value: ""
- name: actorStateStore
value: "true"
在 YAML 檔案中:
metadata/name
是您的應用程式與元件對話的方式(在程式碼範例中稱為 DAPR_STORE_NAME
)。spec/metadata
定義到元件使用的 Redis 範例的連線。開始使用 Dapr 的釋出和訂閱構建塊
讓我們看一下 Dapr 的釋出和訂閱 (Pub/sub) 構建塊。您將執行釋出者微服務和訂閱者微服務,以演示 Dapr 如何啟用釋出/訂閱模式。
在終端視窗中,從 quickstarts 根目錄導航到 order-processor 目錄。
cd pub_sub/javascript/sdk/order-processor
安裝依賴項,其中將包括 JavaScript SDK 中的 dapr-client 包:
npm install
驗證您在服務目錄中包含以下檔案:
package.json
package-lock.json
與 Dapr sidecar 一起執行 order-processor subscriber 服務。
dapr run --app-port 5001 --app-id order-processing --app-protocol http --dapr-http-port 3501 --components-path ../../../components -- npm run start
在 order-processor 訂閱者中,我們訂閱名為 order_pub_sub 的 Redis 範例(如 pubsub.yaml 元件中所定義)和 topic orders。這使您的應用程式程式碼能夠通過 Dapr sidecar 與 Redis 元件範例通訊。
server.pubsub.subscribe("order_pub_sub", "orders", (data) => console.log("Subscriber received: " + JSON.stringify(data)));
在新的終端視窗中,從 Quickstarts 克隆目錄的根目錄導航到 checkout 目錄。
cd pub_sub/javascript/sdk/checkout
安裝依賴項,其中將包括 JavaScript SDK 中的 dapr-client 包:
npm install
驗證您在服務目錄中包含以下檔案:
package.json
package-lock.json
與 Dapr sidecar 一起執行 checkout 釋出者服務。
dapr run --app-id checkout --app-protocol http --dapr-http-port 3500 --components-path ../../../components -- npm run start
在 checkout
釋出者服務中,我們將 orderId 訊息釋出到名為 order_pub_sub
的 Redis 範例(在 pubsub.yaml 元件中定義)和 topic orders
。服務一啟動,就會迴圈釋出:
const client = new DaprClient(DAPR_HOST, DAPR_HTTP_PORT);
await client.pubsub.publish(PUBSUB_NAME, PUBSUB_TOPIC, order);
console.log("Published data: " + JSON.stringify(order));
請注意,正如上面程式碼中所指定的,釋出者將一個亂數推播到 Dapr sidecar,而訂閱者接收它。
釋出者 & 訂閱者輸出:
pubsub.yaml 元件檔案
當你執行 dapr init
時,Dapr
會建立一個預設的 Redis pubsub.yaml
並在你的本地機器上執行一個 Redis 容器,它位於:
%UserProfile%\.dapr\components\pubsub.yaml
下~/.dapr/components/pubsub.yaml
下使用 pubsub.yaml
元件,您可以輕鬆更換底層元件,而無需更改應用程式程式碼。
本快速入門包含的 Redis pubsub.yaml
檔案包含以下內容:
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: order_pub_sub
spec:
type: pubsub.redis
version: v1
metadata:
- name: redisHost
value: localhost:6379
- name: redisPassword
value: ""
在 YAML 檔案中:
metadata/name
是您的應用程式與元件對話的方式。spec/metadata
定義與元件範例的連線。scopes
指定哪個應用程式可以使用該元件。開始使用 Dapr 的 Binding 構建塊
讓我們看一下 Dapr 的 Bindings 構建塊。使用繫結,您可以:
接下來您將使用輸入 Cron binding 安排批次處理指令碼每 10 秒執行一次。該指令碼使用 PostgreSQL Dapr binding 處理 JSON 檔案並將資料輸出到 SQL 資料庫。
在您機器上的 Docker 容器中本地執行 PostgreSQL 範例。範例包含一個 Docker Compose 檔案,用於在本地自定義、構建、執行和初始化帶有預設 orders
表的 postgres 容器。
在終端視窗中,從 quickstarts 根目錄導航到 bindings/db
目錄。
cd bindings/db
執行以下命令來設定容器:
docker compose up
在新的終端視窗中,導航到 SDK 目錄。
cd bindings/javascript/sdk/batch
安裝依賴項:
npm install
與 Dapr sidecar 一起執行 batch-sdk 服務。
dapr run --app-id batch-sdk --app-port 5002 --dapr-http-port 3500 --components-path ../../../components -- node index.js
process_batch 函數內的程式碼每 10 秒執行一次(在 components 目錄的 binding-cron.yaml 中定義)。繫結觸發器在 Dapr sidecar 的 Flask 應用程式中查詢通過 HTTP POST 呼叫的路由。
async function start() {
await server.binding.receive(cronBindingName,processBatch);
await server.start();
}
batch-sdk 服務使用 binding-postgres.yaml 元件中定義的 PostgreSQL 輸出繫結將 OrderId、Customer 和 Price 記錄插入到 orders
表中。
async function processBatch(){
const loc = '../../orders.json';
fs.readFile(loc, 'utf8', (err, data) => {
const orders = JSON.parse(data).orders;
orders.forEach(order => {
let sqlCmd = `insert into orders (orderid, customer, price) values (${order.orderid}, '${order.customer}', ${order.price});`;
let payload = `{ "sql": "${sqlCmd}" } `;
console.log(payload);
client.binding.send(postgresBindingName, "exec", "", JSON.parse(payload));
});
console.log('Finished processing batch');
});
return 0;
}
請注意,如上所述,程式碼使用 OrderId、Customer 和 Price 作為 payload 呼叫輸出繫結。
你的輸出繫結的 print 語句輸出:
在新終端中,驗證是否已將相同的資料插入到資料庫中。
cd bindings/db
啟動互動式 Postgres CLI:
docker exec -i -t postgres psql --username postgres -p 5432 -h localhost --no-password
在 admin=#
提示符下,更改為 orders
表:
\c orders;
在 orders=#
提示符下,選擇所有行:
select * from orders;
輸出應如下所示:
components\binding-cron.yaml 元件檔案
當您執行 dapr run 命令並指定元件路徑時,Dapr sidecar:
binding-cron.yaml 檔案包含以下內容:
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: cron
namespace: quickstarts
spec:
type: bindings.cron
version: v1
metadata:
- name: schedule
value: "@every 10s"
注意:binding-cron.yaml 的後設資料部分包含一個 Cron 表示式,用於指定呼叫繫結的頻率。
component\binding-postgres.yaml 元件檔案
當您執行 dapr run 命令並指定元件路徑時,Dapr sidecar:
使用 binding-postgres.yaml 元件,您可以輕鬆換出後端資料庫繫結,而無需更改程式碼。
本快速入門包含的 PostgreSQL binding-postgres.yaml 檔案包含以下內容:
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: sqldb
namespace: quickstarts
spec:
type: bindings.postgres
version: v1
metadata:
- name: url
value: "user=postgres password=docker host=localhost port=5432 dbname=orders pool_min_conns=1 pool_max_conns=10"
在 YAML 檔案中:
開始使用 Dapr 的 Secrets Management 構建塊
Dapr 提供了一個專用的 secrets API,允許開發人員從 secrets store 中檢索 secrets。接下來:
在終端視窗中,導航到 order-processor
目錄。
cd secrets_management/javascript/sdk/order-processor
安裝依賴項:
npm install
與 Dapr sidecar 一起執行 order-processor 服務。
dapr run --app-id order-processor --components-path ../../../components/ -- npm start
order-processor 服務
請注意下面的 order-processor 服務如何指向:
// index.js
const DAPR_SECRET_STORE = "localsecretstore";
const SECRET_NAME = "secret";
async function main() {
// ...
const secret = await client.secret.get(DAPR_SECRET_STORE, SECRET_NAME);
console.log("Fetched Secret: " + JSON.stringify(secret));
}
local-secret-store.yaml 元件
DAPR_SECRET_STORE 定義在 local-secret-store.yaml 元件檔案中,位於 secrets_management/components 中:
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: localsecretstore
namespace: default
spec:
type: secretstores.local.file
version: v1
metadata:
- name: secretsFile
value: secrets.json
- name: nestedSeparator
value: ":"
在 YAML 檔案中:
metadata/name
是您的應用程式參照元件的方式(在程式碼範例中稱為 DAPR_SECRET_STORE)。spec/metadata
定義與元件使用的 secret 的連線。secrets.json 檔案
SECRET_NAME
在位於 secrets_management/javascript/sdk/order-processor
的 secrets.json
檔案中定義:
{
"secret": "YourPasskeyHere"
}
正如上面的應用程式程式碼中所指定的,order-processor 服務通過 Dapr secret 儲存檢索 secret 並將其顯示在控制檯中。