Como implementar funções Node.js sem servidor usando o Google Cloud

Publicados: 2022-03-11

A criação de software não termina com a escrita de um bom código. Ele é concluído quando o software é implantado e capaz de lidar com as solicitações adequadamente e quando podemos dimensionar sem prejudicar o desempenho e o custo de execução.

Você provavelmente está pensando em como você tem a computação em nuvem para cuidar de todas essas coisas. “Então, o que é essa nova coisa sem servidor , Vignes?”

Funções do Node.js sem servidor usando o Google Cloud

A computação sem servidor é um estilo de arquitetura em que o código é executado em uma plataforma de nuvem onde não precisamos nos preocupar com a configuração de hardware e software, segurança, desempenho e custos de tempo ocioso da CPU. É um avanço da computação em nuvem que vai além da infraestrutura que também abstrai o ambiente de software. Isso significa que nenhuma configuração é necessária para executar o código.

Com serverless, o seguinte será seu estilo de trabalho:

  1. Desenvolva o código.

  2. Carregue o código para o provedor de serviços.

  3. Configure o gatilho (uma solicitação HTTP, no nosso caso).

Nosso trabalho está feito! Agora, o provedor da plataforma cuidará das solicitações recebidas e do dimensionamento.

Introdução aos microsserviços sem servidor

A arquitetura sem servidor geralmente é acoplada a um design de estilo de microsserviços. Um microsserviço é uma parte autônoma de um grande software que lida com solicitações de um módulo específico. Ao criar microsserviços que podem ser executados em um ambiente sem servidor, fica fácil manter o código e acelerar as implantações.

Introdução ao AWS Lambda e GCF, uma comparação

Um recurso sem servidor geralmente é chamado de “back-end como serviço” ou “função como serviço”. O número de provedores de computação sem servidor está começando a aumentar. No entanto, alguns dos grandes players tradicionais também oferecem opções sem servidor, como o AWS Lambda Functions da Amazon Web Services e o Google Cloud Functions (GCF), o último dos quais, enquanto atualmente em beta, é o que estou usando. Embora funcionem de forma semelhante, existem algumas diferenças importantes entre eles.

AWS Lambda Funções do Google Cloud
Suporte de linguas Node.js, Python, C#, Java Node.js
Gatilhos DynamoDB, Kinesis, S3, SNS, gateway de API (HTTP), CloudFront e mais HTTP, Cloud PubSub, bucket de armazenamento em nuvem
Tempo máximo de execução 300 segundos 540 segundos

Neste artigo, passaremos pelo processo de implementação de implantação de código sem servidor usando o GCF. O Google Cloud Functions é uma solução de computação assíncrona leve e baseada em eventos que permite criar funções pequenas e de finalidade única que respondem a eventos na nuvem sem a necessidade de gerenciar um servidor ou um ambiente de tempo de execução.

O GCF tem três implementações possíveis separadas com base em gatilhos.

  1. Gatilho HTTP Roteia solicitações HTTP para as funções de nuvem

  2. Gatilho pub/sub interno do Google Rotas de publicação e solicitações de assinatura para funções de nuvem

  3. Acionador do bucket de armazenamento em nuvem Roteia quaisquer alterações feitas no bucket de armazenamento para a função de nuvem

Vamos criar uma configuração baseada em gatilho HTTP usando o Google Cloud Functions

O Google Cloud Functions não requer nenhuma configuração ou instalação especial adicional. O GCF garante que o ambiente de nó padrão esteja configurado e pronto para execução. Quando uma função de nuvem é criada com HTTP como gatilho, ela fornece uma URL para acionar a função. Comparando com o AWS Lambda, que usa um gateway de API como meio de comunicação com ele, o Google Cloud Functions fornece o URL imediatamente com base no projectID e na região.

Diagrama do Google Cloud Platform - Cloud Functions e AWS Lambda

Como criar um aplicativo Node.js sem servidor

Para tornar nosso código executável no GCF, devemos envolver o código dentro de uma única função. O GCF chamará essa função específica sempre que o gatilho ocorrer. As maneiras possíveis de fazer isso são o upload,

  1. Arquivo único: Exporte uma função padrão que chamará outras funções com base na solicitação.

  2. Vários arquivos: Tenha um arquivo index.js exigindo todos os outros arquivos e exportando a função padrão como ponto de partida.

  3. Vários arquivos: Tenha um arquivo principal configurado em package.json usando "main": "main.js" como ponto de partida.

Qualquer um dos métodos acima funcionará.

O GCF tem uma versão de tempo de execução do Node específica compatível. Certifique-se de que o código foi escrito para oferecer suporte a essa versão específica. No momento da criação desta postagem, o GCF oferece suporte ao Node versão v6.11.1.

Para criar uma função, há poucas opções a serem consideradas.

  1. Memória Isso informa quanta memória é necessária para processar a solicitação por um tempo de execução. Definido em MB. Para um aplicativo pequeno, 128 MB deve ser suficiente, mas pode aumentar até 2 GB.

  2. Tempo limite O tempo limite, como o nome indica, define o tempo limite de execução do código esperado. Depois disso, o código será morto e parado. Qualquer execução após este ponto será interrompida abruptamente. O tempo limite máximo é de 540 segundos.

  3. Função a ser executada Embora mais de uma função possa ser exportada do arquivo do manipulador principal, precisamos configurar uma função que deve ser acionada para processar a solicitação. Isso permite que o desenvolvedor tenha vários pontos de entrada com base no método/URL HTTP.

