dapr-hello world 体验

Dapr 快速入门 是代码样本的教程集合,旨在让您从 Dapr 快速入门,每个教程都突出了不同的 Dapr 功能。

  • 一合适的入门起点是 hello-world 快速入门,它演示了如何在本地机器上以自托管模式运行Dapr,并使用一个简单的应用程序中演示了状态管理和服务调用。
  • 接下来,如果您熟悉Kubernetes,想了解如何在Kubernetes环境中运行相同的应用程序,请阅读hello-kubernetes快速入门。 其他的快速入门教程皆在探索Dapr的不同功能,如发布/订阅、绑定和分布式计算,同时教程内包括本地和Kubernetes上运行的说明,可以无序完成。 快速入门的完整列表可在下方找到。
  • 您可以随时浏览 Dapr 文档或 SDK 特定例子,还可以尝试额外的快速入门。
  • 当你完成所有入门后,可以考虑探索Dapr样例库,查看由社区贡献的更多的代码样本,其中展示Dapr的更多高阶或特定的用法。

下面演示下,演示如何在本地运行Dapr。 重点介绍服务调用和状态管理。

以下架构图说明了构成第一部分示例的组件:

稍后,您将部署一个 Python 应用程序来充当发布者。下面的架构图显示了新组件的添加:

 必备条件
本快速入门要求您在计算机上安装以下内容:

  • Docker
  • Node.js version 8 or greater
  • Python 3.x: Note: When running this quickstart on Windows, it best to install Python from python.org rather than from the Windows store.
  • Postman [Optional]

Step 1 - Setup Dapr

按照dapr部署说明初始化 Dapr。

Step 2 - Understand the code

现在 Dapr 已在本地设置,克隆存储库,然后导航到 Hello World 快速入门的 Node.js 版本:

git clone [-b <dapr_version_tag>] https://github.com/dapr/quickstarts.git
cd quickstarts/hello-world/node

使用idea打开对应的项目:(需具备go语言基础)

 注意:有关支持的标签,请参阅 https://github.com/dapr/quickstarts#supported-dapr-runtime-version。使用 dapr 运行时的边缘版本时,请使用 git clone https://github.com/dapr/quickstarts.git。

在 app.js 中,您会发现一个简单的 express 应用程序,它公开了一些路由和处理程序。首先,看一下文件的顶部:

const daprPort = process.env.DAPR_HTTP_PORT || 3500;
const stateStoreName = `statestore`;
const stateUrl = `http://localhost:${daprPort}/v1.0/state/${stateStoreName}`;

Dapr CLI 为 Dapr 端口创建一个环境变量,默认为 3500。您将在第 3 步中向系统发送 POST 消息时使用它。 stateStoreName 是给状态存储的名称。稍后您将返回到该名称以查看该名称是如何配置的。

接下来,看一下 neworder 处理程序:

app.post('/neworder', (req, res) => {
    const data = req.body.data;
    const orderId = data.orderId;
    console.log("Got a new order! Order ID: " + orderId);

    const state = [{
        key: "order",
        value: data
    }];

    fetch(stateUrl, {
        method: "POST",
        body: JSON.stringify(state),
        headers: {
            "Content-Type": "application/json"
        }
    }).then((response) => {
        if (!response.ok) {
            throw "Failed to persist state.";
        }

        console.log("Successfully persisted state.");
        res.status(200).send();
    }).catch((error) => {
        console.log(error);
        res.status(500).send({message: error});
    });
});

在这里,应用程序公开了一个将接收和处理 neworder 消息的端点。它首先记录传入的消息,然后通过将状态数组发布到 /state/<state-store-name> 端点,将订单 ID 保存到 Redis 存储中。

或者,您可以通过简单地将状态与响应对象一起返回来保持状态:

res.json({
        state: [{
            key: "order",
            value: order
        }]
    })

但是,这种方法不允许您验证消息是否成功持久化。

该应用程序还公开了一个 GET 端点 /order:

app.get('/order', (_req, res) => {
    fetch(`${stateUrl}/order`)
        .then((response) => {
            if (!response.ok) {
                throw "Could not get state.";
            }

            return response.text();
        }).then((orders) => {
            res.send(orders);
        }).catch((error) => {
            console.log(error);
            res.status(500).send({message: error});
        });
});

