NestJS的微服务实现

微服务基本概念:微服务就是将一个项目拆分成多个服务。举个简单的例子:将网站的登录功能可以拆分出来做成一个服务。

微服务分为提供者和消费者,如上"登录服务"就是一个提供者,"网站服务器"就是一个消费者。

你可能注意到了客户端和网站服务器通信使用的是http,为什么服务器之间使用的是tcp,这主要和性能、传输灵活度相关。

在nestjs中传输方式还有很多中,比如通过grpc、rabbitmq、redis等技术来传输数据。

补充:登录服务可以部署在同一台服务器也可以在其他服务器,但只要拆分出来了就称之为微服务。

1.2 搭建提供者和消费者

首先保证你全局安装了nestjs脚手架 npm i -g @nestjs/cli

创建nestjs项目,如下代码我将会使用monorepo模式,如果你还不太熟悉这是官网地址:docs.nestjs.com/cli/monorep...

或者你也可以直接按照我如下步骤操作

  1. nest new my-app:创建一个nestjs的项目,自行选择包管理器
  2. cd my-app:进入my-app目录
  3. nest generate app rpc-provider:把当前项目转化为monorepo模式,并创建rpc-provider项目(提供者)
  4. nest generate app rpc-consumer:创建消费者
  5. pnpm i:安装依赖
  6. pnpm i @nestjs/microservices:安装微服务需要的包

1.3 实现微服务提供者

1.3.1 app/rpc-provider/src/main.ts

typescript 复制代码
import { NestFactory } from '@nestjs/core';
import { RpcProviderModule } from './rpc-provider.module';
import { MicroserviceOptions, Transport } from '@nestjs/microservices';
​
// 创建微服务
async function bootstrap() {
  const app = await NestFactory.createMicroservice<MicroserviceOptions>(
    RpcProviderModule,
    {
      transport: Transport.TCP,
      options: {
        host: '127.0.0.1',
        port: 2999,
      },
    },
  );
  await app.listen();
}
bootstrap();

1.3.2 app/rpc-provider/src/rpc-provider.controller.ts

说明:nestjs中微服务提供了两种模式

  • MessagePattern:基于请求-响应的消息处理程序
  • EventPattern:基于发布-订阅的消息处理程序,此方式是不需要做出响应的
typescript 复制代码
import { Controller, Get } from '@nestjs/common';
import { RpcProviderService } from './rpc-provider.service';
import { EventPattern, MessagePattern } from '@nestjs/microservices';
​
@Controller()
export class RpcProviderController {
  constructor(private readonly rpcProviderService: RpcProviderService) {}
​
  @MessagePattern('calc')
  async accumulate(nums: number[]): Promise<number> {
    console.log('微服务提供者 MessagePattern', nums);
    return await new Promise((resolve) => {
      setTimeout(() => {
        resolve(nums.reduce((pre, cur) => pre + cur, 0));
      }, 10);
    });
  }
​
  @EventPattern('notice')
  handleUserCreated(data: string): void {
    console.log('微服务提供者 EventPattern', data);
  }
​
  @Get()
  getHello(): string {
    return this.rpcProviderService.getHello();
  }
}

1.4 实现微服务消费者

1.4.1 app/rpc-consumer/src/rpc-consumer.module.ts

typescript 复制代码
import { Module } from '@nestjs/common';
import { RpcConsumerController } from './rpc-consumer.controller';
import { RpcConsumerService } from './rpc-consumer.service';
import { ClientsModule, Transport } from '@nestjs/microservices';
​
@Module({
  imports: [
    // 注册服务
    ClientsModule.register([
      {
        name: 'MATH_SERVICE', //给该服务取一个名字
        transport: Transport.TCP, //服务传输方式
        options: {
          host: '127.0.0.1',
          port: 2999,
        },
      },
    ]),
  ],
  controllers: [RpcConsumerController],
  providers: [RpcConsumerService],
})
export class RpcConsumerModule {}

1.4.2 app/rpc-consumer/src/rpc-consumer.controller.ts

typescript 复制代码
import { Body, Controller, Get, Inject, Post } from '@nestjs/common';
import { RpcConsumerService } from './rpc-consumer.service';
import { ClientProxy } from '@nestjs/microservices';
import { Observable } from 'rxjs';
​
@Controller()
export class RpcConsumerController {
  constructor(
    private readonly rpcConsumerService: RpcConsumerService,
    @Inject('MATH_SERVICE') private client: ClientProxy,
  ) {}
​
  @Post()
  // 说明:Observable是一个可被观察的流,需要安装rxjs(pnpm i rxjs)
  callService(@Body('nums') nums: number[]): Observable<number> {
    // emit调用EventPattern
    this.client.emit('notice', 'xxx');
    // 返回的是一个Observable对象
    return this.client.send<number>('calc', nums);
  }
​
  @Get()
  getHello(): string {
    return this.rpcConsumerService.getHello();
  }
}

有疑问欢迎在文章下留言,看到了我就会回答

相关推荐
wn53129 分钟前
【Go - 类型断言】
服务器·开发语言·后端·golang
m0_6355022034 分钟前
Spring Cloud Gateway组件
网关·微服务·负载均衡·过滤器
希冀1231 小时前
【操作系统】1.2操作系统的发展与分类
后端
GoppViper1 小时前
golang学习笔记29——golang 中如何将 GitHub 最新提交的版本设置为 v1.0.0
笔记·git·后端·学习·golang·github·源代码管理
爱上语文2 小时前
Springboot的三层架构
java·开发语言·spring boot·后端·spring
serve the people2 小时前
springboot 单独新建一个文件实时写数据,当文件大于100M时按照日期时间做文件名进行归档
java·spring boot·后端
罗政8 小时前
[附源码]超简洁个人博客网站搭建+SpringBoot+Vue前后端分离
vue.js·spring boot·后端
拾光师9 小时前
spring获取当前request
java·后端·spring
Java小白笔记11 小时前
关于使用Mybatis-Plus 自动填充功能失效问题
spring boot·后端·mybatis
nbsaas-boot11 小时前
微服务之间的安全通信
安全·微服务·架构