Além de todas as discussões recentes sobre o Kubernetes e se você deve ou não Dockerizar seu banco de dados, hoje eu gostaria de mostrar por que essas duas coisas podem ser boas soluções quando a escalabilidade e a elasticidade são um grande requisito em sua arquitetura.

O segredo aqui é simples: Spring Boot com Kubernetes para implantação do aplicativo e do banco de dados usando NoSQL.

 

Por que NoSQL e Spring Data?

Com os bancos de dados de documentos, é possível evitar muitas junções desnecessárias, pois toda a estrutura é armazenada em um único documento. Portanto, ele terá um desempenho naturalmente mais rápido do que um modelo relacional à medida que seus dados crescerem.

Se você estiver usando qualquer uma das linguagens JVM, o Spring Data e o Spring Boot podem ser algo bastante familiar para você. Assim, você pode começar rapidamente com o NoSQL mesmo sem nenhum conhecimento prévio.

 

Por que Kubernetes?

O Kubernetes (K8s) permite escalonar para cima e para baixo seu aplicativo sem estado em um ambiente independente de nuvem. Nas últimas versões, o K8s também adicionou a capacidade de executar aplicativos com estado, como bancos de dados, e esse é um dos (muitos) motivos pelos quais ele é um tema tão importante atualmente.

Eu mostrei em Minha postagem anterior no blog como implantar o Couchbase no K8s e como torná-lo "elástico", aumentando e diminuindo a escala facilmente. Se você ainda não o leu, dedique alguns minutos extras à transcrição do vídeo, pois ela é uma parte importante do que falaremos aqui.

 

Criação de um microsserviço de perfil de usuário

Na maioria dos sistemas, o usuário (e todas as entidades relacionadas) é o dado acessado com mais frequência. Consequentemente, essa é uma das primeiras partes do sistema que precisa passar por algum tipo de otimização à medida que os dados crescem.

Adicionar uma camada de cache é o primeiro tipo de otimização que podemos pensar. No entanto, ainda não é a "solução final". As coisas podem ficar um pouco mais complicadas se você tiver milhares de usuários ou se precisar armazenar entidades relacionadas ao usuário também na memória.

O gerenciamento de grandes quantidades de perfis de usuários é uma boa opção para bancos de dados de documentos. Basta dar uma olhada no Caso de uso do Pokémon Gopor exemplo. Portanto, a criação de um serviço de perfil de usuário altamente dimensionável e elástico parece ser um desafio suficientemente bom para demonstrar como projetar um microsserviço altamente dimensionável.

O que você vai precisar:

  • Couchbase
  • JDK e o plug-in do Lombok para Eclipse ou Intellij
  •  Maven
  • Um cluster do Kubernetes - estou executando este exemplo em 3 nós no AWS (não recomendo usar o minikube). Se você não sabe como configurar um, assista a este vídeo vídeo.

O Código

Você pode clonar o projeto inteiro aqui:

 

Vamos começar criando nossa entidade principal chamada Usuário:

 

Nessa entidade, temos duas propriedades importantes:

  • securityRoles: Todas as funções que o usuário pode desempenhar no sistema.
  • preferências: Todas as possíveis preferências que o usuário possa ter, como idioma, notificações, moeda etc.

Agora, vamos brincar um pouco com nosso Repositório. Como estamos usando o Spring Data, você pode usar praticamente todos os seus recursos aqui:

Se você quiser saber mais sobre o Couchbase e o Spring Data, Confira este tutorial.

Também implementamos dois outros métodos:

 

  • hasRole: Verifica se um usuário tem uma função especificada:
  • findUsersByPreferencyName: Como o nome diz, ele encontra todos os usuários que contêm uma determinada preferência.

Observe que estamos usando a sintaxe N1QL no código acima, pois ela torna as consultas muito mais simples do que o uso de JQL simples.

Além disso, você pode executar todos os testes para se certificar de que tudo está funcionando corretamente:

Não se esqueça de alterar seu application.properties com as credenciais corretas do seu banco de dados:

Para testar nosso microsserviço, adicionei alguns endpoints Restful:

 

Dockerizando seu microsserviço

Primeiro, altere seu application.properties para obter as credenciais de conexão das variáveis de ambiente:

E agora podemos criar nosso Dockerfile:

Em seguida, criamos e publicamos nossa imagem no Docker Hub:

  • Crie sua imagem:

 

  • Faça login no Docker Hub a partir da linha de comando

  •  Vamos pegar o imageId de nossa imagem criada recentemente:

  • Crie sua nova tag usando o imageId:

 

  • Por fim, impulsione sua imagem:

Sua imagem agora deve estar disponível no Docker Hub:

 

Configuração do banco de dados

Escrevi um artigo inteiro sobre isso aquimas para ser breve. Basta executar os seguintes comandos dentro do diretório do kubernetes.

Depois de algum tempo, todas as três instâncias do nosso banco de dados deverão estar em execução:

Vamos encaminhar a porta do Console da Web para nossa máquina local:

E agora podemos acessar o console da Web em http://localhost:8091. Você pode fazer login usando o nome de usuário Administrador e a senha senha

Ir para Segurança -> ADICIONAR USUÁRIO com as seguintes propriedades:

  • Nome de usuário: amostra de couchbase
  • Nome completo: amostra de couchbase
  • Senha: amostra de couchbase
  • Verificar senha: amostra de couchbase
  • Funções: De acordo com a imagem abaixo:

OBS: Em um ambiente de produção, não adicione seu aplicativo como administrador

 