这会调用 Redis 缓存以检索“order”键的最新值,从而有效地使 Node.js 应用程序成为无状态的。

Step 3 - Run the Node.js app with Dapr

打开一个新终端并导航到 ./hello-world/node 目录并按照以下步骤操作:

1.Install dependencies:

npm install

这将安装 express 和 body-parser,package.json 中显示的依赖项。

2.使用 Dapr 运行 Node.js 应用程序:

dapr run --app-id nodeapp --app-port 3000 --dapr-http-port 3500 node app.js

输出内容:

ℹ️  Starting Dapr with id nodeapp. HTTP Port: 3500. gRPC Port: 53796
INFO[0000] starting Dapr Runtime -- version 1.7.1 -- commit 5fd38aeaaa9cf58f3f00f6f9bfc6c58d8cd82b87  app_id=nodeapp instance=romandeMacBook-Pro.local scope=dapr.runtime type=log ver=1.7.1
INFO[0000] log level set to: info                        app_id=nodeapp instance=romandeMacBook-Pro.local scope=dapr.runtime type=log ver=1.7.1
INFO[0000] metrics server started on :53797/             app_id=nodeapp instance=romandeMacBook-Pro.local scope=dapr.metrics type=log ver=1.7.1
INFO[0000] standalone mode configured                    app_id=nodeapp instance=romandeMacBook-Pro.local scope=dapr.runtime type=log ver=1.7.1
INFO[0000] app id: nodeapp                               app_id=nodeapp instance=romandeMacBook-Pro.local scope=dapr.runtime type=log ver=1.7.1
INFO[0000] mTLS is disabled. Skipping certificate request and tls validation  app_id=nodeapp instance=romandeMacBook-Pro.local scope=dapr.runtime type=log ver=1.7.1
INFO[0000] local service entry announced: nodeapp -> 192.168.1.67:53801  app_id=nodeapp instance=romandeMacBook-Pro.local scope=dapr.contrib type=log ver=1.7.1
INFO[0000] Initialized name resolution to mdns           app_id=nodeapp instance=romandeMacBook-Pro.local scope=dapr.runtime type=log ver=1.7.1
INFO[0000] loading components                            app_id=nodeapp instance=romandeMacBook-Pro.local scope=dapr.runtime type=log ver=1.7.1
== APP == Node App listening on port 3000!
INFO[0000] component loaded. name: pubsub, type: pubsub.redis/v1  app_id=nodeapp instance=romandeMacBook-Pro.local scope=dapr.runtime type=log ver=1.7.1
INFO[0000] waiting for all outstanding components to be processed  app_id=nodeapp instance=romandeMacBook-Pro.local scope=dapr.runtime type=log ver=1.7.1
INFO[0000] detected actor state store: statestore        app_id=nodeapp instance=romandeMacBook-Pro.local scope=dapr.runtime type=log ver=1.7.1
INFO[0000] component loaded. name: statestore, type: state.redis/v1  app_id=nodeapp instance=romandeMacBook-Pro.local scope=dapr.runtime type=log ver=1.7.1
INFO[0000] all outstanding components processed          app_id=nodeapp instance=romandeMacBook-Pro.local scope=dapr.runtime type=log ver=1.7.1
INFO[0000] gRPC proxy enabled                            app_id=nodeapp instance=romandeMacBook-Pro.local scope=dapr.runtime type=log ver=1.7.1
INFO[0000] enabled gRPC tracing middleware               app_id=nodeapp instance=romandeMacBook-Pro.local scope=dapr.runtime.grpc.api type=log ver=1.7.1
INFO[0000] enabled gRPC metrics middleware               app_id=nodeapp instance=romandeMacBook-Pro.local scope=dapr.runtime.grpc.api type=log ver=1.7.1
INFO[0000] API gRPC server is running on port 53796      app_id=nodeapp instance=romandeMacBook-Pro.local scope=dapr.runtime type=log ver=1.7.1
INFO[0000] enabled metrics http middleware               app_id=nodeapp instance=romandeMacBook-Pro.local scope=dapr.runtime.http type=log ver=1.7.1
INFO[0000] enabled tracing http middleware               app_id=nodeapp instance=romandeMacBook-Pro.local scope=dapr.runtime.http type=log ver=1.7.1
INFO[0000] http server is running on port 3500           app_id=nodeapp instance=romandeMacBook-Pro.local scope=dapr.runtime type=log ver=1.7.1
INFO[0000] The request body size parameter is: 4         app_id=nodeapp instance=romandeMacBook-Pro.local scope=dapr.runtime type=log ver=1.7.1
INFO[0000] enabled gRPC tracing middleware               app_id=nodeapp instance=romandeMacBook-Pro.local scope=dapr.runtime.grpc.internal type=log ver=1.7.1
INFO[0000] enabled gRPC metrics middleware               app_id=nodeapp instance=romandeMacBook-Pro.local scope=dapr.runtime.grpc.internal type=log ver=1.7.1
INFO[0000] internal gRPC server is running on port 53801  app_id=nodeapp instance=romandeMacBook-Pro.local scope=dapr.runtime type=log ver=1.7.1
INFO[0000] application protocol: http. waiting on port 3000.  This will block until the app is listening on that port.  app_id=nodeapp instance=romandeMacBook-Pro.local scope=dapr.runtime type=log ver=1.7.1
INFO[0000] application discovered on port 3000           app_id=nodeapp instance=romandeMacBook-Pro.local scope=dapr.runtime type=log ver=1.7.1
WARN[0000] [DEPRECATION NOTICE] Adding a default content type to incoming service invocation requests is deprecated and will be removed in the future. See https://docs.dapr.io/operations/support/support-preview-features/ for more details. You can opt into the new behavior today by setting the configuration option `ServiceInvocation.NoDefaultContentType` to true.  app_id=nodeapp instance=romandeMacBook-Pro.local scope=dapr.runtime type=log ver=1.7.1
INFO[0000] application configuration loaded              app_id=nodeapp instance=romandeMacBook-Pro.local scope=dapr.runtime type=log ver=1.7.1
INFO[0000] actor runtime started. actor idle timeout: 1h0m0s. actor scan interval: 30s  app_id=nodeapp instance=romandeMacBook-Pro.local scope=dapr.runtime.actor type=log ver=1.7.1
INFO[0000] dapr initialized. Status: Running. Init Elapsed 212.087ms  app_id=nodeapp instance=romandeMacBook-Pro.local scope=dapr.runtime type=log ver=1.7.1
INFO[0000] placement tables updated, version: 0          app_id=nodeapp instance=romandeMacBook-Pro.local scope=dapr.runtime.actor.internal.placement type=log ver=1.7.1
ℹ️  Updating metadata for app command: node app.js
✅  You're up and running! Both Dapr and your app logs will appear here.

