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
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.