Læsere som dig hjælper med at støtte MUO. Når du foretager et køb ved hjælp af links på vores websted, kan vi optjene en affiliate-kommission. Læs mere.

Som webudvikler er det afgørende, at dine apps yder så hurtigt, som de kan. Du bør bygge webapps, der reagerer på anmodninger hurtigst muligt.

En af de mange teknologier, der kan hjælpe dig, er opgavekø.

Så hvad er opgavekø, og hvordan kan du bruge det til at optimere en Node.js-applikation?

Hvad er opgavekø?

Message queuing er et middel til asynkron kommunikation mellem to applikationer eller tjenester, normalt omtalt som producent og forbruger. Det er et velkendt koncept, der anvendes i serverløse og mikroservicearkitekturer.

Konceptet med opgave eller jobstå i kø udnytter beskedkø til at forbedre applikationens ydeevne. Det abstraherer kompleksiteten ved at administrere beskeder og giver dig mulighed for at definere funktioner til at administrere job eller opgaver asynkront ved hjælp af en kø, og derved reducere hastigheden af hukommelsesforbrug i nogle dele af en ansøgning.

instagram viewer

Det mest almindelige eksempel på software til beskedkø er RabbitMQ. Værktøjer til opgavekø omfatter Selleri og Bull. Du kan også konfigurere RabbitMQ til at fungere som en opgavekø. Læs videre for at lære om opgavekø i Node.js ved hjælp af Bull.

Hvad er BullMQ?

BullMQ (Bull.js) er et Node.js-bibliotek, der bruges til at implementere køer i Node-applikationer. Bull er et Redis-baseret system (du er måske mere bekendt med Redis som et værktøj til hurtig datalagring), og det er en hurtig og pålidelig mulighed at overveje til opgavekø i Node.js.

Du kan bruge Bull til mange opgaver, såsom implementering af forsinkede job, planlagte job, gentagelige job, prioriterede køer og mange flere.

Så hvordan kan du bruge Bull og Redis til at køre Node.js-opgaver asynkront?

Sådan konfigureres Bull og Redis til opgavekø i Node.js

For at komme i gang med opgavekø i Node.js med Bull, skal du have Node.js og Redis installeret på din maskine. Du kan følge Redis laboratorievejledning til installation af Redis hvis du ikke har det installeret.

Det første skridt til at implementere Bull er at tilføje det til dit projekts afhængigheder ved at køre npm installer bull eller garn tilføj tyr i terminalen inde i dit projekts mappe. Der er flere måder at initialisere en kø i Bull som vist nedenfor:

konst Kø = kræve('tyr');

// forskellige måder at initialisere en kø på
// - ved hjælp af redis URL-streng
konst emailQueue = ny Kø('E-mail-kø', 'redis://127.0.0.1:6379');

// - med et redis-forbindelse og køoptionsobjekt
konst videokø = ny Kø('Videokø', 'redis://127.0.0.1:6379', køindstillinger);

// - uden en redis-forbindelse, men med queueOption
konst docQueue = ny Kø('Dokumentkø', køindstillinger);

// - uden en redis-forbindelse eller køindstillinger
konst QueueClient = ny Kø('Min kø');

Disse bruger alle minimal konfiguration til Bull i Node.js. Optionsobjektet understøtter mange egenskaber, og du kan lære om dem i sektion for køindstillinger i Bulls dokumentation.

Implementering af en e-mail-opgavekø ved hjælp af BullMQ

For at implementere en kø til afsendelse af e-mails, kan du definere din producentfunktion, som tilføjer e-mails til e-mail-køen, og en forbrugerfunktion til at håndtere afsendelse af e-mails.

For det første kan du initialisere din kø i en klasse ved hjælp af en Redis URL og nogle kømuligheder som vist nedenfor.

// queueHandler.js
konst Kø = kræve('tyr');

// brug et rigtigt e-mail-håndteringsmodul her - dette er blot et eksempel
konst emailHandler = kræve('./emailHandler.js');

// definere konstanter, Redis URL og køindstillinger
konst REDIS_URL = 'redis://127.0.0.1:6379';

konst queueOpts = {
// rate limiter muligheder for at undgå overbelastning af køen
begrænser: {
// maksimalt antal opgaver, køen kan tage
max: 100,

// tid til at vente i millisekunder, før du accepterer nye job efter
// når grænsen
varighed: 10000
},
præfiks: 'EMAIL-OPGAVE', // et præfiks, der skal tilføjes til alle kønøgler
defaultJobOptions: { // standardindstillinger for opgaver i køen
forsøg: 3, // standard antal gange at prøve en opgave igen

// for at fjerne en opgave fra køen efter afslutning
removeOnComplete: rigtigt
}
};

klasseE-mailkø{
konstruktør() {
det her.kø = ny Kø('E-mail-kø', REDIS_URL, queueOpts);
}
};

eksportStandard EmailQueue; // eksporter klassen

