PHP Conference 2015: Construindo e mantendo aplicações multi-tenant (multi-cliente)

1.258 visualizações

Publicada em

O multi-tenancy é uma evolução natural para boa parte das aplicações. Startups e seus produtos precisam dele para seu modelo SaaS, empresas e seus sistemas o querem para o reuso de código. Essa palestra irá mostrar técnicas e modelos para a aplicação de multi-tenancy, e erros comuns no processo.

Publicada em: Tecnologia
  • Seja o primeiro a comentar

PHP Conference 2015: Construindo e mantendo aplicações multi-tenant (multi-cliente)

  1. 1. Construindo e mantendo aplicações multi-tenant (multi- cliente) Aryel Tupinambá PHP Conference 2015
  2. 2. Sobre o palestrante Co-fundador e CTO da LQDI Digital Projetos para empresas como Porto Seguro, Nestlé, Garoto, Editora FTD, Tishman Speyer e Ambev 12 anos trabalhando com PHP Desde a época que o PHPClasses era a onda :) Aryel Tupinambá
  3. 3. Single tenant - Um único "cliente" para a aplicação - Forma tradicional, instalada no servidor do cliente - Faz sentido quando a aplicação é um PROJETO
  4. 4. Agora com mais um cliente… e mais outro... - Seu PROJETO se tornou um PRODUTO - Diversos clientes usando a mesma aplicação - Estruturas separadas para cada novo cliente - Nada é compartilhado; tudo é isolado
  5. 5. E agora, como faço... … atualizações de segurança? … correção de bugs? … features novas para todo mundo? E o espaço que toda essa galera ocupa? E o custo que tudo isso gera?
  6. 6. Arquitetura multi-tenant - Tenant = inquilino - Uma única aplicação para vários clientes - Uma estrutura comum entre os clientes - As benfeitorias servem para todos - A customização de um cliente não interfere nos demais, nem previne que ele utilize da estrutura comum
  7. 7. Principais desafios DATA STORAGE CODEBASE CUSTOMIZAÇÃO Como segmentar a base de dados para cada cliente? Como segmentar os arquivos enviados? Como fica o código fonte da aplicação? Como ficam as customizações? Como lidamos com updates e novas features? Como podemos customizar as funcionalidades da aplicação? Como permitir que atualizações e novas features não sejam impedidas por customizações?
  8. 8. Não existe escolha certa ou errada O que existe são escolhas que fazem mais sentido para determinados cenários.
  9. 9. Data storage
  10. 10. Três formatos mais comuns Data storage Instâncias separadas Bancos de dados separadas Banco de dados compartilhado Cada cliente possui uma instância do seu SGDB (MySQL, Postgres, Mongo, etc), com seus dados isolados. Mais isolado Mais compartilhado Cada cliente tem um banco de dados (ou schema) diferente, na mesma instância Todos os clientes estão na mesma base de dados; o cliente é identificado por meio de uma coluna nas tabelas (tenantID) Referência / diagramas: Microsoft - https://msdn.microsoft.com/en-us/library/aa479086.aspx
  11. 11. Três formatos mais comuns Data storage Instâncias separadas Bancos de dados separadas Banco de dados compartilhado Mais isolado Mais compartilhado Todos os clientes estão na mesma base de dados; o cliente é identificado por meio de uma coluna nas tabelas (tenantID) Referência / diagramas: Microsoft - https://msdn.microsoft.com/en-us/library/aa479086.aspx
  12. 12. Três formatos mais comuns Data storage Instâncias separadas Bancos de dados separadas Banco de dados compartilhado Mais isolado Mais compartilhado Cada cliente tem um banco de dados (ou schema) diferente, na mesma instância Referência / diagramas: Microsoft - https://msdn.microsoft.com/en-us/library/aa479086.aspx
  13. 13. Três formatos mais comuns Data storage Instâncias separadas Bancos de dados separadas Banco de dados compartilhado Mais isolado Mais compartilhado Cada cliente possui uma instância do seu SGDB (MySQL, Postgres, Mongo, etc), com seus dados isolados. Referência / diagramas: Microsoft - https://msdn.microsoft.com/en-us/library/aa479086.aspx
  14. 14. Referência / diagramas: Microsoft - https://msdn.microsoft.com/en-us/library/aa479086.aspx
  15. 15. Referência / diagramas: Microsoft - https://msdn.microsoft.com/en-us/library/aa479086.aspx
  16. 16. Três formatos mais comuns Data storage Instâncias separadas Bancos de dados separadas Banco de dados compartilhado Sugestão de uso: - Aplicações com pouca ou nenhuma variabilidade / customização - Aplicações em que a principal customização é visual - Aplicações com alto número de usuários (500k+) Mais isolado Mais compartilhado
  17. 17. Três formatos mais comuns Data storage Instâncias separadas Bancos de dados separadas Banco de dados compartilhado Sugestão de uso: - Aplicações em que deve haver maior flexibilidade para customização - Aplicações em que a infra-estrutura sempre será responsabilidade sua - Planos baseados em volume de consumo ou performance Mais isolado Mais compartilhado
  18. 18. Três formatos mais comuns Data storage Instâncias separadas Bancos de dados separadas Banco de dados compartilhado Sugestão de uso: - Projetos em que a separação física do hardware se faz necessária (instalações on-premises, compliance corporativo ou governamental, decisões de performance); - Alta disparidade no volume de dados ou de acessos entre clientes (quando alguns clientes consomem demais) - Quando você precisa monitorar o consumo individual de hardware para cada cliente (e seu SGDB não faz isso por database/schema) Mais isolado Mais compartilhado
  19. 19. - Em regra geral, a FLEXIBILIDADE necessária deve ser o fator decisório - Customizar funcionalidades pode ser um desafio quando você tem um modelo de dados fixo; alterar o modelo de dados de toda uma aplicação só para atender um cliente / uma feature pode gerar inconsistência e dificultar a manutenção - Use o pattern de "migrations" e "seeds" para criar e manter o database schema; muito importante criar migrations que sejam, na medida do possível, 100% reversíveis. - Você não necessariamente precisa escolhar um único modelo para todos os dados da aplicação; se sua aplicação tem interações entre os clientes mas é altamente customizável, por exemplo, faz sentido segmentar o que faz parte do core em um único database, e o que faz parte da customização em um database separado Data storage
  20. 20. Relembrando: não existe escolha certa ou errada
  21. 21. Data storage: na prática
  22. 22. Data storage: na prática Modelo compartilhado (via tenant ID)
  23. 23. Data storage: na prática Modelo isolado (instâncias diferentes)
  24. 24. Codebase
  25. 25. Codebase - Dois cenários: uma instância para todos, ou uma instância por tenant app código fonte cliente1.app.com cliente2.app.com cliente3.app.com config 1 config 2 config 3 cliente1.app.com código fonte config 1 cliente2.app.com código fonte config 2 cliente3.app.com código fonte config 3 custom code Uma instância para todos Uma instância por cliente
  26. 26. Codebase - Uma instância para todos - Atualizações são sincronizadas sem custo ou esforço - Nenhum ou pouquíssimo "housekeeping" necessário - Não é muito flexível para customizações - Mais fácil de escalar quando o padrão de consumo de todos os clientes é semelhante app código fonte cliente1.app.com cliente2.app.com bigcorp.app.com config 1 config 2 config 3
  27. 27. Codebase - Uma instância para todos - Atualizações são sincronizadas sem custo ou esforço - Nenhum ou pouquíssimo "housekeeping" necessário - Não é muito flexível para customizações - Mais fácil de escalar quando o padrão de consumo de todos os clientes é semelhante app código fonte cliente1.app.com cliente2.app.com bigcorp.app.com config 1 config 2 config 3 Nginx sitesvia DB, cachedGit repository
  28. 28. Codebase - Uma instância por cliente - Atualizações não são sincronizadas, exceto se automatizadas - Necessário um trabalho de "housekeeping" para manutenção das instâncias - Bastante flexível para customizações - Qualquer cliente pode ter sua versão da aplicação "congelada" - O código do próprio "core" da aplicação pode ser forkado e alterado a qualquer momento (se em algum momento isso fizer sentido para o negócio) bigcorp.app.com código fonte config 1 cliente1.app.com código fonte config 2 cliente2.app.com código fonte config 3 custom code
  29. 29. Codebase - Uma instância por cliente - Atualizações não são sincronizadas, exceto se automatizadas - Necessário um trabalho de "housekeeping" para manutenção das instâncias - Bastante flexível para customizações - Qualquer cliente pode ter sua versão da aplicação "congelada" - O código do próprio "core" da aplicação pode ser forkado e alterado a qualquer momento (se em algum momento isso fizer sentido para o negócio) bigcorp.app.com código fonte config 1 cliente1.app.com código fonte config 2 cliente2.app.com código fonte config 3 Git repo .env files custom code
  30. 30. Codebase - Uma instância por cliente - Atualizações não são sincronizadas, exceto se automatizadas - Necessário um trabalho de "housekeeping" para manutenção das instâncias - Bastante flexível para customizações - Qualquer cliente pode ter sua versão da aplicação "congelada" - O código do próprio "core" da aplicação pode ser forkado e alterado a qualquer momento (se em algum momento isso fizer sentido para o negócio) bigcorp.app.com código fonte config 1 cliente1.app.com código fonte config 2 cliente2.app.com código fonte config 3 Nginx sites + PHP-FPM pools v1.4.0 v1.4.1 v1.4.0 custom code
  31. 31. Codebase - De novo, o maior fator decisório aqui deve ser a FLEXIBILIDADE: o quanto você espera que o código da aplicação se altere com customizações de clientes? - A escalabilidade, embora seja um desafio (e mereceria uma palestra a parte), não deve ser dificultada em nenhum dos cenários, DESDE QUE você automatize todos os processos e fique de olho na consistência - Instâncias isoladas permitem que você escale clientes mais "barulhentos" (alto volume) para hardware melhor - Você pode também trabalhar com instâncias segmentadas por tier ou plano, e "empacotar" menos clientes por instâncua em tiers mais elevados/caros.
  32. 32. Variabilidade e customização
  33. 33. Variabilidade e customização - O calcanhar de aquiles da arquitetura multi-tenant - Requer bastante meditação sobre os requisitos - Aqui é um dos melhores lugares onde design patterns e uma arquitetura sã e consistente brilham de verdade - Vou falar sobre algumas técnicas e formatos interessantes
  34. 34. Relembrando: não existe escolha certa ou errada
  35. 35. Variabilidade e customização - Para configuração: - Para instâncias de código isoladas: um arquivo de configuração (biblioteca DotEnv) - Para instâncias unificadas: parâmetros de configuração no banco/repositório de tenant data .env
  36. 36. Variabilidade e customização - Para o data storage: - Migrations: funcionam como um controle de versão do seu modelo de dados - A maioria dos frameworks/ORMs possuem suporte built-in (Laravel, CakePHP, Doctrine), e há libs standalone para outros formatos. - Sempre criar migrations "reversíveis", ou seja, que possam sofrer rollback
  37. 37. Variabilidade e customização - Para o código / funcionalidade: EVENTS Transação de negócio (ex: novo pedido realizado) Gerenciador de eventos (via Framework, biblioteca ou hand-made) Envio de e- mail para o usuário Registro no log de atividade do usuário Sub-serviços do core app Módulo customizado: NF-E Geração de NF-E Módulo customizado: Tracking Registrar nova carga à entregar dispatchEvent('order_created', $order);
  38. 38. - Para o código / funcionalidade: EVENTS Variabilidade e customização Transação de negócio (ex: novo pedido realizado) Gerenciador de eventos (via Framework, biblioteca ou hand-made) Envio de e- mail para o usuário Registro no log de atividade do usuário Sub-serviços do core app Módulo customizado: NF-E Geração de NF-E Módulo customizado: Tracking Registrar nova carga à entregar dispatchEvent($order); CORE APP CUSTOM CODE
  39. 39. return [ ['Entregas','abc.delivery.index'], ['Configurar Frete','abc.delivery.config'] ]; - Para o código / funcionalidade: HOOKS Variabilidade e customização Renderizar menu principal Gerenciador de hookstriggerHook('render_menu'); return [['Pedidos','core.orders.index']]; return [['Estoque','core.inventory.index']]; Módulo de Pedidos Módulo de Estoque Módulos do core app Módulo de Entregas Custom code do cliente ABC return [...];
  40. 40. Variabilidade e customização - Para o código / funcionalidade: DEPENDENCY INJECTION Order BillingGatewayContract PayPalBillingGateway implementa DI Container registra recebe PayPalBillingGateway pede BillingGatewayContract
  41. 41. Variabilidade e customização - Para o código / funcionalidade: DEPENDENCY INJECTION Order BillingGatewayContract PayPalBillingGateway Core app Order BillingGatewayContract PayPalBillingGateway Core app Order BillingGatewayContract PayPalBillingGateway Core app TENANT 1 TENANT 2 TENANT 3
  42. 42. PagSeguroBillingGateway Variabilidade e customização - Para o código / funcionalidade: DEPENDENCY INJECTION Order BillingGatewayContract PayPalBillingGateway Core app Order BillingGatewayContract PayPalBillingGateway Core app Order BillingGatewayContract PayPalBillingGateway Core app TENANT 1 TENANT 2 TENANT 3 Custom code
  43. 43. Variabilidade e customização - Para o frontend / interface: - Dê preferência para usar uma engine de templates (Blade, Twig, etc);
  44. 44. Variabilidade e customização - Para o frontend / interface: - Use Sass ou outro pré-compilador de CSS - Você pode gerar o config via PHP, e então rodar o compilador (automático ou manual)
  45. 45. Variabilidade e customização - Para infraestrutura / deploy:
  46. 46. Variabilidade e customização - Para infraestrutura / deploy:
  47. 47. Variabilidade e customização - Para infraestrutura / deploy: http://forge.laravel.com http://deployhq.com http://envoyer.io Use ferramentas ou serviços de automatização de deploy (imagine atualizar manualmente a versão de 600 clientes)
  48. 48. Variabilidade e customização - Para infraestrutura / deploy: Use o Composer para gerenciar core app e código customizável
  49. 49. Variabilidade e customização - Para infraestrutura / deploy: Automatize (se aplicável) o processo de provisionamento para novos clientes Novo cliente cadastrado Script / microservice de PROVISIONAMENTO Criar pasta no servidor e site no Nginx Criar banco de dados Gerar .env de configuração Criar registro no DB de tenants Cadastrar no Envoyer e realizar primeiro deploy Gerar composer.json com Core + Custom code Disparar e-mail para o cliente Gerar config do Sass e compilar CSS final
  50. 50. Variabilidade e customização - Para infraestrutura / deploy: Automatize (se aplicável) o processo de provisionamento para novos clientes Novo cliente cadastrado Script / microservice de PROVISIONAMENTO Criar pasta no servidor e site no Nginx Criar banco de dados Gerar .env de configuração Criar registro no DB de tenants Cadastrar no Envoyer e realizar primeiro deploy Gerar composer.json com Core + Custom code Disparar e-mail para o cliente Gerar config do Sass e compilar CSS final
  51. 51. Variabilidade e customização - Para infraestrutura / deploy: - O custo e tempo para provisionamento interfere diretamente em um KPI de negócio, o CAC (Custo de Aquisição de Cliente) - Provavelmente toda sua infra-estrutura pode ser administrada via API; use isso a seu favor - Amazon EC2 e DigitalOcean tem APIs para provisionamento de servidores - Amazon S3 e Rackspace Cloud tem APIs para criação de novos "buckets" de arquivos - Amazon Route 51 e DigitalOcean tem APIs para gerenciar o DNS (domínios customizáveis)
  52. 52. TL;DR - Oriente sua arquitetura principalmente pela sua necessidade de flexibilidade e customização - Mais customizável -> mais isolada - Mais uniforme -> mais compartilhada - Use as melhores práticas de SOLID, principalmente no que diz respeito a Inversão de Dependência; a arquitetura multitenant é provavelmente o melhor use- case de substituição de implementações de uma interface em runtime
  53. 53. TL;DR - Automatize TUDO que diz respeito a provisionamento, deploy e housekeeping de infraestrutura: manutenção manual de instâncias é uma eterna dívida técnica que se acumula - TDD é PRIMORDIAL; lembre-se que em um ambiente sincronizado, uma atualização impacta TODOS os seus clientes
  54. 54. Perguntas?
  55. 55. A está contratando! Procuramos desenvolvedores front-end e back-end, de TODOS os níveis de experiência, apaixonados pelo que fazem e a fim de aprender e ensinar Ambiente de trabalho bacana, descontraído, com remuneração competitiva, horários flexíveis e bastante abertura para novas idéias. Sem melindres, sem preciosismo e puxação de saco :D Plano de carreira sólido e flexível, com espaço para crescimento em gestão e especialização, e programas de feedback contínuo entre a equipe e os gestores. Manda um e-mail pra work@lqdi.net e cite a palestra da PHP Conference Ou me chame pessoalmente agora para trocarmos uma idéia Começe 2016 de trampo novo!
  56. 56. Obrigado! E-mail / Hangouts: aryel.tupinamba@lqdi.net Facebook: http://facebook.com/aryel.tupinamba Twitter: http://twitter.com/DfKimera LinkedIn: http://linkedin.com/in/aryeltupinamba Slides da palestra: http://slideshare.net/aryeltupinamba http://lqdi.net

×