La construction d’une architecture de microservice peut ressembler à beaucoup de travail, mais NESTJS a des outils qui facilitent le processus. Découvrez l’architecture de microservice, puis créez un microservice simple à l’aide de NESTJS.
À mesure que les systèmes logiciels se développent en complexité, nous, les développeurs, recherchons constamment de meilleures façons de créer des applications évolutives et maintenables. Une solution qui a attiré beaucoup d’attention est l’architecture de microservice, qui est simplement un moyen de diviser les grandes applications en services plus petits et indépendants qui peuvent fonctionner ensemble.
Pas est un puissant Node.js Framework, et il est devenu un choix populaire parmi les développeurs qui cherchent à créer des microservices efficaces. NESTJS a une structure modulaire et des fonctionnalités cool et adaptées aux développeurs, qui aident à simplifier les systèmes distribués du bâtiment.
Dans cet article, nous discuterons de l’architecture de microservice, de ses avantages et finons enfin un microservice de mathématiques et de chaînes simples à l’aide de NESTJS.
Pourquoi les microservices?
Les microservices offrent des avantages puissants par rapport à l’approche monolithique à l’ancienne en décomposant des applications complexes en pièces plus petites et indépendantes. Certains avantages sont:
Évolutivité
Les microservices nous donnent la flexibilité pour mettre à l’échelle des composants spécifiques indépendamment. Par exemple, si vous avez une passerelle de paiement qui fait face à un trafic accru, vous pouvez faire évoluer le système sans affecter les autres parties du système. Cela permet une utilisation plus efficace des ressources.
Développement et déploiement plus rapides
Chaque microservice fonctionne indépendamment, permettant aux équipes de développement de travailler sur différentes parties de l’application sans avoir besoin d’attendre que d’autres accomplissent leurs tâches. Cela accélère considérablement le processus de développement et facilite le déploiement des mises à jour en continu.
Isolement d’anomalie
Avec le système monolithique à l’ancienne, toute défaillance de tous les composants écraserait probablement l’ensemble de votre application. Les microservices résolvent ce problème en vous aidant à isoler les services. Si un service ou un module échoue, le reste de l’application continue de fonctionner, minimisant le temps d’arrêt de vos applications.
Flexibilité technologique
Les microservices permettent à votre équipe la liberté et la flexibilité de sélectionner les outils et technologies les plus appropriés pour chaque service. Par exemple, l’un de vos services peut être construit avec Node.js, tandis qu’un autre pourrait utiliser Python, selon ses besoins spécifiques.
Amélioration de l’entretien
Travailler avec des services plus petits et spécialisés semble beaucoup plus simple. Il est plus facile de comprendre votre tête ce que chacun fait, d’apporter des modifications et de retrouver les insectes.
Pourquoi NESTJS pour les microservices?
NESTJS se distingue par le développement de microservices en raison de sa structure d’opinion, qui minimise les frais généraux lors de la mise en place et de la gestion des services. Il prend également en charge la programmation asynchrone, et sa compatibilité avec TypeScript permet aux développeurs d’écrire du code propre et maintenable. De plus, ses outils intégrés pour la communication entre les services facilitent la gestion des systèmes distribués.
Concevoir une architecture de microservice
La création d’une architecture de microservice nécessite une planification et une exécution réfléchies pour offrir l’évolutivité, la fiabilité et la maintenabilité à long terme. NESTJS simplifie ce processus grâce à sa conception modulaire et à sa approche conviviale pour les développeurs.
Décomposer l’application
Tout d’abord, vous devez identifier les fonctionnalités uniques au sein de votre application et les décomposer en microservices séparés. Si, par exemple, vous créez une plate-forme de commerce électronique, vous pouvez avoir des services dédiés à la gestion des utilisateurs, aux catalogues de produits, au traitement des commandes et aux paiements.
Chaque service doit se concentrer sur une tâche spécifique et interagir avec les autres via des API ou des courtiers de messages. En créant un module séparé pour chaque service, vous le gardez indépendant et autonome.
Par exemple:
@Module({
controllers: [OrderController],
providers: [OrderService],
})
export class OrderModule {}
Communication entre les microservices
NESTJS prend en charge plusieurs méthodes de communication pour les microservices, telles que:
- Http: Simple et adapté à la communication synchrone.
- Courtiers de messages: Nous pouvons utiliser des outils comme RabbitMQ ou Kafka pour permettre une communication asynchrone, donc les services ne se bloquent pas.
- Redis ou grpc: Ce sont des options efficaces pour les interactions haute performance et en temps réel.
Conception de la base de données
Il est important d’éviter d’utiliser une base de données partagée entre les services, car cela crée un couplage serré. Au lieu de cela, chaque service doit avoir une base de données dédiée. Des outils comme Typeorm ou Prisma peuvent être utilisés dans NESTJS pour gérer séparément les interactions de données pour chaque service.
L’asseoir ensemble
Créons un microservice de mathématiques et de chaînes simples. Pour le service mathématique, nous créerons un microservice qui gère les opérations arithmétiques (par exemple, addition et multiplication). Ensuite, nous créons un microservice simple pour le service de chaîne qui gère les opérations de chaîne (par exemple, concaténation, capitalisation). Enfin, nous créerons une autre application Nest comme passerelle pour communiquer avec nos microservices.
Nous utiliserons Transport TCP Pour rester simple, mais vous pouvez le remplacer par RabbitMQ, Redis ou tout autre protocole pour une configuration prête pour la production.
Configuration du projet
Exécutez les commandes suivantes pour créer un répertoire de projet:
mkdir multi-microservice-demo && cd multi-microservice-demo
nest new math-service
nest new string-service
nest new client-app
Accédez à chaque projet et exécutez cette commande pour installer le package Microservices requis:
npm install --save @nestjs/microservices
Construisez le microservice mathématique
Créons un contrôleur pour gérer les opérations mathématiques. Ouvrir le math-service
dossier et ajoutez ce qui suit au src/math.controller.ts
déposer:
import { Controller } from "@nestjs/common";
import { MessagePattern } from "@nestjs/microservices";
@Controller()
export class MathController {
@MessagePattern({ cmd: "sum" })
calculateSum(data: number[]): number {
return data.reduce((a, b) => a + b, 0);
}
@MessagePattern({ cmd: "multiply" })
calculateProduct(data: number[]): number {
return data.reduce((a, b) => a * b, 1);
}
}
Dans le MathController
Classe, nous définissons deux opérations mathématiques: résumé et multiplier une liste de nombres. Le @MessagePattern
Le décorateur écoute des modèles de messages spécifiques des autres microservices.
Le calculateSum
La méthode écoute la commande SUM et attend un tableau de nombres. Il calcule la somme des nombres en utilisant le reduce()
Méthode, qui itère sur le tableau et ajoute chaque valeur ensemble, renvoyant la somme totale.
De même, le calculateProduct
La méthode écoute la commande Multiply et multiplie les nombres dans le tableau en utilisant reduce
. Il commence par une valeur initiale de 1 (la valeur d’identité pour la multiplication) et multiplie chaque élément du tableau, renvoyant le produit.
Les deux méthodes font partie du service mathématique, qui lui permet de traiter les tâches mathématiques basées sur des commandes d’autres microservices.
Ensuite, enregistrons le contrôleur dans AppModule
. Mettre à jour le src/app.module.ts
dossier avec les éléments suivants:
import { Module } from "@nestjs/common";
import { MathController } from "./math.controller";
@Module({
controllers: [MathController],
})
export class AppModule {}
Nous devons modifier le point d’entrée pour exécuter le microservice. Mettre à jour le src/main.ts
dossier avec les éléments suivants:
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";
import { Transport, MicroserviceOptions } from "@nestjs/microservices";
async function bootstrap() {
const app = await NestFactory.createMicroservice<MicroserviceOptions>(
AppModule,
{
transport: Transport.TCP,
options: { host: "127.0.0.1", port: 3001 },
}
);
await app.listen();
console.log("Math Service is running on port 3001");
}
bootstrap();
Le main.ts
Le fichier ci-dessus configure un microservice NESTJS de base à l’aide de TCP comme protocole de transport. Le bootstrap
La fonction initialise le microservice, la lie à l’adresse IP locale (127.0.0.1) et écoute le port 3001. Le microservice fonctionne avec la logique définie dans AppModule
.
Une fois le microservice commence, nous enregistrons également un message à la console confirmant que le service est en cours d’exécution et prêt à accepter les demandes entrantes.
Ensuite, exécutez le microservice mathématique:
npm run start
Construisez le microservice de chaîne
Ouvrir le string-service
dossier et créez un contrôleur pour les opérations de chaîne. Mettre à jour le src/string.controller.ts
dossier avec les éléments suivants:
import { Controller } from "@nestjs/common";
import { MessagePattern } from "@nestjs/microservices";
@Controller()
export class StringController {
@MessagePattern({ cmd: "concat" })
concatenateStrings(data: string[]): string {
return data.join(" ");
}
@MessagePattern({ cmd: "capitalize" })
capitalizeString(data: string): string {
return data.toUpperCase();
}
}
Dans le StringController
classe, nous définissons deux méthodes de gestion des messages en utilisant le @MessagePattern()
Décorateur de Nestjs. Le @MessagePattern()
décorateur écoute les messages entrants avec des modèles de commande spécifiques (cmd
) à partir d’autres microservices.
La première méthode, concatenateStrings
écoute pour le concat
commander et attend un tableau de chaînes sous forme de données. Il rejoint ensuite les cordes avec des espaces, renvoyant le résultat concaténé.
La deuxième méthode, capitalizeString
écoute la commande capitaliser et transforme la chaîne donnée en majuscules avant de le retourner. Ces méthodes font partie du service de manipulation de chaînes qui lui permet de répondre aux commandes des autres microservices du système.
Ensuite, enregistrons le contrôleur dans AppModule
. Mettre à jour le src/app.module.ts
dossier avec les éléments suivants:
import { Module } from "@nestjs/common";
import { StringController } from "./string.controller";
@Module({
controllers: [StringController],
})
export class AppModule {}
Ensuite, modifions le point d’entrée comme en mettant à jour le src/main.ts
dossier avec les éléments suivants:
import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";
import { Transport, MicroserviceOptions } from "@nestjs/microservices";
async function bootstrap() {
const app = await NestFactory.createMicroservice<MicroserviceOptions>(
AppModule,
{
transport: Transport.TCP,
options: { host: "127.0.0.1", port: 3002 },
}
);
await app.listen();
console.log("String Service is running on port 3002");
}
bootstrap();
Dans le main.ts
Fichier ci-dessus, nous avons configuré un microservice NESTJS de base à l’aide de TCP comme protocole de transport. La fonction bootstrap initialise le microservice, la lie à l’adresse IP locale (127.0.0.1) et écoute le port 3002. Le microservice fonctionne avec la logique définie dans AppModule
. Une fois le microservice commence, nous enregistrons un message à la console confirmant que le service est en cours d’exécution et prêt à accepter les demandes entrantes.
Exécutez cette commande dans votre terminal pour exécuter le microservice de chaîne:
npm run start
Créer l’application client
Maintenant, créons un service de passerelle pour communiquer avec les deux microservices. Ouvrir le client-app
dossier et mettez à jour le src/app.service.ts
dossier avec les éléments suivants:
import { Injectable } from "@nestjs/common";
import {
ClientProxy,
ClientProxyFactory,
Transport,
} from "@nestjs/microservices";
@Injectable()
export class AppService {
private mathClient: ClientProxy;
private stringClient: ClientProxy;
constructor() {
this.mathClient = ClientProxyFactory.create({
transport: Transport.TCP,
options: { host: "127.0.0.1", port: 3001 },
});
this.stringClient = ClientProxyFactory.create({
transport: Transport.TCP,
options: { host: "127.0.0.1", port: 3002 },
});
}
async calculateSum(numbers: number[]): Promise<number> {
return this.mathClient.send({ cmd: "sum" }, numbers).toPromise();
}
async capitalizeString(data: string): Promise<string> {
return this.stringClient.send({ cmd: "capitalize" }, data).toPromise();
}
}
Le AppService
La classe ci-dessus gère la communication avec les deux microservices mathClient
et stringClient
. Le ClientProxyFactory.create()
La méthode est utilisée pour créer les deux proxies clients mathClient
et stringClient
qui permettent au service de communiquer avec d’autres microservices via TCP. Chaque proxy est configuré pour se connecter à un service spécifique exécutant sur localhost mais sur différents ports.
Le calculateSum
et capitalizeString
Méthodes Envoient des messages à leurs microservices respectifs en utilisant le .send()
Méthode, qui passe la commande et les données. Les réponses sont retournées comme promesses, résolues en utilisant .toPromise()
. Cette configuration permet au AppService
pour déléguer des tâches à d’autres services, pour une architecture modulaire et distribuée.
Maintenant, nous pouvons mettre à jour le contrôleur d’application pour utiliser ce service. Mettre à jour le src/app.controller.ts
dossier avec les éléments suivants:
import { Controller, Get } from "@nestjs/common";
import { AppService } from "./app.service";
@Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
@Get("sum")
async getSum(): Promise<number> {
return this.appService.calculateSum([5, 10, 15]);
}
@Get("capitalize")
async getCapitalizedString(): Promise<string> {
return this.appService.capitalizeString("hello world");
}
}
Le AppController
La classe ici gère les demandes HTTP et délégue la logique au AppService
classe. Le @Controller()
Le décorateur marque la classe en tant que contrôleur dans NESTJS, ce qui le rend capable de gérer les demandes HTTP entrantes. Le AppService
est injecté dans le contrôleur via l’injection de dépendance, ce qui lui permet d’accéder à des méthodes comme calculateSum
et capitalizeString
.
Le @Get('sum')
et @Get('capitalize')
Les décorateurs définissent HTTP GET
points de terminaison. Quand un GET
La demande est faite à /sum
le getSum
la méthode est appelée, qui à son tour appelle le calculateSum
Méthode dans le AppService
.
De même, un GET
demander à /capitalize
déclenche le getCapitalizedString
Méthode, appelant le capitalizeString
méthode de AppService
. Ces points de terminaison permettent une interaction entre le client et les microservices pour effectuer des opérations de mathématiques et de chaînes.
Nous pouvons exécuter la commande ci-dessous pour exécuter l’application client:
npm run start
Tester le système
Pour tester ce que nous avons jusqu’à présent, nous devons d’abord démarrer chaque microservice.
Exécutez la commande ci-dessous pour démarrer le service mathématique:
cd math-service && npm run start
Ensuite, exécutez ceci pour démarrer le service de chaîne:
cd string-service && npm run start
Enfin, démarrez l’application client:
cd client-app && npm run start
Tester les points de terminaison
Meilleures pratiques pour les microservices
Lorsque vous travaillez avec des microservices, suivre certaines pratiques peut aider à rendre votre système efficace et facile à maintenir à long terme. Passons en revue quelques pratiques clés à suivre lors de la construction de microservices avec NESTJS.
Concentrez-vous sur les petits services indépendants
Chaque service doit gérer une fonction commerciale spécifique, qu’elle soit l’authentification des utilisateurs, les paiements ou la gestion des stocks. Cela rend chaque service plus facile à maintenir et à évoluer indépendamment.
Le couplage lâche est la clé
Une bonne architecture de microservices maintient les services indépendants, ce qui rend chaque service plus facile à mettre à jour ou à remplacer sans affecter le reste du système. La communication entre les services ne doit pas être directe, mais doit se produire par le biais d’API ou de courtiers de messages comme RabbitMQ ou Kafka.
Utilisez une passerelle API
Au lieu de faire appeler directement plusieurs services, introduire une passerelle API. Il ne s’agit pas seulement de rouler le trafic; Il simplifie également des tâches comme l’équilibrage de la charge, l’authentification et la limitation du taux. Cette couche agit comme un seul point d’entrée pour toutes les demandes.
Conclusion
La construction d’une architecture de microservice peut ressembler à beaucoup de travail, mais NESTJS a des outils qui facilitent le processus. Avec son support intégré pour les protocoles de communication comme Redis, Kafka et RabbitMQ, vous pouvez connecter vos services sans effort et créer de puissants systèmes distribués.
Source link