I lettori come te aiutano a sostenere MUO. Quando effettui un acquisto utilizzando i link sul nostro sito, potremmo guadagnare una commissione di affiliazione. Per saperne di più.

In qualità di sviluppatore web, è fondamentale che le tue app funzionino il più rapidamente possibile. Dovresti creare app Web che rispondano alle richieste nel minor tempo possibile.

Una delle tante tecnologie che possono aiutarti è l'accodamento delle attività.

Quindi, cos'è l'accodamento delle attività e come puoi utilizzarlo per ottimizzare un'applicazione Node.js?

Cos'è l'accodamento delle attività?

L'accodamento dei messaggi è un mezzo di comunicazione asincrona tra due applicazioni o servizi, generalmente indicato come produttore E consumatore. È un concetto ben noto utilizzato nelle architetture serverless e a microservizi.

Il concetto di compito O lavoroin coda sfrutta l'accodamento dei messaggi per migliorare le prestazioni dell'applicazione. Astrae le complessità della gestione dei messaggi e consente di definire funzioni per gestire lavori o attività in modo asincrono utilizzando una coda, riducendo così il tasso di

instagram viewer
utilizzo della memoria in alcune parti di un'applicazione.

L'esempio più comune di software per la coda dei messaggi è RabbitMQ. Gli strumenti per la coda delle attività includono Celery e Bull. Puoi anche configurare RabbitMQ in modo che funzioni come una coda di attività. Continua a leggere per conoscere l'accodamento delle attività in Node.js utilizzando Bull.

Cos'è BullMQ?

BullMQ (Bull.js) è una libreria Node.js utilizzata per implementare le code nelle applicazioni Node. Bull è un sistema basato su Redis (potresti avere più familiarità con Redis come strumento per rapida memorizzazione dei dati) ed è un'opzione rapida e affidabile da considerare per l'accodamento delle attività in Node.js.

Puoi utilizzare Bull per molte attività come l'implementazione di lavori ritardati, lavori pianificati, lavori ripetibili, code prioritarie e molto altro.

Quindi, come puoi utilizzare Bull e Redis per eseguire attività Node.js in modo asincrono?

Come configurare Bull e Redis per l'accodamento delle attività in Node.js

Per iniziare con l'accodamento delle attività in Node.js con Bull, devi installare Node.js e Redis sulla tua macchina. Puoi seguire il Guida ai laboratori Redis per installare Redis se non lo hai installato.

Il primo passo per implementare Bull è aggiungerlo alle dipendenze del tuo progetto eseguendo npm installa toro O filato aggiungere toro nel terminale all'interno della cartella del tuo progetto. Esistono diversi modi per inizializzare una coda in Bull come mostrato di seguito:

cost coda = richiedere('toro');

// diversi modi per inizializzare una coda
// - utilizzando la stringa URL redis
cost emailQueue = nuovo Coda('Coda email', 'redis://127.0.0.1:6379');

// - con una connessione redis e un oggetto opzioni coda
cost coda video = nuovo Coda("Coda video", 'redis://127.0.0.1:6379', opzioni coda);

// - senza una connessione redis ma con queueOption
cost docQueue = nuovo Coda('Coda documenti', opzioni coda);

// - senza una connessione redis o opzioni di coda
cost QueueClient = nuovo Coda("La mia coda");

Tutti usano una configurazione minima per Bull in Node.js. L'oggetto opzioni supporta molte proprietà e puoi conoscerle nel file sezione delle opzioni di coda della documentazione di Bull.

Implementazione di una coda di attività e-mail utilizzando BullMQ

Per implementare una coda per l'invio di e-mail, puoi definire la tua funzione produttore che aggiunge e-mail alla coda e-mail e una funzione consumatore per gestire l'invio di e-mail.

In primo luogo, puoi inizializzare la tua coda in una classe utilizzando un URL Redis e alcune opzioni di coda come mostrato di seguito.

// queueHandler.js
cost coda = richiedere('toro');

// usa un vero modulo di gestione della posta qui - questo è solo un esempio
cost emailHandler = richiedere('./emailHandler.js');

// definisce le costanti, l'URL Redis e le opzioni della coda
cost REDIS_URL = 'redis://127.0.0.1:6379';

cost opzionicoda = {
// opzioni del limitatore di velocità per evitare di sovraccaricare la coda
limitatore: {
// numero massimo di attività che la coda può richiedere
massimo: 100,

// tempo di attesa in millisecondi prima di accettare nuovi lavori dopo
// raggiungimento del limite
durata: 10000
},
prefisso: 'E-MAIL-TASK', // un prefisso da aggiungere a tutte le chiavi della coda
defaultJobOptions: { // opzioni predefinite per le attività in coda
tentativi: 3, // numero predefinito di volte per riprovare un'attività

// per rimuovere un'attività dalla coda dopo il completamento
removeOnComplete: VERO
}
};

classeCoda e-mail{
costruttore() {
Questo.coda = nuovo Coda('Coda email', REDIS_URL, queueOpts);
}
};

esportarepredefinito EmailQueue; // esporta la classe

Ora che hai inizializzato una coda, puoi definire la tua funzione produttore (usando Bull's aggiungere() funzione) come metodo di Coda e-mail class per aggiungere e-mail alla coda delle attività. Il seguente blocco di codice lo dimostra:

// queueHandler.js

classeCoda e-mail{
costruttore () {
// ...
}

// funzione producer per aggiungere le email alla coda
asincrono addEmailToQueue (emailData) {
// aggiunge attività con nome 'email_notification' alla coda
aspettaQuesto.queue.add('notifica per email', e-mailDati);
consolare.tronco d'albero('l'email è stata aggiunta alla coda...');
}
};

