Ir para o console

Como otimizar redes

As funções do Cloud Functions são bem simples e, com elas, você pode desenvolver um 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 prioridade tão urgente. No entanto, à medida que a implantação evolui, otimizar o código torna-se cada vez mais importante.

Neste documento, você verá como otimizar a rede para suas funções. Veja a seguir alguns dos benefícios da otimização de rede:

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

Como manter conexões permanentes

Nesta seção, você verá exemplos sobre como manter conexões permanentes em uma função. As cotas de conexão poderão se esgotar rapidamente caso você não faça isso.

As seguintes situações são abordadas nesta seção:

  • HTTP/S
  • APIs do Google

Solicitações HTTP/S

Veja abaixo no snippet de código otimizado como manter conexões permanentes em vez de criar uma nova conexão em cada chamada de função:

const http = require('http');
const functions = require('firebase-functions');
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,
    }, 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();
});

Como acessar as APIs do Google

O Cloud Pub/Sub foi usado para este exemplo, mas esta abordagem também funciona em outras bibliotecas de cliente, como a Cloud Natural Language ou a Cloud Spanner. Observe que as melhorias no desempenho podem depender da implementação atual de algumas bibliotecas de cliente.

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

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

Teste de carga da sua função

Para analisar quantas conexões sua função executa em média, basta implantá-la como uma função HTTP e usar uma estrutura de teste de desempenho para invocá-la em determinada taxa de consultas por segundo (QPS, na sigla em inglês). Uma escolha possível é o Artillery (em inglês), que pode ser invocado com uma única linha:

$ artillery quick -d 300 -r 30 URL

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

Depois de executar o teste, verifique o uso da cota de conexão na página de cota da API Cloud Functions no Console do Cloud. Se o uso for consistente em torno de 30 (ou múltiplos de 30), você está estabelecendo uma (ou várias) conexões a cada invocação. Depois de otimizar seu código, você verá algumas conexões (10 a 30) ocorrerem apenas no início do teste.

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