Skip to main content
programador usando um imac

Aplicações Serverless: como construir usando JAVA?

Aplicações serverless não são mais uma novidade. Em todos os eventos de TI podemos ver que muitos arquitetos, engenheiros e programadores estão utilizando essa arquitetura em suas empresas.

É importante dizer que as vantagens das aplicações serverless são várias. Desde o uso de várias linguagens ao mesmo tempo, até maior produtividade e abertura para inovação em desenvolvimento de software.

Geralmente essas implementações são feitas utilizando linguagens de programação como Python, NodeJS e Golang.

Mas porque a linguagem de programação mais popular do mundo não está nessa lista?

Sim, eu estou falando do Java.

Hoje eu quero te introduzir à construção de uma aplicação serveless usando Java.

Vamos lá!

Vamos entender cold start

programador programando

Para falarmos sobre a falta depopularidade do Java com serverless vamos primeiro abordar o conceito de cold start, importante característica do function as a service (que é a outra forma de nos referirmos a essa arquitetura).

De modo geral, o cold start é o termo usado para descrever o fenômeno de que os aplicativos que não foram usados por um tempo demoram mais para serem iniciados.

Para facilitar o entendimento temos a imagem abaixo que exemplifica o funcionamento do cold start.

Vamos pensar numa linha do tempo que vai do tempo 1 até o tempo 3.

No tempo 1 você faz 2 (duas) requisições simultâneas para a função 1 (F1) e 1 (uma) requisição para a função 2 (F2).

Nesse momento não havia nenhuma dessas funções ativas e o provider teve que iniciá-las para poder executar.

No caso da F1 ainda tivemos que iniciar 2 (duas) instâncias, pois foram requisições simultâneas. Isso é o cold start.

Para executar essas funções o tempo total de execução foi de cold start + execução da função.

Já no tempo 2 houve uma requisição para F1 e uma para F2. Ambas já tinham instâncias iniciadas e não precisou iniciar, somente tivemos que executar.

Nesse caso, assim como no tempo 3, não houve cold start e o tempo de execução total da função foi exclusivamente o tempo de execução da função.

Cold start e o Java

Agora que vimos sobre o conceito do Cold Start vamos entender a relação disso com o Java.

Acontece que o Java trabalha com máquina virtual e a memória é instanciada logo na inicialização da JVM.

Esse processo pode ser custoso a depender de quanta memória foi alocada para a função serverless.

Para que isso não seja um problema em suas funções em Java separei algumas dicas valiosas para viabilizar o desenvolvimento.

Essas dicas podem ser mais ou menos relevantes a depender do propósito da sua função.

Se é um processo assíncrono, que não é bloqueante para o usuário, talvez você não precise ser tão rigoroso quanto ao tempo de processamento.

Mas ao mesmo tempo não pode descuidar tanto pois a forma de cobrança dos providers geralmente é um cálculo do Tempo de execução x memória alocada.

Dicas para construir a aplicação em serverless com Java

programador em frente ao computador


“Essa eu dedico aos javeiros como eu” 🙂

Stateless

Pense em sua função totalmente stateless. Não necessariamente a próxima função que você executar ainda terá o estado que você precisa, pois quem gerencia isso é o provider. Por conceito o Serverless é Stateless;

Classpath Scanner

Evite utilizar classpath scanner ou APIs que façam isso. Quando você inicia a JVM e algum processo é startado para fazer classpath scanner você deixa o tempo de cold start maior;

Atributos static

A utilização de atributos static tem efeito prático e semelhante ao do item anterior. Por precisar iniciar instâncias logo ao subir a JVM o cold start será maior.

Opte por instanciar os objetos necessários à medida que sua função precisar.

Memória alocada para a JVM

Os Programadores Java (me incluo nessa) são conhecidos por não se preocuparem com o uso de memória. Trabalhando com Serverless é extremamente importante pensar em economia de memória. Quanto menos memória precisar dar pra JVM, menos tempo de cold start.

APIs

Priorize utilização de APIs light weight.

Muitas das APIs tradicionais que utilizamos em projetos com Spring Boot ou Java EE não são uma boa ideia no mundo Serverless.

Isso porque eles tem um tempo de bootstrap alto e isso vai afetar diretamente o cold start. Então, dê preferência a APIs leves ou até mesmo “codar” algo próprio bem mais “roots”;

Serverless code

homem segurando post it amarelo


Show me the code…

Quando temos que fazer acesso a um banco de dados relacional em Java geralmente utilizamos um ORM como o Hibernate, por exemplo.

Para Serverless isso não é uma boa estratégia. Por esse motivo selecionei essa camada para exemplificar como seria uma boa prática.

No exemplo abaixo utilizo um wrapper JDBC ao invés de um ORM. Nesse caso estou utilizando a API Fluent JDBC Wrapper.

 
DataSource dataSource = ConnectionUtil.getDataSource();
       try {
           return new JdbcSession(dataSource)
                   .sql("SELECT agency, accountnumber, status, name FROM account WHERE agency = ? and accountnumber = ?")
                   .set(agency)
                   .set(accountNumber)
                   .select(
                           (ResultSet rset, Statement statement) -> {
                               AccountEntity account = new AccountEntity();
                               while (rset.next()) {
                                   account.setAgency(rset.getInt("agency"));
                                   account.setAccountNumber(rset.getInt("accountnumber"));
                                   account.setStatus(AccountEntity.AccountStatus.valueOf(rset.getString("status")));
                                   account.setName(rset.getString("name"));
                               }
                               return account;
                           });


Vejam que o acesso aos dados é bem mais simplificado pela forma fluente que a API foi construída, sem toda a burocracia que o JDBC têm.

Por ser apenas um wrapper do JDBC o bootstrap não é alto e isso evita que o cold start seja custoso. Outras opções interessantes são o jOOQ e o ActiveJDBC dependendo da necessidade.

No exemplo obtenho um datasource e com ele faço uma consulta SQL conectando em um banco de dados PostgreSQL. Com o resultado instancio um objeto com leve só com o que preciso.

Mostrei um exemplo para acesso a camada de dados. Mas poderia ser um acesso a um webservice externo.

A lógica seria a mesma, procurar por uma API mais leve que as tradicionais ou até mesmo usar um wrapper de URLConnection.

Caso queiram ver esse código funcionando podem acessar meu GitHub no projeto debit-authorizer. Esse projeto é uma prova de conceito em cima de um cenário real de uma instituição financeira.

Façam seus testes e fiquem a vontade para dar feedbacks sobre essas dicas e complementar com outras coisas que eu não tenha comentado.

Obrigado!


Aplicações Serverless: como construir usando JAVA?
4.6 (91.11%) 9 votes