Lezers zoals jij steunen MUO. Wanneer u een aankoop doet via links op onze site, kunnen we een aangesloten commissie verdienen. Lees verder.

Als webontwikkelaar is het van cruciaal belang dat uw apps zo snel mogelijk presteren. U moet web-apps bouwen die zo snel mogelijk op verzoeken reageren.

Een van de vele technologieën die u kunnen helpen, is taakwachtrij.

Wat is task queuing en hoe kun je het gebruiken om een ​​Node.js-applicatie te optimaliseren?

Wat is taakwachtrij?

Message queuing is een manier van asynchrone communicatie tussen twee applicaties of services, meestal aangeduid als de producent En klant. Het is een bekend concept dat wordt gebruikt in serverloze en microservice-architecturen.

Het concept van taak of functiein de rij staan maakt gebruik van berichtwachtrijen om de prestaties van applicaties te verbeteren. Het abstraheert de complexiteit van het beheer van berichten en stelt u in staat functies te definiëren om taken of taken asynchroon te beheren met behulp van een wachtrij, waardoor de snelheid van geheugengebruik in sommige delen van een applicatie.

instagram viewer

Het meest voorkomende voorbeeld van berichtenwachtrijsoftware is RabbitMQ. Hulpprogramma's voor taakwachtrijen zijn Celery en Bull. U kunt RabbitMQ ook configureren om als taakwachtrij te werken. Lees verder om meer te weten te komen over taakwachtrijen in Node.js met behulp van Bull.

Wat is BullMQ?

BullMQ (Bull.js) is een Node.js-bibliotheek die wordt gebruikt voor het implementeren van wachtrijen in Node-applicaties. Bull is een op Redis gebaseerd systeem (misschien bent u meer bekend met Redis als hulpmiddel voor snelle gegevensopslag) en het is een snelle en betrouwbare optie om te overwegen voor taakwachtrijen in Node.js.

U kunt Bull voor veel taken gebruiken, zoals het implementeren van uitgestelde taken, geplande taken, herhaalbare taken, prioriteitswachtrijen en nog veel meer.

Dus, hoe kun je Bull en Redis gebruiken om Node.js-taken asynchroon uit te voeren?

Bull en Redis configureren voor Task Queuing in Node.js

Om aan de slag te gaan met taakwachtrijen in Node.js met Bull, moeten Node.js en Redis op uw computer zijn geïnstalleerd. U kunt de volgen Redis labs gids om Redis te installeren als je het niet hebt geïnstalleerd.

De eerste stap bij het implementeren van Bull is om het toe te voegen aan de afhankelijkheden van uw project door het uit te voeren npm installeer stier of garen stier toevoegen in de terminal in de map van uw project. Er zijn meerdere manieren om een ​​wachtrij in Bull te initialiseren, zoals hieronder weergegeven:

const Wachtrij = vereisen('stier');

// verschillende manieren om een ​​wachtrij te initialiseren
// - met behulp van een redis-URL-tekenreeks
const emailQueue = nieuw Wachtrij('E-mailwachtrij', 'redis://127.0.0.1:6379');

// - met een redis-verbinding en object met wachtrij-opties
const videoQueue = nieuw Wachtrij('Videowachtrij', 'redis://127.0.0.1:6379', wachtrijOpties);

// - zonder redis-verbinding maar met wachtrijOption
const docQueue = nieuw Wachtrij('Documentwachtrij', wachtrijOpties);

// - zonder redis-verbinding of wachtrij-opties
const WachtrijClient = nieuw Wachtrij('Mijn wachtrij');

Deze gebruiken allemaal minimale configuratie voor Bull in Node.js. Het options-object ondersteunt veel eigenschappen en u kunt er meer over leren in de sectie met wachtrij-opties in de documentatie van Bull.

Een e-mailtaakwachtrij implementeren met behulp van BullMQ

Om een ​​wachtrij voor het verzenden van e-mails te implementeren, kunt u uw producentfunctie definiëren die e-mails aan de e-mailwachtrij toevoegt, en een consumentenfunctie om het verzenden van e-mails af te handelen.