注意:--app-port(应用程序运行的端口)是可配置的。 Node 应用程序恰好在端口 3000 上运行,但您可以将其配置为在任何其他端口上运行。另请注意,Dapr --app-port 参数是可选的,如果未提供,则使用随机可用端口。

说明:

dapr run 命令查找默认组件目录,对于 Linux/MacOS 是 $HOME/.dapr/components,对于 Windows 是 %USERPROFILE%\.dapr\components,它包含 Dapr 将在运行时使用的组件的 yaml 定义文件。在本地运行时,为本地开发环境提供默认定义的 yaml 文件放置在此默认组件目录中。查看 components 目录中的 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 文件将状态存储定义为 Redis,并将其命名为 statestore。这是在 app.js 中用于调用应用程序中的状态存储的名称:

const stateStoreName = `statestore`;
const stateUrl = `http://localhost:${daprPort}/v1.0/state/${stateStoreName}`;

虽然在本教程中使用了默认 yaml 文件,但通常开发人员会根据应用程序和场景修改它们或创建自定义 yaml 定义。

可选:现在是熟悉 Dapr 仪表板的好时机。这是一个方便的界面,可以检查在 Dapr 上运行的应用程序的状态和信息。以下命令将使其在 http://localhost:9999/ 上可用。

Step 4 - Post messages to the service

现在 Dapr 和 Node.js 应用程序正在运行,您可以使用不同的工具针对它发送 POST 消息。注意:这里 POST 消息发送到端口 3500 - 如果您使用不同的端口,请务必相应地更新您的 URL。

