Catch up on everything announced at Firebase Summit, and learn how Firebase can help you accelerate app development and run your app with confidence. Learn More

Otimizando a rede

Mantenha tudo organizado com as coleções Salve e categorize o conteúdo com base nas suas preferências.

A simplicidade do Cloud Functions permite desenvolver código rapidamente e executá-lo em um ambiente sem servidor. Em escala moderada, o custo de executar funções é baixo e otimizar seu código pode não parecer uma alta prioridade. À medida que sua implantação aumenta, no entanto, otimizar seu código torna-se cada vez mais importante.

Este documento descreve como otimizar a rede para suas funções. Alguns dos benefícios de otimizar a rede são os seguintes:

  • Reduza o tempo de CPU gasto no estabelecimento de novas conexões em cada chamada de função.
  • Reduza a probabilidade de ficar sem conexão ou cotas de DNS.

Mantendo Conexões Persistentes

Esta seção fornece exemplos de como manter conexões persistentes em uma função. Deixar de fazer isso pode resultar no esgotamento rápido das cotas de conexão.

Os seguintes cenários são abordados nesta seção:

  • HTTP/S
  • APIs do Google

Solicitações HTTP/S

O trecho de código otimizado abaixo mostra como manter conexões persistentes em vez de criar uma nova conexão a cada chamada de função:

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();
});

Acessando as APIs do Google

O exemplo abaixo usa Cloud Pub/Sub , mas essa abordagem também funciona para outras bibliotecas de cliente, por exemplo, Cloud Natural Language ou Cloud Spanner . Observe que as melhorias de desempenho podem depender da implementação atual de determinadas bibliotecas cliente.

A criação de um objeto de cliente PubSub resulta em uma conexão e duas consultas de DNS por invocação. Para evitar conexões desnecessárias e consultas de DNS, crie o objeto cliente PubSub no escopo global, conforme mostrado no exemplo abaixo:

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');
        }
    });
});

Testando sua função com carga

Para medir quantas conexões sua função realiza em média, basta implantá-la como uma função HTTP e usar uma estrutura de teste de desempenho para invocá-la em determinados QPS. Uma escolha possível é Artilharia , que você pode invocar com uma única linha:

$ artillery quick -d 300 -r 30 URL

Este comando busca o URL fornecido em 30 QPS por 300 segundos.

Depois de realizar o teste, verifique o uso de sua cota de conexão na página de cota da API Cloud Functions no Cloud Console. Se o uso estiver consistentemente em torno de 30 (ou seu múltiplo), você estará estabelecendo uma (ou várias) conexões em cada chamada. Depois de otimizar seu código, você verá algumas conexões (10-30) ocorrerem apenas no início do teste.

Você também pode comparar o custo da CPU antes e depois da otimização no gráfico de cota da CPU na mesma página.