Ten eerste kunt u uw wachtrij in een klas initialiseren met behulp van een Redis-URL en enkele wachtrij-opties, zoals hieronder te zien is.

// wachtrijHandler.js
const Wachtrij = vereisen('stier');

// gebruik hier een echte e-mailhandlermodule - dit is slechts een voorbeeld
const e-mailHandler = vereisen('./emailHandler.js');

// definieer constanten, Redis-URL en wachtrij-opties
const REDIS_URL = 'redis://127.0.0.1:6379';

const wachtrijOpts = {
// snelheidsbeperkende opties om overbelasting van de wachtrij te voorkomen
begrenzer: {
// maximaal aantal taken die in de wachtrij kunnen staan
maximaal: 100,

// tijd om in milliseconden te wachten voordat nieuwe taken worden geaccepteerd
// limiet bereiken
duur: 10000
},
voorvoegsel: 'EMAIL-TAAK', // een voorvoegsel dat moet worden toegevoegd aan alle wachtrijsleutels
defaultJobOptions: { // standaardopties voor taken in de wachtrij
pogingen: 3, // standaard aantal keren om een ​​taak opnieuw te proberen

// om een ​​taak na voltooiing uit de wachtrij te verwijderen
removeOnComplete: WAAR
}
};

klasE-mailwachtrij{
constructeur() {
dit.wachtrij = nieuw Wachtrij('E-mailwachtrij', REDIS_URL, wachtrijOpts);
}
};

exporterenstandaard E-mailwachtrij; // exporteer de klas