Nu hvor du har initialiseret en kø, kan du definere din producerfunktion (ved hjælp af Bull's tilføje() funktion) som en metode til E-mailkø klasse for at tilføje e-mails til opgavekøen. Følgende kodeblok demonstrerer dette:

// queueHandler.js

klasseE-mailkø{
konstruktør () {
// ...
}

// producentfunktion til at tilføje e-mails til køen
asynkron addEmailToQueue (emailData) {
// tilføj opgave med navnet 'email_notification' til køen
ventedet her.queue.add('email_notification', emailData);
konsol.log('e-mailen er blevet tilføjet til køen...');
}
};

eksportStandard EmailQueue; // eksporter klassen

Producerfunktionen er klar, og du kan nu definere en forbrugerfunktion (ved hjælp af Bull's behandle() funktion) for at behandle alle e-mail-opgaver i køen – dvs. ring til funktionen for at sende en e-mail. Du bør definere denne forbrugerfunktion i klassens konstruktør.

// queueHandler.js
klasseE-mailkø{
konstruktør () {
// ...

// forbrugerfunktion, der tager det tildelte navn på opgaven og
// en tilbagekaldsfunktion
det her.kø.proces('email_notification', asynkron (e-mailJob, udført) => {
konsol.log('behandler e-mail notifikationsopgave');
vente emailHandler.sendEmail (emailJob); // send e-mailen
Færdig(); // fuldfør opgaven
})
}
// ...
};

eksportStandard EmailQueue; // eksporter klassen

Et job kan også have muligheder for at definere sin adfærd i køen eller hvordan forbrugerfunktionen håndterer det. Du kan få mere at vide om dette i jobmuligheder i Bulls dokumentation.

Det emailJob argument er et objekt, der indeholder egenskaberne for opgaven, som køen skal behandle. Det inkluderer også de vigtigste data, der er nødvendige for at konstruere e-mailen. For nem forståelse er Send e-mail() funktion ville ligne dette eksempel:

// emailHandler.js
konst sendgridMail = kræve('@sendgrid/mail');

konst apiKey = proces.env. SENDGRID_API_KEY

sendgridMail.setApiKey (apiKey); // sæt e-mail-transporter sikkerhedsoplysninger

konst sendE-mail = asynkron (emailJob) => {
prøve {
// udtræk e-mail-data fra jobbet
konst { navn, email } = emailJob.data;

konst besked = {
fra: '[email protected]',
til: '[email protected]',
emne: 'Hej! Velkommen',
tekst: 'Hej ${name}, velkommen til MUO`
};

vente sendgridMail.sendMail (besked); // Send e-mail

// marker opgave som afsluttet i køen
vente emailJob.moveToCompleted('Færdig', rigtigt);
konsol.log('E-mail sendt med succes...');
} fangst (fejl) {
// flyt opgaven til mislykkede job
vente emailJob.moveToFailed({ besked: 'opgavebehandling mislykkedes..' });
konsol.fejl (fejl); // log fejlen
}
}

eksportStandard Send e-mail;

Nu hvor du har både producent- og forbrugerfunktionerne defineret og klar til brug, kan du nu ringe til din producentfunktion hvor som helst i din ansøgning for at tilføje en e-mail til køen til behandling.

Et eksempel på en controller ville se sådan ud:

// userController.js
konst EmailQueue = kræve('../handlers/queueHandler.js')

konst tilmelding = asynkron (req, res) => {
konst { navn, e-mail, adgangskode } = req.body;

// --
// en forespørgsel for at tilføje den nye bruger til databasen...
// --

// tilføje til e-mail-kø
konst emailData = { navn, email };
vente EmailQueue.addEmailToQueue (emailData);

res.status(200).json({
besked: "Tilmelding lykkedes, tjek venligst din e-mail"
})
}

Din queueHandler.js filen skal nu være som følger:

// queueHandler.js
konst Kø = kræve('tyr');
konst emailHandler = kræve('../handlers/emailHandler.js');

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

konst queueOpts = {
begrænser: {
max: 100,
varighed: 10000
},

præfiks: 'EMAIL-OPGAVE',

defaultJobOptions: {
forsøg: 3,
removeOnComplete: rigtigt
}
};

klasseE-mailkø{
konstruktør() {
det her.kø = ny Kø('E-mail-kø', REDIS_URL, queueOpts);

// forbruger
det her.kø.proces('email_notification', asynkron (e-mailJob, udført) => {
konsol.log('behandler e-mail notifikationsopgave');
vente emailHandler.sendEmail (emailJob);
Færdig();
})
}

// producent
asynkron addEmailToQueue (emailData) {
// tilføj opgave med navnet 'email_notification' til køen
ventedet her.queue.add('email_notification', emailData);
konsol.log('e-mailen er blevet tilføjet til køen...');
}
};

eksportStandard EmailQueue;

Når du implementerer dette i en Node.js REST API, vil du bemærke et fald i responstiden for tilmeldingsslutpunktet og hurtigere leveringstider for e-mail sammenlignet med alternativet.

Opgavekøer gjorde det også muligt for dig at håndtere tilmeldings- og e-mail-fejl uafhængigt.

Optimering af applikationer ved hjælp af opgavekøer

Besked- og opgavekøer er en fantastisk måde at forbedre applikationernes generelle ydeevne på. De er også meget billige, og du kan bruge dem i lige så mange dele af en applikation, som du har brug for.

Selvom denne vejledning brugte e-mails som et eksempelscenarie til håndtering af hukommelseskrævende opgaver med køer, er der mange andre tilfælde, hvor du kan anvende de samme koncepter. Disse omfatter tunge læse-/skriveoperationer, gengivelse af billeder eller dokumenter i høj kvalitet og udsendelse af massemeddelelser.