Serverless após um ano em produção

Junior Ferreira
How Kovi Work
Published in
4 min readOct 1, 2019

A arquitetura Serverless tem deixado de ser apenas uma hype e começa a substituir algumas aplicações em containers. No início da Kovi, tudo precisava ser muito rápido, devido a isso foi adotado a cultura Serverless para desenvolvimento.

Em um ano, o time escreveu 20 mil linhas de código Serverless, nessas 20 mil linhas escritas apareceram diversas dúvidas sobre problemas que poderiam ser evitados caso tivéssemos adotado uma arquitetura tradicional, nesse cenário teríamos a solução na ponta da língua.

Lembrando que o time inicial tem o domínio na stack Javascript e AWS, então tudo que foi feito, foi pensado em Node.Js com os serviços da AWS.

Como organizar?

Os primeiros problemas eram claros: Como organizar a regra de negócio com a camada de serviço?

Seria inviável pensando em performance (tempo), ter que configurar todos os serviços manualmente, como: SQS, Cognito, Rotas do API Gateway, DynamoDB e S3.

Para isso já existem muitos frameworks que desacoplam o Provedor dos serviços (Aws, Google, IBM) da regra de negócio, deixando o código agnóstico do provedor.

Existem muitos frameworks, mas dois se destacam. Serverless Framework e o Apex.

Apex tem uma comunidade maior em Go lang, já o Serverless Framework em Javascript, ambos são agnósticos de runtime (linguagens suportadas).

De primeira escolhemos o Serverless Framework, principalmente pela forte comunidade javascript que possui.

Organizando a criação dos serviços com o Handler (Função que carrega a regra de negócio), identificamos outro problema: A repetição de código. O que em uma arquitetura tradicional seria fácil de driblar.

Pensando em reaproveitar código com workers (crons e filas) e services (Http ou Socket), escolhemos adotar a estratégia do monorepo, e para gerenciar tudo isso, usamos o Lerna (Gerenciador de monorepo em Javascript).

Com o Lerna consigo compartilhar código versionado entre os services e workers.

Resumidamente, tenho um diretório que possui todos os domínios (chamado de packages), um para workers, que carrega tudo que irei rodar com filas ou Crons, e um para services, com tudo que será servido a um Graphql ou Rest.

Ambiente de Desenvolvimento:

Infelizmente não há um Docker oficial da AWS que simule o off-line.

Isso é um problema.

Desenvolver localmente seria inviável visto que toda hora que terminar parte de um código teríamos que fazer um deploy para analisar o resultado.

Existe um conjunto de plugins que apenas simula parte da infraestrutura.

Eles ajudam muito, porem no final de qualquer implantação sempre temos que fazer um double check no ambiente de Homologação dentro da AWS, para ter certeza que irá funcionar corretamente.

Deploy:

O arquivo de configuração de Serverless Framework, já é basicamente um script de CI/CD, apenas precisamos da ferramenta para fazer o deploy.

E a ferramenta escolhida foi o seed.run, com ele podemos fazer deploy e o gerenciamento de monorepo serverless de forma fácil e com um custo baixo.

Produção:

Em produção, percebemos as primeiras vantagens e desvantagens dessa arquitetura, são elas:

· (Desvantagem) Cold-start: A famosa partida a frio, as primeiras chamadas são deficientes em quesito latência, e em nossas métricas isso visível, mas esse ponto não traz grande impacto para Kovi.

· (Desvantagem) Log & métricas: Eu particularmente amo o New Relic, mas em lambda é inviável (devido ao custo). Existem muitas soluções (dashbird, datadog, logDNA, sentry), porém nenhuma delas reúne a solução centralizada com um preço acessível. Usamos Sentry para erros e o deficiente CloudWatch para logs e métricas. Alias acredito que isso melhore com tempo dentro da própria AWS.

· (Desvantagem) Custo: Pois é, custo é uma vantagem se souber usar da maneira correta, se não, será mais caro que uma aplicação em container. Na Aws, recurso de lambda é limitado. O limite de uma execução é de 300 segundos, deixar a função chegar sempre nesse limite não é uma boa ideia. Além do que não é recomendado para uma aplicação que possui milhões de acessos constantes por dia, pois o API Gateway pode ser um cavalo de troia um dia, devido aos custos ocultos dele.

· (Desvantagem) Ambiente Local: Está melhorando muito, mas a Aws precisa urgentemente solucionar isso.

· (Vantagem) Tempo: Não precisamos mais provisionar, gerenciar ou pensar em como a Kovi aumentará ou diminuirá suas demandas. Apenas focamos na implementação. Em suma, todo tempo que iria gastar lidando com a infraestrutura gastamos em mais features para o MVP.

· (Vantagem) Custo: Como dito anteriormente, se souber usar da maneira correta o preço final será estupidamente barato, pois pagamos apenas pelo que usamos!

· (Vantagem) Linhas de código: Acredito que a diminuição de linhas se deu por usar monorepo (Lerna), caso contrário, talvez seria maior.

· (Vantagem) Manutenção: Já pensou em dar manutenção em apenas uma rota do seu microservice? Com serverless, isso é possível! Usando o seed.run, conseguimos fazer deploys específicos sem afetar outras rotas.

· (Vantagem) Multi-implementação: Javascript não é bala de prata das linguagens e o time de tecnologia também escala, logo podemos ter algumas funções do mesmo microservice em Python, Go, Ruby, Java ou C#.

Conclusão:

Em um ano de produção, houve mais resultados positivos do que negativos.

A arquitetura Serverless nos deu velocidade nas entregas, e os problemas apresentados foram rapidamente driblados. Hoje cerca de 90% da solução da Kovi é Serverless, mas ainda quase 10% não é atendida por essa arquitetura devida a custo ou implementação, logo optamos por deixar em containers para não fazer do serverless uma péssima experiência.

--

--