Como construir um SaaS Multi-tenant

Empreendedorismo

Como construir um SaaS Multi-tenant

Luiz Duarte
Escrito por Luiz Duarte em 04/10/2021
Junte-se a mais de 22 mil profissionais de TI

Entre para minha lista e receba conteúdos exclusivos e com prioridade

Se você não faz a mínima ideia do que é um SaaS ou quer reforçar, recomendo assistir ao vídeo abaixo antes de avançar.

Na era de ouro dos programas desktop, pré-internet comercial, todos que tinham a ideia de construir uma ferramenta como um EPR, um CRM ou qualquer que fosse tinham de recorrer a tecnologias desktop como Delphi e Visual Basic. E embora o desenvolvimento com estas ferramentas, apelidadas de RAD à época (Rapid Application Development) fosse muito prático e rápido, o deploy e a posterior manutenção/atualização não o eram, exigindo muitas vezes a presença física de um técnico no local como computador ou complicadas instruções por telefone para algum usuário executar do outro lado da linha.

Com o avanço da Internet nos anos 90 e a popularização dos servidores e datacenters, houve uma migração expressiva de aplicações desktop para a web, uma vez que apesar do desenvolvimento não ser tão prático, bastava o cliente ter uma conexão com a Internet e voilá, acessava o sistema 100% atualizado e operacional. Novas instalações e updates eram entregues de maneira mais simples uma vez que o servidor ficava de controle do desenvolvedor ou empresa dona do software, podendo fazê-lo via FTP. Assim, se popularizou um formato de cobrança por aluguel, como se o software fosse um serviço e não um produto, daí vindo o nome SaaS (Software as a Service).

No entanto, o advento dos primeiros SaaS tinham dois problemas cruciais que precisavam ser resolvidos: o primeiro deles era o alto custo para comprar e hospedar servidores em datacenters. O segundo era que ter muitos clientes usando seu SaaS significava muita dor de cabeça pois isso exigiria setups complexos, mais servidores contratados e mesmo que a atualização não exigisse presença física, ainda dependia de ser feita servidor a servidor e muitas vezes existiam variações entre os clientes que tinham de ser cuidadas.

O primeiro problema, de custo, solucionou-se com a evolução da virtualização de hardware, a popularização da banda larga (2001-2002) e a união dos dois que gerou a Computação em Nuvem (Cloud Computing) ali por 2006-2007. A computação em nuvem permitiu que você locasse servidores como se fossem um serviço, o chamado IaaS (Infrastructure as a Service, onde a AWS reina hoje). Não demorou para que plataformas surgissem criando mais uma camada de abstração em cima da computação em nuvem, criando os primeiros PaaS (Platform as a Service) como a Heroku, uma das pioneiras no setor. Assim, você podia começar o seu SaaS com apenas um servidor virtualizado (VPS) pequeno e poucos clientes e ia pagando mais, conforme seu negócio crescia.

Mas e seu segundo problema?

Agora tínhamos um preço justo e a escala de hardware, estava na hora do software evoluir da mesma forma e aí as arquiteturas multi-tenant ou multi-inquilino explodiram. Hoje SaaS e multi-tenant são praticamente sinônimos mas isso nem sempre foi assim e até hoje muitas empresas sofrem para migrar suas soluções do desktop para a web e da web 1.0 para a 2.0.

Neste artigo eu vou explorar algumas abordagens de multi-tenancy, explicar a diferença entre multi-tenant e multi-usuário e contar alguns cases pelos quais passei na minha carreira.

O conteúdo deste artigo pode ser assistido no vídeo abaixo, se preferir.

O que é multi-tenant?

Multi-tenancy é a capacidade de um software de ter vários inquilinos, ou seja, vários clientes pagando pelo uso de um mesmo software, mas sem que um interaja ou interfira no uso do outro, como em um prédio de apartamentos para alugar. Cada inquilino, ou tenant, traz os seus dados e realiza as suas operações no software, assim como um inquilino real traria sua mobília, família e levaria a sua vida privada no apartamento.

Um ponto importante é não confundir multi-tenancy como multi-usuário.

Para que um sistema seja multi-usuário basta que você permita que várias pessoas tenham credenciais de acesso ao sistema e aqui eu trago como exemplo um software de gestão que desenvolvi em 2012 para uma rede de escolas de Inglês da minha região. O software é multi-usuário: alunos, professores e administradores usam-no diariamente para as atividades da escola, cada um com suas responsabilidades e acessos, mas existe apenas um tenant do sistema inteiro: a rede de escolas, ou seja, é um software single-tenant o que é até fácil de perceber uma vez que eu tenho apenas um cliente.

