微服务基本概念:微服务就是将一个项目拆分成多个服务。举个简单的例子:将网站的登录功能可以拆分出来做成一个服务。
微服务分为提供者和消费者,如上“登录服务”就是一个服务提供者,“网站服务器”就是一个服务消费者(服务客户端)。
你可能注意到了客户端和网站服务器通信使用的是http,为什么服务器之间使用的是tcp,这主要和性能、传输灵活度相关。
在nestjs中传输方式还有很多中,比如通过grpc、rabbitmq、redis等技术来传输数据。
补充:登录服务可以部署在同一台服务器也可以在其他服务器,但只要拆分出来了就称之为微服务。
首先保证你全局安装了nestjs脚手架 npm i -g @nestjs/cli
创建nestjs项目,如下代码我将会使用monorepo模式,如果你还不太熟悉这是官网地址:https://docs.nestjs.com/cli/monorepo#monorepo-mode
或者你也可以直接按照我如下步骤操作
nest new my-app
:创建一个nestjs的项目,自行选择包管理器cd my-app
:进入my-app目录nest generate app rpc-provider
:把当前项目转化为monorepo模式,并创建rpc-provider
项目(提供者)nest generate app rpc-consumer
:创建消费者pnpm i
:安装依赖pnpm i @nestjs/microservices
:安装微服务需要的包补充启动方式:npm run start:dev rpc-provider
1.3.1 apps/rpc-provider/src/main.ts
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 apps/rpc-provider/src/rpc-provider.controller.ts
说明:nestjs中微服务提供了两种模式
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 apps/rpc-consumer/src/rpc-consumer.module.ts
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 apps/rpc-consumer/src/rpc-consumer.controller.ts
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();
}
}
有疑问欢迎在文章下留言,看到了我就会回答