sidecar构架之dapr服务调用
服务调用示意
dapr调用示意
sidecar 之间的通信都是 gRPC (3、6)
application与sidecar之间的通信是http/grpc (1、7、4、5)
- 服务 A 对服务 B 发起HTTP/gRPC的调用。
- Dapr使用服务注册发现平台的名称解析组件发现服务B的位置。(例如:mDNS、consul等)
- Dapr 将消息转发至服务 B的 Dapr 边车
注: Dapr 边车之间的所有调用考虑到性能都优先使用 gRPC。 仅服务与 Dapr 边车之间的调用可以是 HTTP 或 gRPC - 服务 B的 Dapr 边车将请求转发至服务 B 上的特定端点 (或方法) 。 服务 B 随后运行其业务逻辑代码。
- 服务 B 发送响应给服务 A。 响应将转至服务 B 的边车。
- Dapr 将消息转发至服务 A 的 Dapr 边车。
- 服务 A 接收响应。
python和node服务示例
- Node.js应用程序有一个
app ID
为nodeapp
的Dapr应用程序。 当python
应用程序通过POST http://localhost:3500/v1.0/invoke/nodeapp/method/neworder
调用 Node.js 应用程序的neworder
方法时, 首先会到达python app的本地dapr sidecar。 - Dapr 使用本地机器运行的名称解析组件(在这种情况下自动运行的 mDNS),发现 Node.js 应用的位置。
- Dapr 使用刚刚收到的位置将请求转发到 Node.js 应用的 sidecar。
- Node.js 应用的 sidecar 将请求转发到 Node.js 应用程序。 Node.js 应用执行其业务逻辑,记录收到的消息,然后将订单 ID 存储到 Redis (未在图表中显示)中
- Node.js应 用程序通过 Node.js sidecar 向 Python 应用程序发送一个响应。
- Dapr 转发响应到 Python 的 Dapr sidecar
- Python 应用程序收到响应。
API 和端口
Dapr runtime 对外提供两个 API,分别是 Dapr HTTP API 和 Dapr gRPC API。另外两个 dapr runtime 之间的通讯 (Dapr internal API) 固定用 gRPC 协议。
两个 Dapr API 对外暴露的端口
- 3500: HTTP 端口,可以通过命令行参数 dapr-http-port 设置
- 50001: gRPC 端口,可以通过命令行参数 dapr-grpc-port 设置
1 | dapr run --app-id nodeapp --app-port 3000 --dapr-http-port 3500 --dapr-grpc-port 50001 node app.js |
Dapr internal API 是内部端口,比较特殊,没有固定的默认值,而是取任意随机可用端口。也可以通过命令行参数 dapr-internal-grpc-port 设置。
为了向服务器端的应用发送请求,dapr 需要获知应用在哪个端口监听并处理请求,这个信息通过命令行参数 app-port 设置。Dapr 的示例中一般喜欢用 3000 端口。
实践
我们使用官方的教程来实验一下
启动服务
我们先开启node的订单服务
1 | cd ./hello-world/node |
1 | ℹ️ Starting Dapr with id nodeapp. HTTP Port: 3500. gRPC Port: 54626 |
服务解析
启动后,我们先看看订单服务有什么操作
创建订单:/neworder
1 | app.post('/neworder', async (req, res) => { |
获取订单:/order
1 | app.get('/order', async (_req, res) => { |
服务调用
http调用方式
使用 Dapr cli 调用
1 | dapr invoke --app-id nodeapp --method neworder --data-file sample.json |
1 | // 创建订单 |
使用curl调用
通过dapr的Endpoint
1 | // 创建订单 |
通过Node程序自己的Endpoint,这样不通过Dapr Sidecar。
1 | curl -XPOST -d @sample.json -H "Content-Type:application/json" http://localhost:3000/neworder |
使用Postman调用
使用SDK
默认HTTP
1 | import { DaprClient } from "@dapr/dapr"; |
另一个程序语言的服务调用(python)
接下来部署Python的程序。Python也得先装运行环境:
1 | cd ./hello-world/python |
启动成功了。因为Python自己不提供服务,所以–app-port不用指定。–dapr-http-port是3501,这是自己的Sidecar用的端口,不能跟别人的重了。再看看刚才Node的窗口,不停的有新的Request过来,就是Python程序来的每隔一秒的Request。
最后看一下dapr list的结果:
1 | APP ID HTTP PORT GRPC PORT APP PORT COMMAND AGE CREATED PID |
GRPC调用方式
GRPC调用方式,在application得起一个GRPC服务,然后通过dapr调用application的GRPC服务
使用SDK
1 | import { DaprClient, CommunicationProtocol } from "@dapr/dapr"; |