La simplicité de Cloud Functions vous permet de développer rapidement du code et de l'exécuter dans un environnement sans serveur. À une échelle modérée, le coût d'exécution des fonctions est faible et l'optimisation de votre code peut ne pas sembler être une priorité. Cependant, à mesure que votre déploiement évolue, l'optimisation de votre code devient de plus en plus importante.
Ce document décrit comment optimiser la mise en réseau de vos fonctions. Certains des avantages de l'optimisation de la mise en réseau sont les suivants :
- Réduisez le temps CPU consacré à l'établissement de nouvelles connexions à chaque appel de fonction.
- Réduisez la probabilité de manquer de connexion ou de quotas DNS .
Maintenir des connexions persistantes
Cette section donne des exemples sur la façon de maintenir des connexions persistantes dans une fonction. Si vous ne le faites pas, vous risquez d'épuiser rapidement les quotas de connexion.
Les scénarios suivants sont couverts dans cette section :
- HTTP/S
- API Google
Requêtes HTTP/S
L'extrait de code optimisé ci-dessous montre comment maintenir des connexions persistantes au lieu de créer une nouvelle connexion à chaque appel de fonction :
const http = require('http'); const functions = require('firebase-functions'); // Setting the `keepAlive` option to `true` keeps // connections open between function invocations const agent = new http.Agent({keepAlive: true}); exports.function = functions.https.onRequest((request, response) => { req = http.request({ host: '', port: 80, path: ' ', method: 'GET', agent: agent, // Holds the connection open after the first invocation }, res => { let rawData = ''; res.setEncoding('utf8'); res.on('data', chunk => { rawData += chunk; }); res.on('end', () => { response.status(200).send(`Data: ${rawData}`); }); }); req.on('error', e => { response.status(500).send(`Error: ${e.message}`); }); req.end(); });
Accéder aux API Google
L'exemple ci-dessous utilise Cloud Pub/Sub , mais cette approche fonctionne également pour d'autres bibliothèques clientes, par exemple, Cloud Natural Language ou Cloud Spanner . Notez que les améliorations de performances peuvent dépendre de l'implémentation actuelle de bibliothèques clientes particulières.
La création d'un objet client PubSub
entraîne une connexion et deux requêtes DNS par appel. Pour éviter les connexions inutiles et les requêtes DNS, créez l'objet client PubSub
dans une portée globale, comme illustré dans l'exemple ci-dessous :
const PubSub = require('@google-cloud/pubsub'); const functions = require('firebase-functions'); const pubsub = PubSub(); exports.function = functions.https.onRequest((req, res) => { const topic = pubsub.topic(''); topic.publish('Test message', err => { if (err) { res.status(500).send(`Error publishing the message: ${err}`); } else { res.status(200).send('1 message published'); } }); });
Test de charge de votre fonction
Pour mesurer le nombre de connexions effectuées en moyenne par votre fonction, déployez-la simplement en tant que fonction HTTP et utilisez un framework de test de performances pour l'invoquer à certains QPS. Un choix possible est Artillery , que vous pouvez invoquer avec une seule ligne :
$ artillery quick -d 300 -r 30 URL
Cette commande récupère l'URL donnée à 30 RPS pendant 300 secondes.
Après avoir effectué le test, vérifiez l'utilisation de votre quota de connexion sur la page de quota de l'API Cloud Functions dans Cloud Console. Si l'utilisation est constamment autour de 30 (ou son multiple), vous établissez une (ou plusieurs) connexions à chaque invocation. Après avoir optimisé votre code, vous devriez voir quelques connexions (10 à 30) se produire uniquement au début du test.
Vous pouvez également comparer le coût du processeur avant et après l'optimisation sur le tracé du quota de processeur sur la même page.