乐闻世界logo
搜索文章和话题
一篇文章学会 NestJS 如何支持微服务

一篇文章学会 NestJS 如何支持微服务

乐闻的头像
乐闻

2024年01月05日 10:36· 阅读 1328

前言

在软件开发的世界里,微服务架构是一个经常被提及的概念。但它到底是什么意思呢?为什么现在这么多团队和公司选择使用微服务?而NestJS又是如何帮助开发者构建微服务的?

什么是微服务

想象一下,你想建一座大厦。你可以选择由一间强大的公司全权负责,从地基到尖塔的每一部分;另一种方法是,你选择多间专业的小公司,一家负责电梯,一家负责供电系统等等。每间公司都是建筑部分的专家,并负责自己区域内的一切。微服务就是采用这后者的思路,但对象是软件应用。

简单来说,微服务是一种将单一应用程序分解为一组小服务的架构风格,每个服务运行在自己的进程中,并使用轻量级的机制通常是HTTP RESTful API进行通信。每个服务都围绕着特定的业务能力构建,并且可以独立地部署到生产环境。它们可以用不同的编程语言编写,并使用不同的数据存储技术。

为什么需要微服务

当你的应用程序变得越来越大,就会越来越难以维护和扩展,这种现象被称为“代码的大泥球”。微服务架构适应这种情况的原因有几个:

  1. 独立性:微服务使得团队可以独立地更新、部署和扩展各个组件。
  2. 易于理解和维护:每个服务都相对较小,负责单一的功能,因此更容易理解和修改。
  3. 技术多样性:不同的服务可以采用最适合其业务需求的技术栈。
  4. 弹性:服务之间相互独立,一个服务的故障不会直接影响到其他服务。
  5. 可扩展性:可以独立扩展某个特定服务,而不必扩展整个应用。

NestJS微服务实战

NestJS是一个用于构建高效,可靠的服务端应用程序的框架。它完美地支持微服务架构模型。NestJS提供了与微服务相关的模块和装饰器,这些工具允许你轻松创建以消息传递机制(比如通过使用TCP、RabbitMQ或Kafka)进行交互的独立服务。

接下来创建一个简单的微服务系统,其中包括一个主服务和一个微服务,它们通过NestJS的微服务模块通信。

一、创建主服务

首先,我们创建一个新的NestJS应用作为主服务:

shell
nest new main-service

二、创建微服务

然后再创建一个新的应用作为微服务:

shell
nest new microservice-app

三、设置微服务通讯

在微服务应用中,更新 main.ts文件来初始化微服务:

javascript
import { NestFactory } from '@nestjs/core'; import { AppModule } from './app.module'; import { MicroserviceOptions, Transport } from '@nestjs/microservices'; async function bootstrap(){ const app = await NestFactory.create(AppModule); const microservice = app.connectMicroservice<MicroserviceOptions>({ transport: Transport.TCP, options: { host: '127.0.0.1', port: 8877 } }); await app.startAllMicroservicesAsync(); await app.listen(3000); console.log(`Microservice is running`); } bootstrap();

在这段代码中,我们为微服务指定了 Transport.TCP传输机制,并设置它的监听地址和端口。同时,我们调用了 startAllMicroservicesAsync启动所有的微服务,它会启动TCP服务器并开始监听。

四、在微服务中创建服务处理器

接下来,我们在微服务中创建一个服务处理器。在 app.service.ts文件中,你可能会写类似下面的代码:

typescript
import { Injectable } from '@nestjs/common'; import { MessagePattern } from '@nestjs/microservices'; @Injectable() export class AppService { @MessagePattern('get_data') getData(data: any): string { // 实际业务逻辑 return `Data received: ${JSON.stringify(data)}`; } }

在上面的 AppService类中,我们使用 MessagePattern装饰器定义了一个消息处理器,该处理器将响应名为 get_data的消息并返回一些处理过的数据。

五、在主服务中调用微服务

现在,我们需要在主服务中调用微服务。这需要我们设置主服务中的微服务客户端,并通过该客户端发送消息。

更新主服务的 app.module.ts来配置微服务客户端:

javascript
import { Module } from '@nestjs/common'; import { ClientsModule, Transport } from '@nestjs/microservices'; import { AppController } from './app.controller'; import { AppService } from './app.service'; @Module({ imports: [ ClientsModule.register([ { name: 'MICROSERVICE_APP', transport: Transport.TCP, options: { host: '127.0.0.1', port: 8877 }, }, ]), ], controllers: [AppController], providers: [AppService], }) export class AppModule {}

在主服务的 app.controller.ts中定义一个调用微服务的方法:

javascript
import { Controller, Get } from '@nestjs/common'; import { ClientProxy, ClientProxyFactory, Transport } from '@nestjs/microservices'; import { AppService } from './app.service'; @Controller() export class AppController { private client: ClientProxy; constructor(private readonly appService: AppService) { this.client = ClientProxyFactory.create({ transport: Transport.TCP, options: { host: '127.0.0.1', port: 8877, }, }); } @Get() async getData() { const response = await this.client.send('get_data', { id: 1 }).toPromise(); return response; } }

在这个例子中,我们创建了一个名为 clientClientProxy对象,并使用TCP传输和确定的主机及端口对其进行了配置。通过 client.send('get_data', { id: 1 }),我们就可以发送消息 get_data并附带一些数据。使用 toPromise()来处理异步响应。

六、测试微服务系统

一切都设置好之后,你就可以分别运行主服务和微服务了。

shell
# 在两个不同的终端中 # 启动主服务 npm run start # 启动微服务 npm run start

当主服务和微服务都启动之后,你可以通过浏览器访问主服务的根路径,它会通过微服务客户端向微服务发送请求,微服务会处理这个请求并返回结果。

总结

通过以上步骤,我们展示了如何使用NestJS创建微服务架构的一个简单例子。微服务架构允许我们将应用分解为独立可部署的模块,每个模块专注于一个小的业务范围,提高了开发的可维护性和可扩展性。NestJS的微服务模块简化了服务间的通信和管理,使开发者能够专注于业务逻辑的实现,而不是底层的通信细节。

值得注意的是,微服务的设计和管理需要谨慎考虑,它可能带来一些挑战,比如服务间通信的复杂性、数据一致性、分布式系统的测试和部署等。因此,在选择微服务架构前,你应该评估它是否适合你的项目和团队。

标签: