想象一下,你回家过节,你的家人决定聚会。而不是让一个人做所有的烹饪,每个人都同意带上他们擅长制作的特色菜。目标是通过组合所有这些菜肴来制作一顿完整的饭菜。你同意做鸡肉炒饭,你哥哥做甜点蛋糕,妹妹做沙拉。
每个菜代表一个具有特定功能或用途的微服务。例如,炒饭代表一道丰盛的主菜;沙拉代表新鲜健康的配菜,蛋糕代表甜蜜甜点。在微服务架构中,开发人员可以独立于其他微服务开发、部署和维护每个微服务,确保每个微服务保持独立和独立。
就像家庭聚会上的每道菜都代表具有不同功能或目的的微服务一样,软件系统中的每个微服务都必须与其他微服务进行有效的通信,以形成功能齐全的应用程序。类似于每道菜都需要与其他菜肴协调以创建美味佳肴一样,随着微服务数量的增加,微服务之间的通信变得越来越重要。我们可以确保微服务可以无缝运行,通过使用高效的通信框架(如 gRPC)来构建持久且可缩放的系统。
在本文中,我们将了解 gRPC(一种高性能的开源远程过程调用框架)如何允许 NestJS 应用程序中的微服务进行通信。我们将介绍使用 gRPC 的优势,如何在 NestJS 应用程序中执行此操作,并举例说明微服务如何使用它进行通信。
让我们首先介绍一下我们需要的先决条件和工具:
微服务以多种方式相互通信。由于微服务架构中的每个微服务都执行特定的功能或任务,因此需要通信以确保完整的应用程序正常运行。由于每个微服务的独立性,微服务架构使开发人员能够创建更灵活、可扩展和容错的应用程序。此外,微服务的模块化设计使其成为复杂应用程序的理想选择,因为不同的系统组件可能有不同的需求和要求。
微服务通常通过定义明确的 API 和协议相互通信,使每个微服务都能可靠、高效地进行通信。但是,微服务间通信可能有点挑战性和棘手性。当许多微服务相互通信时,开发人员可能会遇到几个问题,包括:
总体而言,微服务之间的通信可能具有挑战性且复杂。开发人员可以通过在设计系统时考虑以下因素来创建高度可扩展、容错和弹性的微服务体系结构:
微服务使用各种通信模式相互通信。我们将研究其中的一些:发布-订阅、请求-响应、事件驱动体系结构和消息队列。
gRPC 是由 Google 开发的高性能开源远程过程调用 (RPC) 框架。它使客户端应用程序能够调用位于远程计算机上的服务器应用程序上的方法,其方式与在本地对象上调用方法一样容易。它通过在客户端和服务器应用程序之间提供高效且独立于语言的通信,简化了构建和扩展分布式应用程序的过程。
微服务体系结构中使用的通信协议包括 gRPC、REST 和 SOAP。以下是它们之间的一些主要区别:
在本节中,您将学习如何创建一个简单的 NestJS 微服务,该服务使用 gRPC 返回“Hello, World!”:
首先,你需要安装 NestJS CLI 和 gRPC 工具:
npm install -g @nestjs/cli
npm install @nestjs/microservices @grpc/grpc-js
你需要使用 CLI 创建一个新的 NestJS 项目:
nest new hello-world-demo
此示例中的项目名称为“hello-world-demo”。
现在,导航到项目文件夹:
cd hello-world-demo
接下来,您需要创建一个新的模块和服务。服务是为应用程序提供特定类型功能的类,而模块是相关服务、控制器和提供程序集合的容器。通过这样做,你基本上是在向你的NestJS应用程序添加一个新的可管理,可测试的功能层。这有助于将来添加其他功能,并有利于应用程序的常规体系结构和可维护性。
nest g module hello
nest g service hello
然后,您需要使用以下代码更新 hello-world-demo/src/hello/hello.service.ts
文件:
import { Injectable } from '@nestjs/common';
import { GrpcMethod } from '@nestjs/microservices';
@Injectable()
export class HelloService {
@GrpcMethod('HelloService', 'SayHello')
sayHello(data: any): { message: string } {
return { message: 'Hello, World!' };
}
}
此服务文件包含一个标记为可注入提供程序的 HelloService 类。 @GrpcMethod
修饰器用于将 sayHello
方法标记为 gRPC 方法,该方法返回“Hello, World!”消息。总的来说,此代码演示了如何使用 NestJS 创建基本的 gRPC 服务。
更新 hello-world-demo/src/app.module.ts
文件以包含 HelloService
和 使用 gRPC:
import { Module } from '@nestjs/common';
import { ClientsModule, Transport } from '@nestjs/microservices';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { HelloService } from './hello/hello.service';
@Module({
imports: [
ClientsModule.register([
{
name: 'HELLO_PACKAGE',
transport: Transport.GRPC,
options: {
url: 'localhost:5000',
package: 'hello',
protoPath: './hello.proto',
},
},
]),
],
controllers: [AppController],
providers: [AppService, HelloService],
})
export class AppModule {}
它具有用于 HelloService 提供程序类、HTTP 控制器和 AppService HelloService 提供程序类的 gRPC 客户端。用于 ClientsModule 使用提供的选项注册 gRPC 客户端,例如描述服务的原型文件的路径、gRPC 服务器的 URL 以及包的名称。在 providers 应用程序中管理业务逻辑的 AppService and HelloService 类包含在字段中。管理 AppController 传入 HTTP 请求的类是该 controllers 属性的成员。
创建一个新文件 hello-world-demo/hello.proto
并添加以下代码:
syntax = "proto3";
package hello;o
service HelloService {
rpc SayHello (HelloRequest) returns (HelloResponse);
}
message HelloRequest {
string name = 1;
}
message HelloResponse {
string message = 1;
}
原型文件用于定义 gRPC 服务的结构和接口。它是一个概述服务的过程以及参数的输入和输出数据格式的文件。gRPC 框架使用用协议缓冲区语言编写的原型文件在 NestJs 中生成客户端和服务器代码。
最后,更新 hello-world-demo/src/main.ts
文件以启动 gRPC 微服务:
import { NestFactory } from '@nestjs/core';
import { Transport } from '@nestjs/microservices';
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.createMicroservice(AppModule, {
transport: Transport.GRPC,
options: {
url: 'localhost:5000',
package: 'hello',
protoPath: './hello.proto',
},
});
await app.listen();
}
bootstrap();
现在,启动 gRPC 微服务:
npm run start
服务器启动后,它将侦听指定 URL 和端口(在本例中为 5000)上的传入 gRPC 请求。然后,可以从 gRPC 客户端(例如 Web 前端、移动应用或其他微服务)向服务器发送请求。对于我们一直在处理的“Hello World”示例,您可以通过使用 grpcurl 命令行工具发送请求来测试服务器。若要测试微服务,可以使用 grpcurl,这是一个用于与 gRPC 服务交互的命令行工具:
grpcurl -plaintext -d '{"name": "John"}' localhost:5000 hello.HelloService/SayHello
这应返回以下响应:
{
"message": "Hello, World!"
}
就是这样!您已经创建了一个使用 gRPC 返回“Hello, World!”的 NestJS 微服务,并且您已经使用 grpcurl 对其进行了测试。当然,在实际应用程序中,微服务可能具有更复杂的功能,而不是简单地返回“Hello, World!”来响应单个请求。但是,启动服务器、侦听传入请求以及根据业务逻辑处理这些请求的基本过程将是相同的。
使用 NestJS 和 gRPC 进行微服务通信可以产生更快、更可靠、更具可扩展性的系统。以下是一些好处:
微服务架构正在成为设计复杂且可扩展的应用程序的一种更流行的方式。它通过将应用程序分解为独立和专用的组件来提供灵活性和可扩展性。但是,此设计的有效性取决于微服务之间的有效通信。这就是高性能远程过程调用 (RPC) 框架 gRPC 发挥作用的地方。
在本文中,我们探讨了在 NestJS 中使用 gRPC 进行微服务通信的好处。我们讨论了微服务通信中涉及的挑战,包括延迟、安全性、服务发现和容错。我们还探讨了 gRPC 如何帮助开发人员克服这些挑战并构建可缩放的容错微服务体系结构。此外,我们还将 gRPC 与其他通信协议(如 REST 和 SOAP)进行了比较,重点介绍了其语言支持、性能、数据格式和服务协定优势。
此外,我们在 NestJS 中使用 gRPC 构建了一个简单的“hello world”服务,以演示 Nest 应用程序中的服务如何使用 gRPC 进行有效通信。
最后,我们讨论了在 NestJS 中使用 gRPC 进行微服务通信的好处,包括强类型协定、自动代码生成、互操作性和易用性。
总之,开发人员可以使用 gRPC 的性能和类型安全以及 NestJS 的简单性,构建具有有效通信通道的可扩展且可维护的微服务,从而产生更健壮、更可靠的系统。