Dapr(分布式应用程序运行时)介绍

Dapr 是一个可移植的、事件驱动的运行时,它使任何开发人员能够轻松构建出弹性的、无状态和有状态的应用程序,并可运行在云平台或边缘计算中,它同时也支持多种编程语言和开发框架。

Dapr 官网:https://dapr.io/

实战 Dapr 的 Redis 发布/订阅应用

1. 创建项目

首先,我们将创建我们的项目根文件夹来托管我们将在后续步骤中创建的所有服务。

mkdir dapr-nestjs-redis-pub-sub

2. 创建 Dapr Placement 服务

由于我们将创建多个服务,我们将使用 docker-compose 来运行这些服务。

让我们在项目的根文件夹中创建 docker-compose.yml 文件

cd dapr-nestjs-redis-pub-sub
touch docker-compose.yml
version: "3.5"services:dapr-placement:image: "daprio/dapr"command: ["./placement", "-port", "50006"]

Dapr placement 服务将负责管理 Dapr actors(我们的服务)之间的所有通信。

简单来说,它负责将所有通信路由到假设接收通信的相应 actor。它充当 message broker(消息代理)。

3. 创建 Redis Publish 服务

让我们继续通过添加我们的 Redis 服务来修改我们的 docker-compose.yml 文件。

将以下代码添加到 docker-compose.yml 的服务部分:

redis-publisher: image: redisrestart: alwaysdepends_on:- dapr-placement

4. 创建 Dapr Pub-Sub 组件

创建一个 dapr/components 文件夹。然后创建组件文件 redis-pubsub.yaml

mkdir -p dapr/components
cd dapr/components
touch redis-pubsub.yaml

然后打开文件并插入我们的 Dapr pub/sub 组件的详细信息

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:name: redis-pubsubnamespace: default
spec:type: pubsub.redisversion: v1metadata:- name: redisHostvalue: redis-publisher:6379- name: redisPasswordvalue: ""

redisHost 是我们的 Redis 服务 redis-pub 的名称,默认 Redis 端口为 6379

5. 创建 Redis Dapr Sidecar

正如前面部分反复提到的,服务直接与 Dapr 通信,而不是直接与其他服务通信。Dapr 充当所有服务的中间人。

服务通过它们自己的 Dapr sidecar 直接与 Dapr 通信,Dapr sidecar 将通信传递给 Dapr placement,该 placement 再次将其传递给假设接收通信的服务的 Dapr sidecar

redis-dapr-sidecar 服务添加到我们的 docker-compose.yml

redis-dapr-sidecar:image: "daprio/daprd:edge"command: ["./daprd","-app-id","redis-publisher","-app-port","6379","-dapr-http-port","5000","-components-path","/components","-placement-host-address","dapr-placement:50006"]volumes: - "./dapr/components/:/components"depends_on:- redis-publishernetwork_mode: "service:redis-publisher"

在这里,我们使用 app-idDapr sidecar 分配给 redis-publisher,同时我们使用 redis 端口 6379

我们还必须将 dapr/components(redis-pubsub.yaml) 文件夹挂载到 docker 容器中。

不要忘记声明 dapr-http-port。这是我们的 Dapr sidecarapi,允许我们调用各种 HTTP 方法。

定义您的 dapr-http-port 很重要,因为您将在此处调用各种 HTTP 调用/方法/请求

最后,注意将 redis-dapr-sidecar 附加到 redis-publisher 网络命名空间。

6. 创建 NestJS Server

我们将使用 NestJS 作为我们的 node server 作为我们的 Redis subscriber(订阅者)

进入到项目文件夹

cd dapr-nestjs-redis-pub-sub

然后执行以下命令设置一个 NestJS node server:

npm i -g @nestjs/cli
nest new nest-subscriber

对于这个项目,我们将选择 yarn 作为包管理器。

