此文章仅考虑的是 NextJS Microservice 场景下,对于其他情况暂时不做解释,按理来说应该你也能理解。
此外,这篇文章使用的是 Redis 作为传输层,你需要知道基本操作才能来看此文章,并且此文章仅讲述交互原理。
创建一个微服务模块
使用 nest g app tester NestJS CLI 将会自动帮你创建对应的模块,但是你需要自己修改部分内容,比如在 main.ts,你需要将 create 替换为 createMicroservice,还有其他的,但是需要注意的是,请将 transporter 设置为 REDIS
接下来我们使用 redis-cli 来监控事件变化
使用微服务订阅事件
与 @nestjs/common 中不一样的 @Get(),你需要使用在 microservices 包内的 MessagePattern,以下是一个示范
接下来,启动这个微服务,注意一下上方 redis-cli monitor 出现的日志
看样子我们找到了一个开始订阅的事件,让我们记住这一个事件,继续下去。
后续,我将使用
user.get.master来代替get.something事件另外,这种事件命名方式并不是必须的,这只是我个人习惯
在网关层订阅事件
你需要在网关层模块中导入一个 ClientModule:
之后在 controller 构造函数中注入它,再任意搞一个请求:
让我们继续启动网关层,redis-cli monitor 此时不会出现任何日志,这是正常的
当收到请求时,事件发生了什么变化
我们访问一下网关层中配置的路径,注意一下 redis-cli monitor 出现的日志:
这日志有点辣眼睛,而且这个是我们开了网关层 & 微服务出现的日志,我们暂时只想知道网关层,我们将上面的微服务关掉,再访问一次:
我们精简一下,将无用的数据去掉,只留下我们想要的东西吧:
可以看到网关层先订阅了一个基于之前我们定义的 user.get.master 的 reply 事件,之后,在 user.get.master 事件上发布了数据,就是将 pattern, data, id 发布了,十分重要的就是这个id,这是网关层中传输来的。
对比一下,你就可以知道其中有一个特别长的日志就是由微服务发布的,可以发现微服务是向 reply 事件发布了事件,内容还包含了之前我们提到的 id,之后网关层收到了数据返回,接着返回来自微服务的数据,取消订阅对应的事件
让我们用一个图来解释下吧:
总结一下,其实就是这样的:

SCR-20230109-nrl
快速使用 NodeJS 启动一个微服务
使用 pnpm 安装上 redis,根据上方我所说的内容,抽出来一些功能函数,以提高可维护性。
因为 NestJS 文档 有说到两种模式,分别是 message 和 event,因此我们需要做一个判定和快捷生成对应的 pattern:
我们分析一下信息的结构吧,很明显来自Gateway的信息带有3个key:pattern, data, id,其中 id 是自动生成的,也是返回响应时必要的;
再分析一下NestJS Microservice 是怎么响应的,它的信息也带有3个key:response, isDispose, id,其中 isDispose 必须为 true,id 必须是来自 Gateway 的。
所以剩下的就是创建 redis client 和发布/订阅事件了,需要注意的是,返回给 Gateway 的信息需要在事件后加上.reply,你在 monitor 上也能看到 Gateway 在发布事件的时候会同时订阅对应的reply事件:
这样便是一个简单易启动的服务啦!使用 node^18 更可以使用其实验性功能:--watch 直接监听文件变化重载程序

注意事项
注意的是:一个事件只能由一个服务受理,否则则会出现冲突情况。别问我问什么,问就是写的时候卡这个问题了。但是一个事件(Event-based)可以调度到多个方法
You can register multiple event handlers for a single event pattern and all of them will be automatically triggered in parallel. -- NestJS Documentaion