Nu je een wachtrij hebt geïnitialiseerd, kun je je producerfunctie definiëren (met behulp van Bull's toevoegen() functie) als een methode van de E-mailwachtrij class om e-mails aan de taakwachtrij toe te voegen. Het volgende codeblok demonstreert dit:

// wachtrijHandler.js

klasE-mailwachtrij{
constructeur () {
// ...
}

// Producer-functie om e-mails aan de wachtrij toe te voegen
asynchroon addEmailToQueue (emailData) {
// voeg een taak met de naam 'email_notification' toe aan de wachtrij
wachtendit.wachtrij.toevoegen('E-mail notificatie', e-mailgegevens);
troosten.log('de e-mail is toegevoegd aan de wachtrij...');
}
};

exporterenstandaard E-mailwachtrij; // exporteer de klas

De producer-functie is klaar en u kunt nu een consumer-functie definiëren (met behulp van Bull's proces() functie) om alle e-mailtaken in de wachtrij te verwerken, d.w.z. bel de functie om een ​​e-mail te sturen. U moet deze consumentenfunctie definiëren in de constructor van de klasse.

// wachtrijHandler.js
klasE-mailwachtrij{
constructeur () {
// ...

// consumentenfunctie die de toegewezen naam van de taak overneemt en
// een callback-functie
dit.wachtrij.proces('E-mail notificatie', asynchroon (emailJob, klaar) => {
troosten.log('taak e-mailmelding verwerken');
wachten emailHandler.sendEmail (emailJob); // verstuur de e-mail
klaar(); // voltooi de taak
})
}
// ...
};

exporterenstandaard E-mailwachtrij; // exporteer de klas

Een taak kan ook opties hebben om zijn gedrag in de wachtrij te definiëren of hoe de consumentenfunctie ermee omgaat. Meer hierover leest u in de sectie met jobopties in de documentatie van Bull.

De emailJob argument is een object dat de eigenschappen van de taak bevat die door de wachtrij moet worden verwerkt. Het bevat ook de belangrijkste gegevens die nodig zijn om de e-mail samen te stellen. Voor een beter begrip, de stuurE-mail() functie zou vergelijkbaar zijn met dit voorbeeld:

// emailHandler.js
const verzendgridMail = vereisen('@sendgrid/mail');

const apiKey = proces.env. SENDGRID_API_KEY

sendgridMail.setApiKey (apiKey); // beveiligingsreferenties voor e-mailtransporter instellen

const stuurEmail = asynchroon (emailJob) => {
poging {
// haal de e-mailgegevens uit de taak
const { naam, e-mail } = emailJob.data;

const bericht = {
van: '[email protected]',
naar: '[email protected]',
onderwerp: 'Hoi! Welkom',
tekst: 'Hallo ${naam}, welkom bij MUO`
};

wachten sendgridMail.sendMail (bericht); // stuur e-mail

// markeer taak als voltooid in de wachtrij
wachten emailJob.moveToCompleted('klaar', WAAR);
troosten.log('E-mail succesvol verzonden...');
} vangst (fout) {
// verplaats de taak naar mislukte taken
wachten emailJob.moveToFailed({ bericht: 'taakverwerking mislukt..' });
troosten.fout (fout); // registreer de fout
}
}

exporterenstandaard stuurE-mail;

Nu u zowel de producer- als de consumer-functie hebt gedefinieerd en klaar voor gebruik, kunt u nu uw producer-functie overal in uw applicatie aanroepen om een ​​e-mail toe te voegen aan de wachtrij voor verwerking.

Een voorbeeldcontroller ziet er als volgt uit:

// userController.js
const E-mailwachtrij = vereisen('../handlers/queueHandler.js')

const aanmelden = asynchroon (req, res) => {
const { naam, e-mail, wachtwoord } = req.body;

// --
// een query om de nieuwe gebruiker toe te voegen aan de database...
// --

// toevoegen aan e-mailwachtrij
const emailData = { naam, e-mail };
wachten EmailQueue.addEmailToQueue (emailData);

res.status(200.json({
bericht: "Aanmelden is gelukt, controleer a.u.b. uw e-mail"
})
}

Jouw wachtrijHandler.js bestand zou nu als volgt moeten zijn:

// wachtrijHandler.js
const Wachtrij = vereisen('stier');
const e-mailHandler = vereisen('../handlers/emailHandler.js');

const REDIS_URL = 'redis://127.0.0.1:6379';

const wachtrijOpts = {
begrenzer: {
maximaal: 100,
duur: 10000
},

voorvoegsel: 'EMAIL-TAAK',

defaultJobOptions: {
pogingen: 3,
removeOnComplete: WAAR
}
};

klasE-mailwachtrij{
constructeur() {
dit.wachtrij = nieuw Wachtrij('E-mailwachtrij', REDIS_URL, wachtrijOpts);

// klant
dit.wachtrij.proces('E-mail notificatie', asynchroon (emailJob, klaar) => {
troosten.log('taak e-mailmelding verwerken');
wachten emailHandler.sendEmail (emailJob);
klaar();
})
}

// producent
asynchroon addEmailToQueue (emailData) {
// voeg een taak met de naam 'email_notification' toe aan de wachtrij
wachtendit.wachtrij.toevoegen('E-mail notificatie', e-mailgegevens);
troosten.log('de e-mail is toegevoegd aan de wachtrij...');
}
};

exporterenstandaard E-mailwachtrij;

Wanneer u dit implementeert in een Node.js REST API, merkt u een afname van de responstijd van het aanmeldingseindpunt en snellere e-mailbezorgtijden in vergelijking met het alternatief.

Taakwachtrijen stelden je ook in staat om aanmeldings- en e-mailfouten onafhankelijk af te handelen.

Toepassingen optimaliseren met behulp van taakwachtrijen

Berichten- en taakwachtrijen zijn een geweldige manier om de algemene prestaties van applicaties te verbeteren. Ze zijn ook erg goedkoop en je kunt ze in zoveel delen van een applicatie gebruiken als je nodig hebt.

Hoewel deze zelfstudie e-mails gebruikte als voorbeeldscenario voor het afhandelen van geheugenverslindende taken met wachtrijen, zijn er veel andere gevallen waarin u dezelfde concepten kunt toepassen. Deze omvatten zware lees-/schrijfbewerkingen, het weergeven van afbeeldingen of documenten van hoge kwaliteit en het verzenden van bulkmeldingen.