Se eu quiser vender o software para outra rede de escolas de Inglês eu consigo? Até consigo, mas fazendo toda uma nova instalação do software e até mesmo tendo de customizar manualmente a identidade visual, nomes, etc. Principalmente falando de banco de dados, se eu deixasse outro cliente usar a instância atual da aplicação, os dados de ambos ficariam misturados e isso claramente seria um problema.

Isso não é multi-tenancy, é multi-usuário.

Outro exemplo é do Beholder TraderBot, projeto central do meu curso homônimo. Nele, o aluno cria um bot trader de criptomoedas e uma das coisas mais importantes que este bot tem são os dados da conta do aluno na exchange Binance. Com os dados da carteira mais os dados do mercado são criadas estratégias de compra a venda automatizada de criptomoedas, mas a arquitetura da aplicação permite apenas uma carteira. Mesmo que você cadastre vários usuários no Beholder, todos irão operar em cima da mesma carteira.

Mas o que seria um exemplo de software multi-tenant então?

Em 2015 eu trabalhei em um software de automação de marketing chamado Route. Nele, cada cliente cadastrava os seus leads, criava suas campanhas de email, automações, tinha seus relatórios e métricas e até mesmo seus próprios usuários. Para todos os efeitos, o software aparentava ser do próprio cliente, completamente isolado dos demais e ele pagava pelo uso do mesmo, aliás muito mais barato do que se ele comprasse uma licença de software de marketing para si próprio.

O mesmo vale para a Expansão Hydra do Beholder, que justamente modifica a arquitetura para permitir múltiplas carteira sendo negociadas paralelamente, mas de maneira isolada uma da outra.

Isso é multi-tenancy!

Uma coisa que você pode perceber é que todo software multi-tenant é multi-usuário, mas que o contrário não necessariamente é verdade. Aqui entra um ponto importante: multi-tenancy não é apenas uma arquitetura, mas um conceito arquitetural que pode ser implementado com diferentes abordagens.

Livro Node.js

Arquiteturas para Multi-Tenancy

Existem duas categorias principais de arquiteturas multi-tenant e infinitas possibilidades de implementação. As duas categorias são multi-tenancy físico e multi-tenancy lógico. E claro pode-se combinar elas em uma abordagem híbrida.

Vou começar explicando o mais simples deles, o multi-tenancy lógico.

Nesta abordagem arquitetural, não há separação física entre os tenants, mas apenas lógica, ou seja, o seu software é que vai decidir quais dados exibir/alterar para quais clientes, mas eles estão todos armazenados no mesmo banco de dados.

A lógica mais comum aqui é baseada no que chamamos de “tenant id”, ou seja, existe um identificador único em cada tenant, geralmente o id da tabela de tenants. Esse tenant id é usado como chave estrangeira em todas as demais tabelas, para referenciar os registros que pertencem aquele tenant.

Por exemplo, em um SaaS de email marketing, cada tenant tem os seus contatos. Logo, apesar de existir apenas uma tabela contacts, sabemos quais contacts são da account A pois ele vai ter o tenant id da account A, enquanto que os contacts da account B vão ter o tenant id da account B. Isso quer dizer, inclusive, que pode ser que existam contacts em comum entre A e B, mas que os dados NÃO PODEM ser compartilhados, para todos efeitos são tratados como registros diferentes no banco de dados.

É assim que funciona por exemplo no MailShrimp, o software de email marketing que é o projeto central do meu curso Web FullStack JS. No MailShrimp, cada tenant tem a sua conta com os seus contatos, os seus emails e as suas configurações de envio. Assim, eu tenho uma tabela de accounts (tabela de tenants) e o accountId é usado nas tabelas de contacts e messages para sabermos quais contatos e quais mensagens, respectivamente, pertencem a cada account.

Claro que outras tabelas referenciadas a contacts e messages não necessariamente precisam ter o accountId de novo, como por exemplo estatísticas de uma mensagem específica ou endereços de um cliente, pois como elas já estão ligadas por uma chave estrangeira a uma tabela segregada pelo tenant id, tudo já fica logicamente separado.

A vantagem deste modelo é a simplicidade de execução. Como deve ter percebido, basta um campo a mais nas tabelas e sempre usar filtros nas consultas pelo tenant id e pronto, arquitetura construída, falando de maneira simplista.

A desvantagem deste modelo é o risco de segurança e, depois de um tempo, a escala. O problema de segurança geralmente é mitigado com uma boa bateria de testes mais as boas práticas de qualquer sistema web. Já o problema de escala, geralmente se resolve migrando para o modelo de multi-tenancy físico.

Curso Node.js e MongoDB

Multi-Tenancy Físico

Multi-tenancy lógico é o modelo mais utilizado principalmente porque é o melhor para começar. Muitas startups ficam anos operando com ele até ter a real necessidade de partir para o modelo físico, principalmente os negócios B2B que são caracterizados por menos clientes mas com ticket maior. E isso é bom, o ideal é começar pelo lógico mesmo que, se bem construído, vai te permitir mais tarde ir para o físico.

