Dapr 与 NestJs ,实战编写一个 Pub & Sub 装饰器

网友投稿 736 2022-11-11

Dapr 与 Nestjs ,实战编写一个 Pub & Sub 装饰器

Dapr 与 NestJs ,实战编写一个 Pub & Sub 装饰器

Dapr 是一个可移植的、事件驱动的运行时,它使任何开发人员能够轻松构建出弹性的、无状态和有状态的应用程序,并可运行在云平台或边缘计算中,它同时也支持多种编程语言和开发框架。Dapr 确保开发人员专注于编写业务逻辑,不必分神解决分布式系统难题,从而显著提高了生产力。Dapr 降低了构建微服务架构类现代云原生应用的门槛。

系列

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

NodeJS 基于 Dapr 构建云原生微服务应用,从 0 到 1 快速上手指南

Dapr JavaScript SDK

用于在 JavaScript 和 TypeScript 中构建 Dapr 应用程序的客户端库。 该客户端抽象了公共 Dapr API,例如服务到服务调用、状态管理、发布/订阅、Secret 等,并为构建应用程序提供了一个简单、直观的 API。

安装

要开始使用 Javascript SDK,请从 NPM 安装 Dapr JavaScript SDK 包:

npm install --save @dapr/dapr

⚠️ dapr-client 现在已弃用。 请参阅#259 了解更多信息。

​​https://github.com/dapr/js-sdk/issues/259 ​​

结构

Dapr Javascript SDK 包含两个主要组件:

DaprServer: 管理所有 Dapr sidecar 到应用程序的通信。

DaprClient: 管理所有应用程序到 Dapr sidecar 的通信。

上述通信可以配置为使用 gRPC 或 HTTP 协议。

实战

创建一个小应用程序来生成有关网站中用户行为的统计信息。

Demo 源码

​​https://github.com/Hacker-Linner/dapr-nestjs-jssdk-decorator ​​

准备环境和项目结构

npm install -g @nestjs/cli

nest new api

mv api nest-dapr

cd nest-dapr

nest generate app page-view

npm install dapr-client

wget -q -O - | /bin/bash

创建一个 decorators.ts 文件(apps/shared/decorators.ts),这样所有微服务都可以从我们即将编写的基础架构中受益。

注入 Dapr 赖项

注入 DaprClient 和 DaprServer,我们需要提供它们到 nest.js。

在 app.module.ts 中让我们注册 DaprClient:

providers: [

...

{

provide: DaprClient,

useValue: new DaprClient()

}

]

在 page-view.module.ts 中以同样的方式添加 DaprServer:

providers: [

...

{

provide: DaprServer,

useValue: new DaprServer()

}

]

配置 Dapr 组件(rabbitMQ)

用 docker compose 启动 rabbitmq:

version: '3.9'

services:

pubsub:

image: rabbitmq:3-management-alpine

container_name: 'pubsub'

ports:

- 5674:5672

- 15674:15672 #web port

我们还需要配置 Dapr 组件。在根文件夹中创建一个 component/pubsub.yml:

apiVersion: dapr.io/v1alpha1

kind: Component

metadata:

name: pubsub

namespace: default

spec:

type: pubsub.rabbitmq

version: v1

metadata:

- name: host

value: 'amqp://guest:guest@localhost:5674'

每个 Dapr 微服务都需要自己的 config。

api/dapr/config.yml:

apiVersion: dapr.io/v1alpha1

kind: Configuration

metadata:

name: api

namespace: default

page-view/dapr/config.yml:

apiVersion: dapr.io/v1alpha1

kind: Configuration

metadata:

name: page-view

namespace: default

API/Gateway 服务

在 app.controller.ts 中,我们将公开一个简单的 API — /add-page-view。

@Post('/add-page-view')

async prderAdd(@Body() pageViewDto: PageViewDto): Promise {

try {

console.log(pageViewDto);

await this.daprClient.pubsub.publish('pubsub', 'page-view-add', pageViewDto);

} catch (e) {

console.log(e);

}

}

内部监听微服务

在我们将数据发布到队列之后,我们需要监听它并调用它:

在 page-view.controller.ts 添加:

@DaprPubSubSubscribe('pubsub', 'add')

addPageView(data: PageViewDto) {

console.log(`addPageView executed with data: ${JSON.stringify(data)}`);

this.data.push(data);

}

注意我们现在需要创建的新装饰器:@DaprPubSubscribe。

@DaprPubSubscribe 装饰器

在 shared/decorators.ts 中:

import { INestApplication } from '@nestjs/common';

import { DaprServer } from 'dapr-client';

export type PubsubMap = {

[pubSubName: string]: {

topic: string;

target: any;

descriptor: PropertyDescriptor;

};

};

export const DAPR_PUB_SUB_MAP: PubsubMap = {};

export const DaprPubSubSubscribe = (

pubSubName: string,

topic: string,

): MethodDecorator => {

return (target: any, propertyKey: string, descriptor: PropertyDescriptor) => {

DAPR_PUB_SUB_MAP[pubSubName] = {

topic,

target,

descriptor,

};

return descriptor;

};

};

export const useDaprPubSubListener = async (app: INestApplication) => {

const daprServer = app.get(DaprServer);

for (const pubSubName in DAPR_PUB_SUB_MAP) {

const item = DAPR_PUB_SUB_MAP[pubSubName];

console.log(

`Listening to the pubsub name - "${pubSubName}" on topic "${item-ic}"`,

);

await daprServer.pubsub.subscribe(

pubSubName,

item-ic,

async (data: any) => {

const targetClassImpl = app.get(item.target.constructor);

await targetClassImpl[item.descriptor.value.name](data);

},

);

}

};

运行应用程序

运行:

docker-compose up -d # 启动 rabbitmq

npm run dapr:api:dev # 启动 api/gateway

npm run page-view:dev # 启动内部微服务监听 dapr rabbitmq 队列

执行请求:

curl --location --request POST '\

--header 'Content-Type: application/json' \

--data-raw '{

"pageUrl" : ""Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0"

}'

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Superset的搭建与使用
下一篇:LeetCode Excel Sheet Column Title
相关文章

 发表评论

暂时没有评论,来抢沙发吧~