Neste post gostaríamos de aprofundar o relato sobre nossa parceria com um de nossos clientes.
Como já dissemos trata-se de nossa experiência na entrega de um projeto que visou a re-construção de um produto existente.
Dentre as motivações por trás do projeto existia o desejo de reduzir os custos com a operação do produto.
Para outras informações sobre o cenário deste relato leia este post.
O modelo SaaS esteve em nosso horizonte desde o início dos trabalhos do projeto.
É interessante o fato de que as promessas deste modelo não anulavam em nosso cliente o interesse em adotar também a abordagem on-premises. Pois é, sabemos que o mercado nunca é muito óbvio.
Nós, time de desenvolvimento, fizemos o seguinte: não engessamos nenhum destes modelos na arquitetura do novo aplicativo. E não lembro disto ter custado qualquer coisa para nós. Após mais de 20 sprints de projeto o PO colocou no topo do backlog requisitos relacionados à distribuição do aplicativo, e só então chegou o momento de priorizarmos um dos modelos. O Molesim, então nosso Scrum Master, facilitou uma reunião onde os stakeholders do projeto apresentaram seus interesses e o time apresentou diferentes opções de arquitetura. Optou-se pelo modelo SaaS e por uma arquitetura que oferece um ótimo equilíbrio entre compartilhamento de recursos e isolamento de dados.
Estranhou o fato de que tratamos um assunto tão importante depois da vigésima sprint?
O fato é que cultivamos uma arquitetura emergente durante todo o projeto. Também prezamos pela simplicidade e pelo bom design de código, mas neste quesito é importante evitar pecar por excesso. Uma boa cobertura de testes é o último elemento desta fórmula. O resultado é a coragem necessária para conciliar a ansiedade de resolver um problema complexo com as prioridades do negócio. Se a solução para o problema fosse desconhecida, teríamos planejado uma prova de conceito com o PO, e assim fizemos antes de solucionar alguns outros requisitos do projeto.
Quais resultados foram conseguidos?
Atualmente a projeção de custos com operação e infra-estrutura está compatível com a realidade desejada pela Lumera.
Esta projeção está aderente à expectativa de que os custos não aumentem exponencialmente em função do número de cartórios atendidos pelo produto (lembrando que o cartório é o cliente final).
Mais detalhes sobre a solução
Daqui em diante vamos aprofundar os aspectos técnicos existentes e como implementamos a arquitetura escolhida. Um bom momento para enchermos nossa xícara de café.
As diferentes opções de arquitetura identificadas resumem-se a três abordagens macro:
- On-premises
Instalação dos componentes do aplicativo em servidores que integram a infra-estrutura do cliente final. - SaaS não compartilhado
Distribuição do software a partir da nuvem. Cada cliente possui servidores exclusivos. - SaaS compartilhado
Distribuição do software a partir da nuvem. Os mesmos servidores são compartilhados por diferentes clientes. Existem diferentes maneiras de implementar este compartilhamento.
A abordagem escolhida foi aquela que oferece o menor custo operacional e de infra-estrutura: SaaS compartilhado. Existem diferentes opções para implementar este modelo no que diz respeito à arquitetura dos dados:
A opção escolhida foi aquela que oferece equilíbrio entre os benefícios gerados por isolamento de dados e os riscos inerentes a compartilhamento de dados: Separated Schema.
Essa arquitetura parece mesmo bonitinha, mas como tiramos a idéia do papel?
Os principais componentes envolvidos no momento eram:
- A interface do aplicativo, uma grande aplicação JavaScript que implementa o conceito de Single-page application
- A api REST do aplicativo, escrita em Java
- O banco de dados PostgreSQL
- Uma api REST de busca fonética, também escrita em Java e que expõe os serviços de um índice Lucene
A implementação inicial da arquitetura SaaS foi feita durante uma sprint de uma semana. A grosso modo os trabalhos consistiram em:
- Criar um subdomínio por cliente e identificar qual cliente está por trás de cada requisição http
- Reservar um Schema por cliente
- Garantir que uma vez identificado o cliente, qualquer comunicação com o banco de dados envolvida na requisição seja dirigida ao Schema do cliente em questão
O PostgreSQL foi uma grata surpresa. Em um primeiro momento foi frustrante saber que não é possível escolher o schema na string de conexão do banco. Depois disso entendemos que o mecanismo de Search Path era a melhor resposta para nossas necessidades.
O Hibernate, outra peça-chave neste quebra-cabeças, se mostrou bastante amigável. Não tivemos a mesma sorte com o Hibernate Search que até então parece não oferecer suporte a multitenancy. Por isso os trabalhos com a api de busca fonética ficaram para a sprint seguinte.
Outra informação relevante é que hoje a infra-estrutura gira em torno dos serviços da Cloudbees, um fornecedor de PaaS especialista na plataforma Java.
Até então as partes envolvidas estão satisfeitas com a dependência sobre estes serviços.
Sinta-se convidado a tirar dúvidas e trocar experiência com a gente, os comentários estão aí para isto!
Este foi mais um post relatando a experiência de nossa parceria com a Lumera. Ainda existe bastante conteúdo por vir!
Rafa Noronha
Rafa Noronha gosta de construir aplicações web inovadoras em qualquer plataforma. Possui experiência em diversas tecnologias mas a única com quem rolou algo mais sério foi a Web. Nos últimos anos precisou se especializar em JavaScript, single-page apps e Backbone.js. Na Lambda3 Rafa Noronha jura que Java é legal e está sempre vencendo seus colegas nos confrontos de Mortal Kombat e FIFA14.