esportarepredefinito EmailQueue; // esporta la classe

La funzione produttore è pronta e ora puoi definire una funzione consumatore (usando Bull's processi() funzione) per elaborare tutte le attività di posta elettronica in coda, ad es. chiama la funzione per inviare un'e-mail. Dovresti definire questa funzione consumer nel costruttore della classe.

// queueHandler.js
classeCoda e-mail{
costruttore () {
// ...

// funzione consumer che accetta il nome assegnato all'attività e
// una funzione di richiamata
Questo.coda.processo('notifica per email', asincrono (emailLavoro, fatto) => {
consolare.tronco d'albero('elaborazione dell'attività di notifica e-mail');
aspetta emailHandler.sendEmail (emailJob); // invia l'e-mail
Fatto(); // completa il compito
})
}
// ...
};

esportarepredefinito EmailQueue; // esporta la classe

Un lavoro può anche avere opzioni per definire il suo comportamento nella coda o come la funzione del consumatore lo gestisce. Puoi saperne di più su questo nel sezione delle opzioni di lavoro della documentazione di Bull.

IL emailJob argomento è un oggetto che contiene le proprietà dell'attività per l'elaborazione della coda. Include anche i dati principali necessari per costruire l'e-mail. Per una facile comprensione, il invia una email() funzione sarebbe simile a questo esempio:

// emailHandler.js
cost sendgridMail = richiedere('@sendgrid/posta');

cost apiKey = process.env. SENDGRID_API_KEY

sendgridMail.setApiKey (apiKey); // imposta le credenziali di sicurezza del trasportatore di posta elettronica

cost inviaEmail = asincrono (emailLavoro) => {
Tentativo {
// estrae i dati email dal lavoro
cost { nome, email } = emailJob.data;

cost messaggio = {
da: '[email protected]',
A: '[email protected]',
soggetto: 'CIAO! Benvenuto',
testo: `Ciao ${nome}, benvenuto in MUO`
};

aspetta sendgridMail.sendMail (messaggio); // invia una email

// contrassegna l'attività come completata nella coda
aspetta emailJob.moveToCompleted('Fatto', VERO);
consolare.tronco d'albero('Email inviata correttamente...');
} presa (errore) {
// sposta l'attività nei lavori non riusciti
aspetta emailJob.moveToFailed({ Messaggio: 'elaborazione dell'attività non riuscita..' });
consolare.errore (errore); // registra l'errore
}
}

esportarepredefinito invia una email;

Ora che hai definito e pronte per l'uso entrambe le funzioni producer e consumer, puoi ora chiamare la funzione producer in qualsiasi punto dell'applicazione per aggiungere un messaggio di posta elettronica alla coda per l'elaborazione.

Un controller di esempio sarebbe simile a questo:

// userController.js
cost EmailQueue = richiedere('../gestori/queueHandler.js')

cost iscriviti = asincrono (req, res) => {
cost { nome, email, password } = req.body;

// --
// una query per aggiungere il nuovo utente al database...
// --

// aggiunge alla coda di posta elettronica
cost emailData = { nome, email };
aspetta EmailQueue.addEmailToQueue (emailData);

res.stato(200).json({
Messaggio: "Iscrizione avvenuta con successo, controlla la tua email"
})
}

Tuo queueHandler.js il file ora dovrebbe essere il seguente:

// queueHandler.js
cost coda = richiedere('toro');
cost emailHandler = richiedere('../gestori/emailHandler.js');

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

cost opzionicoda = {
limitatore: {
massimo: 100,
durata: 10000
},

prefisso: 'E-MAIL-TASK',

defaultJobOptions: {
tentativi: 3,
removeOnComplete: VERO
}
};

classeCoda e-mail{
costruttore() {
Questo.coda = nuovo Coda('Coda email', REDIS_URL, queueOpts);

// consumatore
Questo.coda.processo('notifica per email', asincrono (emailLavoro, fatto) => {
consolare.tronco d'albero('elaborazione dell'attività di notifica e-mail');
aspetta emailHandler.sendEmail (emailJob);
Fatto();
})
}

// produttore
asincrono addEmailToQueue (emailData) {
// aggiunge attività con nome 'email_notification' alla coda
aspettaQuesto.queue.add('notifica per email', e-mailDati);
consolare.tronco d'albero('l'email è stata aggiunta alla coda...');
}
};

esportarepredefinito EmailQueue;

Quando lo implementi in un'API REST di Node.js, noterai una riduzione del tempo di risposta dell'endpoint di registrazione e tempi di consegna della posta più rapidi rispetto all'alternativa.

Le code di attività ti hanno anche consentito di gestire gli errori di registrazione e di posta elettronica in modo indipendente.

Ottimizzazione delle applicazioni utilizzando le code di attività

Le code di messaggi e attività sono un ottimo modo per migliorare le prestazioni generali delle applicazioni. Sono anche molto economici e puoi usarli in tutte le parti di un'applicazione di cui hai bisogno.

Anche se questo tutorial ha utilizzato i messaggi di posta elettronica come scenario di esempio per la gestione delle attività che consumano memoria con le code, esistono molti altri casi in cui è possibile applicare gli stessi concetti. Questi includono pesanti operazioni di lettura/scrittura, rendering di immagini o documenti di alta qualità e invio di notifiche in blocco.