接下来,我们将设置一个 post API 端点。Dapr 将调用这个端点,一旦它收到我们的 Redis 服务发布,它就被调用。

转到 nest-subscriber/src/app.controller.ts

将此文件中的代码替换为以下内容:

import { Controller, Post, Body } from '@nestjs/common';
import { AppService } from './app.service';@Controller()
export class AppController {constructor(private readonly appService: AppService) {}@Post('/redis-publisher')async postRedisPub(@Body() reqBody) {console.log(`Redis 发布了 ${JSON.stringify(reqBody)} `);return `NestJS 订阅者收到的 ${reqBody} 发布`;}
}

7. 为 NestJS 订阅服务器创建 Dockerfile

我们将 NestJS 服务器作为 Docker 容器运行。需要创建一个 Dockerfile

cd nest-subscriber
touch Dockerfile

然后打开文件并粘贴以下代码:

FROM node:16.13.0-alpineWORKDIR "/app"
COPY ./nest-subscriber/package.json ./
RUN yarn install
COPY ./nest-subscriber .
RUN yarn run buildEXPOSE 3000
CMD ["yarn","start:prod"]

构建镜像:

docker build -f ./nest-subscriber/Dockerfile -t nest-subscriber:latest . --no-cache

8. 将 NestJS 订阅服务添加到 docker-compose 文件

在创建了我们的 NestJS 服务器和 Dockerfile 之后,我们创建了 nest-subscriber docker 服务。

将以下内容添加到 docker-compose.yml

nest-subscriber:image: "nest-subscriber:latest"depends_on:- redis-publisher - dapr-placement restart: always

9. 创建 Dapr 订阅

我们将为我们的 pub/sub 订阅定义配置。

创建一个 dapr/subscriptions 文件夹。然后创建组件文件 redis-subscription.yaml

mkdir -p dapr/subscriptions
cd dapr/subscriptions
touch redis-subscription.yaml

然后打开文件并插入我们的 Dapr 订阅组件的详细信息

apiVersion: dapr.io/v1alpha1
kind: Subscription
metadata:name: nest-redis-sub
spec:topic: nest-redis-pub-topicroute: /redis-publisherpubsubname: redis-pubsub
scopes:- nest-subscriber

路由是发布 topicDapr 将调用的 API

scope 是订阅该 topic 的服务。

pubsubnameredis-pubsub,它等于我们的 redis-pubsub.yaml 文件中定义的元数据名称。

在这个项目中,如果发布了一个 topic nest-redis-pub-topic,Dapr 将在我们的 nest-subscriber 服务中调用 API /redis-publisher

10. 创建 NestJS 服务器 Dapr Sidecar

我们需要为我们的 NestJS 服务创建一个 sidecar,就像 redis-publisher 服务一样。

nest-subscriber-dapr-sidecar 服务添加到我们的 docker-compose.yml

nest-subscriber-dapr-sidecar:image: "daprio/daprd:edge"command: ["./daprd","-app-id","nest-subscriber","-app-port","3000",      "-components-path","/components","-placement-host-address","dapr-placement:50006", ]volumes:- "./dapr/components/:/components" depends_on:- nest-subscribernetwork_mode: "service:nest-subscriber"

11. 测试它是否有效

通常 Dapr Docker 容器会在 Docker 网络中进行通信。

但是为了我们做测试,我们将打开映射暴露端口 5000 到我们的本地机器 5001

redis-publisher: image: redisdepends_on:- dapr-placementrestart: alwaysports:- 5001:5000

然后在您的终端中执行以下命令:

curl --location --request POST 'http://localhost:5001/v1.0/publish/redis-pubsub/nest-redis-pub-topic' \
--header 'Content-Type: application/json' \
--data-raw '{"hello": "world"
}'

Dapr 的优点之一是它遵循特定的 URL 格式。这里我们只使用 Dapr sidecar HTTP 端口(5001),然后是版本号(v1.0),然后是 action(publish)。然后是我们 redis-pubsub.yaml 配置文件中定义的 pubsubname(redis-pubsub)和 topic(nest-redis-pub-topic)。