Para fazer o upload do código, basta fazer uma cópia e colar do código para criar um portal de funções. Para mais de um arquivo, compacte o conteúdo e carregue o arquivo. Certifique-se, no caso de um arquivo ZIP, deve haver um arquivo index.js ou um arquivo package.json com o arquivo principal mencionado.

Qualquer dependência do módulo NPM deve ser mencionada em package.json . O GCF tenta instalar os módulos mencionados no arquivo package.json durante a primeira configuração.

Vamos criar um manipulador simples para retornar um status 200 e alguma mensagem. Crie uma função e adicione o seguinte código à fonte.

 exports.httpServer = function httpServer(req, res) { console.log(req); res.status(200).send('Server is working'); } 

Captura de tela da função que está sendo criada

Depois que a função for criada, abra a URL fornecida para acionar a função. Ele deve responder como o seguinte.

Captura de tela da saída do navegador "O servidor está funcionando"

Agora, vamos examinar o objeto req nos logs. Para visualizar os logs, o GCF oferece opções diretamente do console. Clique nos pontos verticais e abra a opção de logs.

Captura de tela da abertura da opção de logs

Agora, vamos atualizar o código para lidar com rotas simples para /users .

O código a seguir é usado para lidar com uma solicitação GET & POST simples para a rota /users :

 exports.httpServer = function httpServer(req, res) { const path = req.path; switch(path) { case '/users': handleUsers(req, res); break; default: res.status(200).send('Server is working'); } }; const handleUsers = (req, res) => { if (req.method === 'GET') { res.status(200).send('Listing users...'); } else if (req.method === 'POST') { res.status(201).send('Creating User...') } else { res.status(404); } }

Após a atualização, vamos testá-lo no navegador agora, mas desta vez com /users no final.

Captura de tela da saída do navegador "Listando usuários..."

Isso é legal. Criamos um servidor HTTP básico com roteamento.

Operações e depuração

Se o código fosse onde a história terminasse, você não estaria pesquisando opções de infraestrutura como aplicativos Node.js sem servidor. Aqui está um breve resumo de como cuidar de tarefas comuns, como implantação e depuração. Coisas que os desenvolvedores do Node.js já fazem para outros aplicativos.

Desdobramento, desenvolvimento:

O código para funções pode ser implantado de quatro maneiras.

  • Copie colando o código no console

  • Carregando um arquivo ZIP

  • Como implantar do bucket de armazenamento em nuvem como um arquivo ZIP

  • Como implantar a partir do repositório de origem na nuvem

A opção mais conveniente é, obviamente, implantar a partir de um repositório de origem.

Invocação:

Ao criar a função, o Console fornece o URL HTTP para acionar a função que está no formato: https://<region>-<project-id>.cloudfunctions.net/<function-name>

A função do AWS Lambda tem problemas de inicialização a frio que fazem com que a execução da função leve mais tempo para inicializar. Uma vez iniciadas, as seguintes execuções responderão normalmente. Este tempo de inicialização adicional inicial é referido como uma partida a frio. Embora não tenhamos a documentação oficial do GCF relacionada a esse tópico, os problemas de inicialização a frio não apareceram durante nossos testes.

Depuração:

O GCF se integra ao serviço Stackdriver Logging no Google Cloud. Todos os logs e erros do console serão registrados aqui e isso ajuda a depurar o código já implantado.

Teste:

O console fornece opções para testar a função passando um JSON como entrada. A função será chamada com JSON como entrada e a saída será exibida no console. A solicitação (entrada) e a resposta são semelhantes à estrutura Express.js e podem ser testadas durante o próprio processo de desenvolvimento. Se você precisar de uma atualização sobre os testes do Node.js, confira Um guia do Node.js para realmente fazer testes de integração

Limitações e próximos passos

O uso de funções sem servidor tem suas próprias vantagens, também vem com limitações

  • Aprisionamento do fornecedor: limita o código que escrevemos para um provedor de serviços específico. Mover o código para outro provedor requer reescrever o código com esforços significativos para a migração. Como isso pode ser um grande problema, devemos ter muito cuidado ao escolher um provedor de serviços.

  • Limitações no número de solicitações e recursos de hardware: os provedores geralmente limitam o número de solicitações paralelas que uma função manipulará por vez. Existem restrições de memória também. Esses tipos de restrições podem ser aumentados falando com o provedor, mas eles ainda existirão.

O Google Cloud Functions está amadurecendo e melhorando muito. Ele ainda está sendo aprimorado e atualizado com frequência, especialmente nos idiomas que pode suportar. Se você planeja usar as funções do Google Cloud, fique de olho nos logs de alterações para evitar alterações importantes na implementação.


Leitura adicional no Blog da Toptal Engineering:

  • Trabalhando com suporte a TypeScript e Jest: um tutorial do AWS SAM