No multi-tenancy físico cada tenant está separado fisicamente um do outro, ou seja, em bancos de dados diferentes ou até mesmo servidores diferentes muitas vezes. Dentro do seu banco, cada tenant é rei e ele pode ou não precisar ter tenant id em suas tabelas, conforme a sua estratégia.

Para saber em qual tenant está cada usuário do sistema, geralmente cria-se uma tabela de tenant catalog, indicando de qual tenant é cada usuário. Assim, toda primeira request é feita para este catálogo e com base na informação recebida, as requests subsequentes são feitas diretamente para o banco de dados do tenant.

Do ponto de vista de experiência do usuário tem de se tomar cuidados para que isso seja o mais transparente possível. Quando o SaaS é com marca própria, uma tela de login única e uma tabela de catálogo já resolvem. Agora quando o SaaS é white-label, uma técnica comum é ter subdomínios ou paths personalizados, como cliente1.meusaas.com.br ou meusaas.com.br/cliente1. Assim a própria aplicação consegue saber de qual tenant estamos falando só de olhar a origem da requisição.

Como vantagens deste modelo temos segurança e escala, pois as chances de um cliente invadir o playground do outro ou mesmo afetar outros por causa de excesso de uso, é praticamente nula se bem executada. Já a desvantagem é que este é um modelo mais caro de manter e mais complicado de implementar, sendo que eu o recomendo somente quando a escala se torna uma necessidade.

Em 2020 eu trabalhei em uma empresa de POSTEF, que basicamente é a retaguarda financeira das maquininhas de cartão (POS ou Point of Sale). Vendíamos muito para postos de gasolina e em cada posto o cliente podia ter quantas bombas de combustível, quantos caixas na loja de conveniência e até mesmo quantas maquininhas quisesse na pista, tudo conversando com os dados da sua filial ou até mesmo da sua rede.

Alguns grandes clientes, como a rede de postos Ipiranga (a maior do Brasil), tinham servidores dedicados para eles conosco, ou seja, tenants fisicamente isolados, enquanto que outros clientes menores estavam em tenants isolados “apenas” logicamente.

Ok, isso já é um pouco híbrido, mas se olhar apenas pra ótica dos postos grandes, acho que dá pra entender. 🙂

Curso FullStack

Modelo Híbrido

E por fim, existem os modelos híbridos, onde ora separa-se fisicamente ora logicamente. Este é o modelo mais comum nas empresas de SaaS que começaram com o modelo de separação lógica e depois migraram para a separação física e ele começa mais ou menos assim: tudo começa com um único servidor e vários tenants separados logicamente por tenant id.

Em dado momento, este servidor tem tantos clientes que torna-se um problema de escala que não se consegue mais resolver apenas colocando mais recursos na máquina ou reescrevendo partes do código. Aí cria-se um segundo servidor com a mesma aplicação e a liberação de novos clientes passa a acontecer nele.

Para conseguir saber qual tenant está em qual servidor, cria-se uma tabela de catálogo que funciona como um índice ou, no caso de SaaS white-label, usa-se um subdomínio ou identificação parecida.

Em outra empresa que trabalhei em 2007, tínhamos um PaaS, mas que funcionava de maneira híbrida a questão dos tenants. Quando a empresa começou, bem pequena, era apenas um servidor com uma aplicação e todos clientes dentro, separados logicamente. Mais tarde, descobrimos que nossa capacidade máxima era de 5 mil clientes por servidor e tivemos que começar a escalar fisicamente, colocando mais servidores e usando tabela de catálogo para entender onde estava cada um.

E voltando ao exemplo da empresa de POSTEF que mencionei, nela o limite era de 500 clientes por servidor quando eram pequenos varejistas ou 200 quando eram de porte médio ou contratos mais premium. Já os grandes eram completamente separados mesmo, como no caso da rede Ipiranga.

Repare que em nenhum momento aqui eu falei de tecnologias específicas, uma vez que arquitetura de software é algo que deve ser discutida sempre uma camada acima das ferramentas a serem utilizadas. Tive a oportunidade de trabalhar nestes e em outros projetos não citados com tecnologias como ASP.NET, Java, C/C++ e Node.js. Um artigo que aborda mais detalhes técnicos da construção de SaaS é este aqui, sobre 12-Factor Apps.

Além disso, não espero esgotar este assunto, mesmo em um artigo tão longo. Mas, ao invés disso, espero ter lhe mostrado algumas possibilidades e despertado seu interesse por saber mais a respeito.

Um abraço e sucesso.

TAGS: web

Olá, tudo bem?

O que você achou deste conteúdo? Conte nos comentários.