Implantação de seu microsserviço

Primeiro, vamos criar um segredo do Kubernetes onde armazenaremos a senha para nos conectarmos ao nosso banco de dados:

Execute o seguinte comando para criar o segredo:

O arquivo spring-boot-app.yaml é o responsável pela implantação do nosso aplicativo. Vamos dar uma olhada em seu conteúdo:

Gostaria de destacar algumas partes importantes desse arquivo:

  • réplicas: 2 -> O Kubernetes iniciará duas instâncias do nosso aplicativo
  •  imagem: deniswsrosa/kubernetes-starter-kit -> A imagem do docker que criamos anteriormente.
  • contêineres: nome: -> Aqui é onde definimos o nome do contêiner que executa nosso aplicativo. Você usará esse nome no Kubernetes sempre que quiser definir quantas instâncias devem estar em execução, estratégias de escalonamento automático, balanceamento de carga etc.
  • env: -> É aqui que definimos as variáveis de ambiente do nosso aplicativo. Observe que também estamos nos referindo ao segredo que criamos anteriormente.

Execute o seguinte comando para implementar nosso aplicativo:

Em alguns segundos, você perceberá que as duas instâncias do seu aplicativo já estão em execução:

Por fim, vamos expor nosso microsserviço ao mundo externo. Há dezenas de possibilidades diferentes de como isso pode ser feito. No nosso caso, vamos simplesmente criar um balanceador de carga:

O seletor é uma das partes mais importantes do arquivo acima. É onde definimos os contêineres para os quais o tráfego será redirecionado. Nesse caso, estamos apenas apontando para o aplicativo que implantamos anteriormente.

Execute o seguinte comando para criar nosso balanceador de carga:

O balanceador de carga levará alguns minutos para ser ativado e redirecionar o tráfego para nossos pods. Você pode executar o seguinte comando para verificar seu status:

Como você pode ver na imagem acima, nosso balanceador de carga pode ser acessado em ad84a916d65ad11e884a20266aa53c9-1223617270.us-west-2.elb.amazonaws.com, e o targetPort 8080 redirecionará o tráfego para dois endpoints: 10.2.1.6:8080 e 10.2.2.7:8080

Por fim, podemos acessar nosso aplicativo e começar a enviar solicitações a ele:

  • Inserção de um novo usuário:
  • Busca de usuários:

 

E quanto a ser elástico?

É aqui que as coisas ficam realmente interessantes. E se precisarmos aumentar a escala de todo o nosso microsserviço? Digamos que a Black Friday esteja chegando e que precisemos preparar nossa infraestrutura para suportar esse fluxo maciço de usuários que chegam ao nosso site. Bem, esse é um problema fácil de resolver:

  •  Para escalonar nosso aplicativo, basta alterar o número de réplicas no spring-boot-app.yaml arquivo.

    Em seguida, execute o seguinte comando:

Está faltando alguma coisa? Sim. E quanto ao nosso banco de dados? Devemos ampliá-lo também:

  • Altere o atributo size no couchbase-cluster.yaml file:

 

Por fim, execute o seguinte comando:

 

Como posso reduzir a escala?

Reduzir a escala é tão fácil quanto aumentar a escala; você só precisa alterar ambos couchbase-cluster.yaml e spring-boot-app.yaml:

  • couchbase-cluster.yaml

  • spring-boot-app.yaml:

 

E execute os seguintes comandos:

 

Escalonamento automático de microsserviços no Kubernetes

Vou me aprofundar nesse tópico na parte 2 deste artigo. Enquanto isso, você pode conferir este vídeo sobre dimensionamento automático de pods.

Solução de problemas de sua implantação do Kubernetes

Se seus pods não conseguirem iniciar, há muitas maneiras de solucionar o problema. No caso abaixo, ambos os aplicativos não conseguiram iniciar:

Como eles fazem parte da implantação, vamos descrever a implantação para tentar entender o que está acontecendo:

Bem, nada é realmente relevante nesse caso. Então, vamos dar uma olhada em um dos registros do pod:

Entendi! O aplicativo não foi iniciado porque esquecemos de criar o usuário no Couchbase. Basta criar o usuário para que os pods sejam ativados em alguns segundos:

Conclusão

Os bancos de dados são aplicativos com estado, e dimensioná-los não é tão rápido quanto dimensionar aplicativos sem estado (e provavelmente nunca será), mas se você precisar criar uma arquitetura realmente elástica, deverá planejar o dimensionamento de todos os componentes da sua infraestrutura. Caso contrário, você estará apenas criando um gargalo em outro lugar.

Neste artigo, tentei mostrar apenas uma pequena introdução sobre como você pode tornar elásticos seu aplicativo e seu banco de dados no Kubernetes. No entanto, essa ainda não é uma arquitetura pronta para produção. Ainda há muitos outros aspectos a serem considerados, e abordarei alguns deles nos próximos artigos.

Enquanto isso, se você tiver alguma dúvida, envie-me um tweet para @deniswsrosa ou deixe um comentário abaixo.

 

Leia também:

Autor

Postado por Denis Rosa, defensor dos desenvolvedores, Couchbase

Denis Rosa é um Developer Advocate do Couchbase e mora em Munique, na Alemanha. Ele tem uma sólida experiência como engenheiro de software e fala fluentemente Java, Python, Scala e Javascript. Denis gosta de escrever sobre pesquisa, Big Data, IA, microsserviços e tudo o mais que possa ajudar os desenvolvedores a criar um aplicativo bonito, mais rápido, estável e escalável.

Deixar uma resposta