首先,在新终端中使用 Dapr cli 发布消息:

dapr invoke --app-id nodeapp --method neworder --data-file sample.json

或者,使用curl:

curl -XPOST -d @sample.json -H Content-Type:application/json http://localhost:3500/v1.0/invoke/nodeapp/method/neworder

或者,使用 Visual Studio Code Rest 客户端插件

sample.http:

POST http://localhost:3500/v1.0/invoke/nodeapp/method/neworder

{
  "data": {
    "orderId": "42"
  }
}

您可以使用 Postman GUI。

打开 Postman 并针对 http://localhost:3500/v1.0/invoke/nodeapp/method/neworder 创建一个 POST 请求.

您的终端,您应该会看到指示已收到消息且状态已更新的日志:

 

Step 5 - Confirm successful persistence

现在,要验证订单是否成功保存到状态存储,请针对:http://localhost:3500/v1.0/invoke/nodeapp/method/order 创建一个 GET 请求。注意:同样,如果您选择了 3500 以外的端口,请务必反映正确的端口。

curl http://localhost:3500/v1.0/invoke/nodeapp/method/order

输出效果:

或者 使用 Dapr CLI 

dapr invoke --app-id nodeapp --method order --verb GET

或使用 Visual Studio Code Rest 客户端插件

sample.http

GET http://localhost:3500/v1.0/invoke/nodeapp/method/order

或使用Postman

这将调用 /order 路由,该路由调用 Redis 存储以获取最新数据。观察预期结果!

Step 6 - Run the Python app with Dapr

查看 ./hello-world/python 目录中的 Python 应用程序,了解另一个应用程序如何通过 Dapr 调用 Node 应用程序,而无需知道目标的主机名或端口。在 app.py 文件中,您可以找到通过 Dapr 调用 Node App 的端点定义。

dapr_port = os.getenv("DAPR_HTTP_PORT", 3500)
dapr_url = "http://localhost:{}/v1.0/invoke/nodeapp/method/neworder".format(dapr_port)

注意 URL 中节点应用程序的名称 (nodeapp) 很重要,它将允许 Dapr 将请求重定向到正确的 API 端点。此名称需要与本练习前面用于运行节点应用程序的名称相匹配。

下面的代码块显示了 Python 应用程序如何每秒增量地发布一个新的 orderId,或者如果发布调用失败则打印一个异常。

n = 0
while True:
    n += 1
    message = {"data": {"orderId": n}}

    try:
        response = requests.post(dapr_url, json=message)
    except Exception as e:
        print(e)

    time.sleep(1)

现在打开一个新终端并转到 ./hello-world/python 目录。

1.安装

pip3 install requests

2.启动

dapr run --app-id pythonapp python3 app.py

3.如果一切顺利,运行 Node 应用程序的另一个终端应该记录如下条目:

 已知问题:如果您从 Microsoft Store 在 Windows 上运行 python3,您会收到以下错误消息:

exec: "python3": executable file not found in %!P(MISSING)ATH%!(NOVERB)

这是由于 golang 无法正确执行 Microsoft Store 别名。您可以使用以下命令代替上述命令:

dapr run --app-id pythonapp cmd /c "python3 app.py"

4.现在,执行几次 GET 请求,看看 orderId 每秒如何变化(将其输入到 Web 浏览器,使用 Postman 或 curl): 

GET http://localhost:3500/v1.0/invoke/nodeapp/method/order
{
    "orderId": 3
}

注意:不需要在第二个终端中运行 dapr init,因为 dapr 最初已经在您的本地计算机上设置,再次运行此命令将失败。

Step 7 - Cleanup

要停止您的服务运行,只需停止“dapr run”进程。或者,您可以使用 Dapr CLI“停止”命令关闭每个服务。例如,要关闭这两个服务,请在新终端中运行以下命令:

dapr stop --app-id nodeapp
dapr stop --app-id pythonapp

要查看服务已停止运行,请运行 dapr list,注意您的服务不再出现!

总结:以上是通过本地,进行dapr的体验。此种方式,将业务开发与架构解耦,大大减少双方的工作量,但对应架构人员要求较高。期待在不久的将来,掌握dapr,实现一套自有的运行时体系。后面也会分享对应dapr的深入研究。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值