一旦发出 HTTP post 请求。我们的 NestJS 服务器应该在 /redis-publisher 收到一个 post 请求,这将导致以下日志:

我们可以看到它正在通过 Dapr 接收 Redis 发布。但是我们的 NestJS 服务器无法正确处理消息。

只有 {} 被发布,而不是我们发布的消息。

我们将在下一步中解决这个问题。

注意:我们通过 redis-dapr-sidecardapr-http-port 调用发布服务。通常会有一个单独的 Docker 服务(例如另一个服务器),它有自己的 Dapr sidecar,它将调用 redis 发布服务。 在这种情况下,我们将使用该 Docker 服务的 Dapr sidecar http-port。该请求将由 sidecar 发送到 Dapr placement 服务,然后该服务将确定将请求转发到的正确 Dapr sidecar

12. 允许 NestJS 解析 application/cloudevents+json

我们的 nest-subscriber-dapr-sidecar 向我们的 nest-subscriber 服务器发出的 post 请求的 Content-Type 将是 application/cloudevents+json 而不是 application/json

目前我们的 NestJS 服务器无法解析 application/cloudevents+json

为了解决这个问题,我们首先需要安装 body-parser

cd nest-subscriber
yarn add body-parser

接下来我们需要修改我们的 NestJS 服务器 main.ts

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import * as bodyParser from 'body-parser';async function bootstrap() {const app = await NestFactory.create(AppModule);app.use(bodyParser.json({ type: 'application/cloudevents+json' }));app.use(bodyParser.json());await app.listen(3000);
}bootstrap();

当我们再次发送 post 请求时,我们的 NestJS 服务器将能够处理请求正文并显示以下日志:

好了,我们现在有一个基于 Dapr 工作的 Redis Pub/Sub 分布式应用。

13. 完整 docker-compose.yaml

version: "3.5"services:dapr-placement:image: "daprio/dapr"command: ["./placement", "-port", "50006"]redis-publisher: image: redisdepends_on:- dapr-placementrestart: alwaysports:- 5001:5000redis-dapr-sidecar:image: "daprio/daprd:edge"command: ["./daprd","-app-id","redis-publisher","-app-port","6379","-dapr-http-port","5000","-components-path","/components","-placement-host-address","dapr-placement:50006"]volumes: - "./dapr/components/:/components"depends_on:- redis-publishernetwork_mode: "service:redis-publisher"nest-subscriber:image: "nest-subscriber:latest"depends_on:- redis-publisher - dapr-placement restart: alwaysnest-subscriber-dapr-sidecar:image: "daprio/daprd:edge"command: ["./daprd","-app-id","nest-subscriber","-app-port","3000",      "-components-path","/components","-placement-host-address","dapr-placement:50006", ]volumes:- "./dapr/components/:/components" depends_on:- nest-subscribernetwork_mode: "service:nest-subscriber"

14. 源码

https://github.com/Hacker-Linner/dapr-nestjs-redis-pub-sub.git

更多

使用 Dapr JS SDK 让 Nest.js 集成 Dapr

