dapr 概要笔记
dapr 概要笔记,本文测试验证了官方 dapr 和阿里 dapr 的具体步骤,并通过 go、rust 程序化调用了最简单的 hsf(类似社区 dubbo) 接口。
dapr 社区版本
安装 dapr-cli
$ brew install dapr/tap/dapr-cli
# 验证安装
$ darp -h
初始化
参考 本地初始化
# 如果本地为 colima 管理的 docker,需手动 export DOCKER_HOST
$ export DOCKER_HOST="unix://$HOME/.colima/default/docker.sock"
# 初始化
$ dapr init
⌛ Making the jump to hyperspace...
ℹ️ Container images will be pulled from Docker Hub
ℹ️ Installing runtime version 1.16.3
✅ Downloading binaries and setting up components...
✅ Downloaded binaries and completed components set up.
...
ℹ️ dapr_placement container is running.
ℹ️ dapr_redis container is running.
ℹ️ dapr_zipkin container is running.
ℹ️ dapr_scheduler container is running.
ℹ️ Use `docker ps` to check running containers.
✅ Success! Dapr is up and running. To get started, go here: https://docs.dapr.io/getting-started
启动并测试
参考 使用 dapr api
# 启动 dapr
# 默认的 componets 目录为 $HOME/.dapr/components
$ dapr run --app-id myapp --dapr-http-port 3500
# 使用 redis 存储状态,进行测试存储
$ curl -X POST -H "Content-Type: application/json" -d '[{ "key": "myname", "value": "pipe"}]' http://localhost:3500/v1.0/state/statestore
# 进行测试获取状态
$ curl http://localhost:3500/v1.0/state/statestore/myname
"pipe"%
dapr 阿里版本
参考 本地启动Dapr
安装 ali-dapr
进入 dapr.io.alibaba-inc.com,获取二进制文件下载地址,比如下载 Mac M 系列的命令如下:
# 下载并重命名为 ali-daprd
$ wget -O ali-daprd http://pandora-repos.oss-cn-hangzhou-c.aliyuncs.com/publicfiles/dapr/v1.15.4.20/darwin_arm64/release/daprd
# 添加执行权限
$ chmod +x ./ali-daprd
配置并启动
参考 社区 dubbo
新建 hsf.yaml
相关的 subscribe 字段,可提前预热 hsf 接口,能有效提升首次调用时间,为简化逻辑,此处不做启动订阅
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: hsf.consumer
spec:
type: bindings.hsf
metadata:
启动 dapr
# 根据当前的 hsf 组件启动,指定为当前目录(上述 hsf.yaml 所在目录)
$ ./ali-daprd -app-id ali-daprd --resources-path ./
测试 hsf 调用
# 测试 hsf 调用
$ curl -X POST http://127.0.0.1:3500/v1.0/bindings/hsf.consumer \
-H "Content-Type: application/json" \
-d '{
"operation": "invoke",
"metadata": {
"rpc-interface-name": "com.alibaba.hsf.mstest.service.hsf.HelloService",
"rpc-method-name": "sayHello",
"rpc-method-parameter-types": "java.lang.String",
"rpc-version": "1.0.0.DAILY"
},
"data": ["pipe.zkk"]
}'
"Hello, pipe.zkk"%
程序调用
dapr 最大优势就是统一协议之后,支持跨语言调用,所以简单测试一下 go 与 rust 的调用。
Rust Dapr
初始化项目
# 新建 rust 项目
$ cargo new rust-dapr
$ cd rust-dapr
# 添加 dapr 库
$ cargo add dapr
# 添加异步库
$ cargo add tokio --features full
main 代码
dapr 默认的 HTTP 端口为 3500,gRPC 端口为 50001
use dapr::Client as DaprClient;
use std::collections::HashMap;
#[tokio::main]
async fn main() {
let addr = "http://127.0.0.1".to_string();
let port = "50001".to_string();
let mut client = DaprClient::<dapr::client::TonicClient>::connect_with_port(addr, port)
.await
.expect("Failed to connect to Dapr");
let data = "[\"pipe.zkk\"]".as_bytes().to_vec();
let mut metadata = Some(HashMap::new());
let _ = metadata.insert(HashMap::from([
(
"rpc-interface-name".to_string(),
"com.alibaba.hsf.mstest.service.hsf.HelloService".to_string(),
),
("rpc-method-name".to_string(), "sayHello".to_string()),
(
"rpc-method-parameter-types".to_string(),
"java.lang.String".to_string(),
),
("rpc-version".to_string(), "1.0.0.DAILY".to_string()),
]));
let response = client
.invoke_binding("hsf.consumer", data, "invoke", metadata)
.await
.expect("Failed to invoke binding");
println!(
"get_response: {:?}",
String::from_utf8(response.data).expect("Failed to convert response to string")
);
}
运行完程序后,输出如下:
# 编译并运行
$ cargo run
Compiling rust-dapr v0.1.0 (/Users/zhoukeke/workspace/grpc-note/rust-grpc/rust-dapr)
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.80s
Running `target/debug/rust-dapr`
get_response: "\"Hello, pipe.zkk\""
go dapr
初始化项目
$ mkdir go-dapr && cd go-dapr
# 初始化并新建 main 文件
$ go mod init hello-dapr
$ touch main.go
# 安装依赖
$ go get github.com/dapr/go-sdk/client
main 代码
package main
import (
"context"
"fmt"
dapr "github.com/dapr/go-sdk/client"
)
func main() {
client, err := dapr.NewClientWithAddress("127.0.0.1:50001")
if err != nil {
panic(err)
}
defer client.Close()
response, err := client.InvokeBinding(context.Background(), &dapr.InvokeBindingRequest{
Name: "hsf.consumer",
Operation: "invoke",
Data: []byte("[\"pipe.zkk\"]"),
Metadata: map[string]string{
"rpc-interface-name": "com.alibaba.hsf.mstest.service.hsf.HelloService",
"rpc-method-name": "sayHello",
"rpc-method-parameter-types": "java.lang.String",
"rpc-version": "1.0.0.DAILY",
},
})
if err != nil {
panic(err)
}
fmt.Println(string(response.Data))
}
运行结果如下
$ go run main.go
dapr client initializing for: 127.0.0.1:50001
"Hello, pipe.zkk"
小结
从上述代码结果,能比较清楚地看出,其实 rust 并不适合写业务代码(相对比较冗余和复杂),go 会更适合一些,rust 会更适合偏低层或操作系统层面的。如果后续做 wasm server runtime 的上层语言选择,go 可能会更适合。