Docker?Compose+Nestjs構(gòu)建Dapr?Redis發(fā)布訂閱分布式應用
Dapr(分布式應用程序運行時)介紹
Dapr 是一個可移植的、事件驅(qū)動的運行時,它使任何開發(fā)人員能夠輕松構(gòu)建出彈性的、無狀態(tài)和有狀態(tài)的應用程序,并可運行在云平臺或邊緣計算中,它同時也支持多種編程語言和開發(fā)框架。
Dapr 官網(wǎng):dapr.io/
實戰(zhàn) Dapr 的 Redis 發(fā)布/訂閱應用
1. 創(chuàng)建項目
首先,我們將創(chuàng)建我們的項目根文件夾來托管我們將在后續(xù)步驟中創(chuàng)建的所有服務。
mkdir dapr-nestjs-redis-pub-sub
2. 創(chuàng)建 Dapr Placement 服務
由于我們將創(chuàng)建多個服務,我們將使用 docker-compose
來運行這些服務。
讓我們在項目的根文件夾中創(chuàng)建 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
(我們的服務)之間的所有通信。
簡單來說,它負責將所有通信路由到假設(shè)接收通信的相應 actor
。它充當 message broker
(消息代理)。
3. 創(chuàng)建 Redis Publish 服務
讓我們繼續(xù)通過添加我們的 Redis
服務來修改我們的 docker-compose.yml
文件。
將以下代碼添加到 docker-compose.yml
的服務部分:
redis-publisher: image: redis restart: always depends_on: - dapr-placement
4. 創(chuàng)建 Dapr Pub-Sub 組件
創(chuàng)建一個 dapr/components
文件夾。然后創(chuàng)建組件文件 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-pubsub namespace: default spec: type: pubsub.redis version: v1 metadata: - name: redisHost value: redis-publisher:6379 - name: redisPassword value: ""
redisHost
是我們的 Redis
服務 redis-pub
的名稱,默認 Redis
端口為 6379
。
5. 創(chuàng)建 Redis Dapr Sidecar
正如前面部分反復提到的,服務直接與 Dapr
通信,而不是直接與其他服務通信。Dapr
充當所有服務的中間人。
服務通過它們自己的 Dapr sidecar
直接與 Dapr
通信,Dapr sidecar
將通信傳遞給 Dapr placement
,該 placement
再次將其傳遞給假設(shè)接收通信的服務的 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-publisher network_mode: "service:redis-publisher"
在這里,我們使用 app-id
將 Dapr sidecar
分配給 redis-publisher
,同時我們使用 redis
端口 6379
。
我們還必須將 dapr/components(redis-pubsub.yaml) 文件夾掛載到 docker
容器中。
不要忘記聲明 dapr-http-port
。這是我們的 Dapr sidecar
的 api
,允許我們調(diào)用各種 HTTP
方法。
定義您的 dapr-http-port
很重要,因為您將在此處調(diào)用各種 HTTP 調(diào)用/方法/請求。
最后,注意將 redis-dapr-sidecar
附加到 redis-publisher
網(wǎng)絡(luò)命名空間。
6. 創(chuàng)建 NestJS Server
我們將使用 NestJS
作為我們的 node server
作為我們的 Redis subscriber(訂閱者)。
進入到項目文件夾
cd dapr-nestjs-redis-pub-sub
然后執(zhí)行以下命令設(shè)置一個 NestJS node server
:
npm i -g @nestjs/cli nest new nest-subscriber
對于這個項目,我們將選擇 yarn
作為包管理器。
接下來,我們將設(shè)置一個 post API
端點。 Dapr
將調(diào)用這個端點,一旦它收到我們的 Redis
服務發(fā)布,它就被調(diào)用。
轉(zhuǎn)到 nest-subscriber/src/app.controller.ts
將此文件中的代碼替換為以下內(nèi)容:
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 發(fā)布了 ${JSON.stringify(reqBody)} `); return `NestJS 訂閱者收到的 ${reqBody} 發(fā)布`; } }
7. 為 NestJS 訂閱服務器創(chuàng)建 Dockerfile
我們將 NestJS
服務器作為 Docker
容器運行。需要創(chuàng)建一個 Dockerfile
。
cd nest-subscriber touch Dockerfile
然后打開文件并粘貼以下代碼:
FROM node:16.13.0-alpine WORKDIR "/app" COPY ./nest-subscriber/package.json ./ RUN yarn install COPY ./nest-subscriber . RUN yarn run build EXPOSE 3000 CMD ["yarn","start:prod"]
構(gòu)建鏡像:
docker build -f ./nest-subscriber/Dockerfile -t nest-subscriber:latest . --no-cache
8. 將 NestJS 訂閱服務添加到 docker-compose 文件
在創(chuàng)建了我們的 NestJS
服務器和 Dockerfile
之后,我們創(chuàng)建了 nest-subscriber
docker
服務。
將以下內(nèi)容添加到 docker-compose.yml
:
nest-subscriber: image: "nest-subscriber:latest" depends_on: - redis-publisher - dapr-placement restart: always
9. 創(chuàng)建 Dapr 訂閱
我們將為我們的 pub/sub
訂閱定義配置。
創(chuàng)建一個 dapr/subscriptions
文件夾。然后創(chuàng)建組件文件 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-topic route: /redis-publisher pubsubname: redis-pubsub scopes: - nest-subscriber
路由是發(fā)布 topic
時 Dapr
將調(diào)用的 API
scope
是訂閱該 topic
的服務。
pubsubname
是 redis-pubsub,它等于我們的 redis-pubsub.yaml
文件中定義的元數(shù)據(jù)名稱。
在這個項目中,如果發(fā)布了一個 topic nest-redis-pub-topic
,Dapr 將在我們的 nest-subscriber
服務中調(diào)用 API /redis-publisher
。
10. 創(chuàng)建 NestJS 服務器 Dapr Sidecar
我們需要為我們的 NestJS
服務創(chuàng)建一個 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-subscriber network_mode: "service:nest-subscriber"
11. 測試它是否有效
通常 Dapr Docker
容器會在 Docker
網(wǎng)絡(luò)中進行通信。
但是為了我們做測試,我們將打開映射暴露端口 5000
到我們的本地機器 5001
。
redis-publisher: image: redis depends_on: - dapr-placement restart: always ports: - 5001:5000
然后在您的終端中執(zhí)行以下命令:
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
的優(yōu)點之一是它遵循特定的 URL
格式。這里我們只使用 Dapr sidecar HTTP 端口(5001),然后是版本號(v1.0),然后是 action(publish)。然后是我們 redis-pubsub.yaml 配置文件中定義的 pubsubname
(redis-pubsub
)和 topic
(nest-redis-pub-topic)。
一旦發(fā)出 HTTP post
請求。我們的 NestJS
服務器應該在 /redis-publisher 收到一個 post
請求,這將導致以下日志:
我們可以看到它正在通過 Dapr
接收 Redis
發(fā)布。但是我們的 NestJS
服務器無法正確處理消息。
只有 {}
被發(fā)布,而不是我們發(fā)布的消息。
我們將在下一步中解決這個問題。
注意:我們通過 redis-dapr-sidecar 的 dapr-http-port 調(diào)用發(fā)布服務。通常會有一個單獨的 Docker
服務(例如另一個服務器),它有自己的 Dapr sidecar
,它將調(diào)用 redis
發(fā)布服務。 在這種情況下,我們將使用該 Docker
服務的 Dapr sidecar http-port。該請求將由 sidecar
發(fā)送到 Dapr placement
服務,然后該服務將確定將請求轉(zhuǎn)發(fā)到的正確 Dapr sidecar
。
12. 允許 NestJS 解析 application/cloudevents+json
我們的 nest-subscriber-dapr-sidecar 向我們的 nest-subscriber
服務器發(fā)出的 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();
當我們再次發(fā)送 post
請求時,我們的 NestJS
服務器將能夠處理請求正文并顯示以下日志:
好了,我們現(xiàn)在有一個基于 Dapr
工作的 Redis Pub/Sub
分布式應用。
13. 完整 docker-compose.yaml
version: "3.5" services: dapr-placement: image: "daprio/dapr" command: ["./placement", "-port", "50006"] redis-publisher: image: redis depends_on: - dapr-placement restart: always ports: - 5001:5000 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-publisher network_mode: "service:redis-publisher" nest-subscriber: image: "nest-subscriber:latest" depends_on: - redis-publisher - dapr-placement restart: always 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-subscriber network_mode: "service:nest-subscriber"
以上就是Docker Compose+Nestjs構(gòu)建Dapr Redis發(fā)布訂閱分布式應用的詳細內(nèi)容,更多關(guān)于Docker Nestjs構(gòu)建Redis分布式的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
淺談docker Dockerfile 指令 VOLUME 介紹
本篇文章主要介紹了淺談docker Dockerfile 指令 VOLUME 介紹 ,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-02-02Docker安裝Nginx并部署及MySQL容器構(gòu)建全過程
眾所周知Docker是一種容器化技術(shù),可以用來快速部署和管理應用程序,這篇文章主要給大家介紹了關(guān)于Docker安裝Nginx并部署及MySQL容器構(gòu)建的相關(guān)資料,需要的朋友可以參考下2024-02-02