本地使用 Docker Compose 与 Nestjs 快速构建基于 Dapr 的 Redis 发布/订阅分布式应用...相关推荐

  1. win10本地利用docker搭建FATE【快速方法】

    win10本地利用docker搭建FATE[快速方法] 本文介绍如何利用docker快速搭建FATE(需要的前期准备:安装win10对应版本的docker) 1.启动任意docker,与本地地址相映射 ...

  2. Docker Compose部署项目到容器-基于Tomcat和mysql的项目yml配置文件代码

    场景 Docker-Compose简介与Ubuntu Server 上安装Compose: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/deta ...

  3. 【转】使用PowerApps快速构建基于主题的轻业务应用 —— 进阶篇

    在上一篇 使用PowerApps快速构建基于主题的轻业务应用 -- 入门篇 中,我用了三个实际的例子演示了如何快速开始使用PowerApps构建轻业务应用,你可能已经发现,我都是使用默认生成的设置,没 ...

  4. 【转】使用PowerApps快速构建基于主题的轻业务应用 —— 入门篇

    前言 在上一篇文章 基于Office 365的随需应变业务应用平台 中我提到,随着随需应变的业务需要,以及技术的发展,业务应用的开发的模式也有了深刻的变化.基于微软的平台,有服务于主干业务应用的Dyn ...

  5. Docker Compose部署项目到容器-基于Tomcat和mysql的商城项目(附源码和sql下载)

    场景 Docker-Compose简介与Ubuntu Server 上安装Compose: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/deta ...

  6. docker部署springboot_Docker+SpringBoot快速构建和部署应用

    前言 Docker技术发展为当前流行的微服务提供了更加便利的环境,使用SpringBoot+Docker部署和发布应用,其实也是一件比较简单的事情.当前,前提是得有Docker的基础. 构建一个Spr ...

  7. .NET遇上Docker - 使用Docker Compose组织Ngnix和.NETCore运行

    本文工具准备: Docker for Windows Visual Studio 2015 与 Visual Studio Tools for Docker 或 Visual Studio 2017 ...

  8. Docker 之Docker Compose 介绍

    文章目录 使用Docker Compose之前的项目搭建 构建一个Python的应用的image 创建composetest文件夹 在 /tmp/composetest文件夹下 创建app.py文件 ...

  9. Ubuntu Server 上使用Docker Compose 部署Nexus(图文教程)

    场景 Docker-Compose简介与Ubuntu Server 上安装Compose: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/deta ...

最新文章

  1. matplotlib的安装
  2. JZOJ 5638. 【NOI2018模拟4.8】IIIDX
  3. [转载]----linux系统工程师的前途在哪里?
  4. ssl1063-统计数字【哈希表】
  5. Struts1和Struts2的区别和对比(完整版)(转)
  6. fileitem方法_FileItem类的常用方法(关于文件上传的)
  7. 排名前100的PHP函数及分析
  8. Oracle 20c 新特性:DIAGNOSTICS_CONTROL 对诊断事件的安全管控
  9. 不说“安全”俩字,如何证明自己是做安全的?
  10. Oracle11gr2新增APPEND_VALUES提示
  11. 拓端tecdat|R语言主成分分析(PCA)葡萄酒可视化:主成分得分散点图和载荷图
  12. vsftpd安装与配置
  13. 碰撞检测之 AABB 包围盒
  14. [从零开始学习FPGA编程-22]:进阶篇 - 架构 - FPGA内部硬件电路的设计与建模
  15. 最大面额钞票10的21次方
  16. 什么是MTTF、MTBF、MTRF?
  17. [SAP ABAP开发技术总结]SD销售订单定价过程
  18. atitit 音频 项目 系列功能表 音乐 v3 t67.docx Atitit 音频 项目 系列功能表 1.音频 音乐 语言领域的功能表 听歌识曲功能 酷我功能。 铃声 功能。。 音频切割(按
  19. 深度学习之图像分类(二十五)-- S2MLPv2 网络详解
  20. 响应式布局详解(优缺点)

热门文章

  1. 天线理论知识4——非频变天线
  2. Windows与Linux端口占用的解决方案
  3. 常用几个空格的 Unicode 码
  4. php.cm,一个关于熊掌号的APP
  5. 接入滴滴打车html5 网页版,接入滴滴打车html5 网页版
  6. 装饰器/使用类和对象封装一个工具类
  7. [烹饪成就]BL特有烹饪配方
  8. 【实例分割论文】 SOLO:Segmenting Objects by Locations(更新代码)
  9. SDAE--随读笔记
  10. Salesforce中国区解散,谁是替代的最佳选择?