NodeJS 基于 Dapr 构建云原生微服务应用,从 0 到 1 快速上手指南
qiyuwang 2024-10-31 15:51 23 浏览 0 评论
Dapr 是一个可移植的、事件驱动的运行时,它使任何开发人员能够轻松构建出弹性的、无状态和有状态的应用程序,并可运行在云平台或边缘计算中,它同时也支持多种编程语言和开发框架。Dapr 确保开发人员专注于编写业务逻辑,不必分神解决分布式系统难题,从而显著提高了生产力。Dapr 降低了构建微服务架构类现代云原生应用的门槛。
系列
- 本地使用 Docker Compose 与 Nestjs 快速构建基于 Dapr 的 Redis 发布/订阅分布式应用
安装 Dapr CLI
MacOS & Dapr 1.8:
sudo curl -fsSL https://raw.githubusercontent.com/dapr/cli/master/install/install.sh | /bin/bash
Linux/Windows 安装方式:
- https://docs.dapr.io/getting-started/install-dapr-cli/
本地环境中初始化 Dapr
Dapr 初始化包括:
- 运行一个用于状态存储和消息代理的 Redis 容器实例
- 运行一个用于提供可观察性的 Zipkin 容器实例
- 创建具有上述组件定义的默认组件文件夹
- 运行用于本地 actor(我们的服务) 支持的 Dapr placement 服务容器实例
运行初始化 CLI 命令
dapr init
验证 Dapr 版本
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 将读取这些组件并使用:
- 用于状态管理和消息传递的 Redis 容器。
- 用于收集踪迹的 Zipkin 容器。
通过打开您的组件目录进行验证:
- Windows, 在 %UserProfile%\.dapr 下
- Linux/MacOS, 在 ~/.dapr 下
ls $HOME/.dapr
bin components config.yaml
使用 Dapr API
运行 Dapr sidecar 并试用 state API
运行 Dapr sidecar
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
查看状态如何存储在 Redis 中
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 下实战完成。
1. 服务调用
使用 Dapr 的服务调用构建块,您的应用程序可以与其他应用程序可靠且安全地通信。
示例仓库
git clone https://github.com/dapr/quickstarts.git
运行 order-processor 服务
从 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);
});
运行 checkout 服务
在新的终端窗口中,从 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 服务输出:
2. 状态管理
让我们看一下 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);
});
查看 order-processor 输出
请注意,正如上面代码中所指定的,代码将应用程序状态保存在 Dapr 状态存储中,读取它,然后将其删除。
Order-processor 输出:
statestore.yaml 组件文件
当你运行 dapr init 时,Dapr 会创建一个默认的 Redis statestore.yaml 并在你的本地机器上运行一个 Redis 容器,它位于:
- Windows,%UserProfile%\.dapr\components\statestore.yaml
- Linux/MacOS ,~/.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 实例的连接。
3. 发布和订阅
开始使用 Dapr 的发布和订阅构建块
让我们看一下 Dapr 的发布和订阅 (Pub/sub) 构建块。您将运行发布者微服务和订阅者微服务,以演示 Dapr 如何启用发布/订阅模式。
- 使用发布服务,开发人员可以重复发布消息到 topic。
- Pub/sub 组件对这些消息进行排队或代理。我们下面的示例使用 Redis,您可以使用 RabbitMQ、Kafka 等。
- 该 topic 的订阅者从队列中提取消息并处理它们。
订阅 topic
在终端窗口中,从 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)));
发布 topic
在新的终端窗口中,从 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 容器,它位于:
- 在 Windows 上,在 %UserProfile%\.dapr\components\pubsub.yaml 下
- 在 Linux/MacOS 上,在 ~/.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 指定哪个应用程序可以使用该组件。
4. 输入和输出绑定
开始使用 Dapr 的 Binding 构建块
让我们看一下 Dapr 的 Bindings 构建块。使用绑定,您可以:
- 使用来自外部系统的事件触发您的应用程序。
- 与外部系统的接口。
接下来您将使用输入 Cron binding 安排批处理脚本每 10 秒运行一次。该脚本使用 PostgreSQL Dapr binding 处理 JSON 文件并将数据输出到 SQL 数据库。
在本地运行 PostgreSQL Docker 容器
在您机器上的 Docker 容器中本地运行 PostgreSQL 实例。示例包含一个 Docker Compose 文件,用于在本地自定义、构建、运行和初始化带有默认 orders 表的 postgres 容器。
在终端窗口中,从 quickstarts 根目录导航到 bindings/db 目录。
cd bindings/db
运行以下命令来设置容器:
docker compose up
安排一个 Cron job 并写入数据库
在新的终端窗口中,导航到 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;
}
查看 job 的输出
请注意,如上所述,代码使用 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:
- 启动 Cron 绑定构建块
- 每 10 秒调用一次绑定端点(批处理)
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:
- 启动 PostgreSQL 绑定构建块
- 使用 binding-postgres.yaml 文件中指定的设置连接到 PostgreSQL
使用 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 文件中:
- spec/type 指定 PostgreSQL 用于此绑定。
- spec/metadata 定义到组件使用的 PostgreSQL 实例的连接。
5. Secrets 管理
开始使用 Dapr 的 Secrets Management 构建块
Dapr 提供了一个专用的 secrets API,允许开发人员从 secrets store 中检索 secrets。接下来:
- 运行带有 secret 存储组件的微服务。
- 在应用程序代码中使用 Dapr secrets API 检索 secrets。
检索 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 服务如何指向:
- 在 local-secret-store.yaml 组件中定义的 DAPR_SECRET_STORE。
- 在 secrets.json 中定义的 secret。
// 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 输出
正如上面的应用程序代码中所指定的,order-processor 服务通过 Dapr secret 存储检索 secret 并将其显示在控制台中。
6. 官方示例仓库(源码)
- https://github.com/dapr/quickstarts.git
相关推荐
- windows开启telnet服务,检测远程服务端口是否可以连通
-
本文介绍windwos开启telnet服务,telnet服务一般可以用于检测远程主机的某个端口服务是否可以连通,在日常的工作中,我们经常会遇到在本地的windows检测远程服务端口是否可以连通。win...
- 仅在Web登录新华三交换机条件下启用设备Telnet登录方式
-
概述Web登录新华三交换机可以在“网络-服务”页面中启用设备Telnet服务或SSH服务,也可以在“设备-管理员”设置管理员用户的可用服务,然而,在设备Web页面中,无法设置lineVTY用户线【l...
- 思科交换机,路由器如何关闭telnet 开启ssh服务
-
SSH为建立在应用层基础上的安全协议。SSH是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议。利用SSH协议可以有效防止远程管理过程中的信息泄露问题。今天我们就来说说思科交换机,路...
- 智能化弱电行业常用的DOS命令,掌握了你也能成为...
-
前言在做智能化弱电项目时,前端摄像头设备安装结束后,我们会对网络摄像头进行调试,调试过程中会遇到前端摄像头没有图像或者图像出来了画面卡顿的现象。我们会采用ping命令来测试网络的连通性和网络承载能力。...
- 「干货」eNSP模拟器之配置Telnet登录
-
配置说明:配置Telnet,使R2(模拟PC)通过SW1登录到R1进行管理和配置。操作步骤:system-view##进入系统视图[Huawei]sysnameR1##改名为R1[R1]int...
- win11开启telnet服务怎么操作 win11打开telent指令是什么
-
telnet服务是我们在进行远程连接的时候,必须要打开的一项功能。但是有不少用户们不清楚在windows11系统中怎么开启telnet服务。今天小编就使用详细的图文教程,来给大家说明一下打开telen...
- 华三(H3C)交换机Telnet的远程登陆
-
一,配置交换机管理IP[SW1]vlan20//创建管理vlan[SW1]interfacevlan20//进入vlan接口[SW1-Vlanif20]ipaddress192.168....
- win10 telnet命令怎么查看端口是否打开
-
可能大家也会遇到这个问题,win10telnet命令查看端口是否打开的步骤是什么?具体方法如下:1、键盘输入快捷键WIN+R,打开运行窗口。2、输入cmd,点击确定按钮。3、弹出cmd命令行窗...
- Windows 7如何打开Telnet功能(win7系统打开telnet)
-
Windows7默认安装后是没有开启telnet客户端功能的,例如,我们在开始菜单中输入cmd,然后使用telnet命令,会弹出下图提示:‘telnet’不是内部或外部命令,也不是可运行程序或批处理文...
- 为锐捷路由器交换机开启web和telnet,实现轻松管理
-
笔者上一篇文章写了关于锐捷二层交换机配置教程,那么接下来讲一下锐捷的路由交换设备配置web、telnet技巧。同样,今天的教程也是基于命令行,比较简单,适合新手小白进行学习。准备工作配置前准备:con...
- 一文学会telnet命令的用途和使用方法
-
Telnet是一个古老的远程登录协议,可以让本地计算机获得远程计算机的工作能力。它采用了TCP的可靠连接方式,可以连接任何网络互通的远程计算机。不过由于它采用了明文传输方式,存在安全风险,目前已经很少...
- Telnet命令是什么?如何使用?(telnet命令在哪里开启)
-
telnet命令是一个常用的远程登陆工具,使用它,我们可以快捷地登陆远程服务器进行操作。那么如何使用telnet命令呢?首先,我们需要打开telnet功能,任何电脑默认是关闭此功能的,开启方式如下:打...
- win11系统如何开启telnet服务(拷贝版本)
-
我们要知道,Telnet协议是Internet远程登陆服务的标准协议,可以使用户在本地计算机上完成远程主机的工作,不过对于一些刚接触win11中文版系统的用户来说,可能还不知道telnet服务在哪...
- 如何开启telnet客户端(如何开启telnet服务)
-
Telnet协议是TCP/IP协议家族中的一员,是Internet远程登陆服务的标准协议和主要方式,Telnet是常用的远程控制Web服务器的方法。工作中经常用到telnet客户端,但在windows...
- Telnet 是什么,如何启用它?(telnet有什么用)
-
对于Internet等TCP/IP网络,Telnet是一个终端仿真程序。Telnet软件在您的系统上运行并将您的个人计算机链接到网络服务器。它将所有数据转换为纯文本这一事实被认为是易受...
你 发表评论:
欢迎- 一周热门
- 最近发表
- 标签列表
-
- navicat无法连接mysql服务器 (65)
- 下横线怎么打 (71)
- flash插件怎么安装 (60)
- lol体验服怎么进 (66)
- ae插件怎么安装 (62)
- yum卸载 (75)
- .key文件 (63)
- cad一打开就致命错误是怎么回事 (61)
- rpm文件怎么安装 (66)
- linux取消挂载 (81)
- ie代理配置错误 (61)
- ajax error (67)
- centos7 重启网络 (67)
- centos6下载 (58)
- mysql 外网访问权限 (69)
- centos查看内核版本 (61)
- ps错误16 (66)
- nodejs读取json文件 (64)
- centos7 1810 (59)
- 加载com加载项时运行错误 (67)
- php打乱数组顺序 (68)
- cad安装失败怎么解决 (58)
- 因文件头错误而不能打开怎么解决 (68)
- js判断字符串为空 (62)
- centos查看端口 (64)