Escrevendo um blog de microsserviço - Parte 1 “Descrição geral”

Neste artigo, quero compartilhar nossa experiência com SergeyMaslov na solução de problemas típicos usando a arquitetura de microsserviços usando o exemplo da tarefa "criar um blog" (na esperança de que o leitor possa imaginar como o blog é organizado e isso não deve levantar questões sobre a funcionalidade :)

Portanto, nosso blog consistirá em 5 microsserviços escritos em golang:

  • API do gateway (api-gw) - responsável pelo roteamento, autenticação, registro e rastreamento de solicitações
  • Usuários (usuário) - registro / autenticação de usuários, registro, rastreamento de solicitações
  • Artigos (publicação) - crie / leia / modifique / exclua artigos (CRUD), registro, rastreamento e autorização de solicitações
  • Comentários - criar / ler / modificar / excluir comentários (CRUD), registro, rastreamento e autorização de solicitações
  • Categorias (categoria) - criação / leitura / alteração / exclusão de categorias (CRUD), registro, rastreamento e autorização de solicitações

O aplicativo cliente (web / front-end) será implementado no vue.js e interagirá com os microsserviços por meio da API REST, e os próprios microsserviços interagirão entre si por meio do gRPC.

Como armazenamento, usaremos o MongoDB.

Mostraremos com uma cereja no bolo como manter a documentação da API (no formato swagger) atualizada em um projeto em desenvolvimento ativo com o mínimo de trabalho.

Diagrama de componentes do blog


imagem

Cada microsserviço será implementado em um contêiner Docker separado e o projeto será iniciado usando o docker-compose.

Faça imediatamente uma reserva no exemplo, para simplificar o processo de desenvolvimento, usarei duas suposições que não devem ser usadas na produção.

  • O banco de dados é implantado em um contêiner de docker. Essa abordagem reduz a confiabilidade do armazenamento (com exceção do esquema discutido no HighLoad 2018).
  • Todo o projeto está hospedado em um repositório git. Essa abordagem contradiz um dos princípios básicos da arquitetura de microsserviços - isolamento e aumenta a probabilidade de conectividade entre componentes.

Você pode ver a demonstração do projeto aqui e o código fonte aqui .

Estrutura do projeto




Como o processo de desenvolvimento será construído


Como eu disse anteriormente, a interação entre microsserviços será baseada no gRPC. Em poucas palavras, o gRPC é uma estrutura de alto desempenho desenvolvida pelo Google para chamar procedimentos remotos (RPC) - funciona sobre o HTTP / 2. O GRPC é baseado no chamado protofile (veja o exemplo abaixo), cuja principal tarefa é declarar duas coisas de forma compacta:

  • forneça uma lista completa de interfaces de serviço (análogo de interfaces API);
  • descreva o que é alimentado na entrada de cada interface e o que obtemos na saída.

Abaixo, como exemplo, é fornecido o protofile do serviço Category.

syntax = "proto3"; package protobuf; import "google/api/annotations.proto"; //   Category service CategoryService { //  rpc Create (CreateCategoryRequest) returns (CreateCategoryResponse) { option (google.api.http) = { post: "/api/v1/category" }; } //  rpc Update (UpdateCategoryRequest) returns (UpdateCategoryResponse) { option (google.api.http) = { post: "/api/v1/category/{Slug}" }; } //  rpc Delete (DeleteCategoryRequest) returns (DeleteCategoryResponse) { option (google.api.http) = { delete: "/api/v1/category/{Slug}" }; } //   SLUG rpc Get (GetCategoryRequest) returns (GetCategoryResponse) { option (google.api.http) = { get: "/api/v1/category/{Slug}" }; } // rpc Find (FindCategoryRequest) returns (FindCategoryResponse) { option (google.api.http) = { get: "/api/v1/category" }; } } //------------------------------------------ // CREATE //------------------------------------------ message CreateCategoryRequest { string ParentId = 1; string Name = 2; string Path = 3; } message CreateCategoryResponse { Category Category = 1; } //------------------------------------------ // UPDATE //------------------------------------------ message UpdateCategoryRequest { string Slug = 1; string ParentId = 2; string Name = 4; string Path = 5; int32 Status = 6; } message UpdateCategoryResponse { int32 Status =1; } //------------------------------------------ // DELETE //------------------------------------------ message DeleteCategoryRequest { string Slug = 1; } message DeleteCategoryResponse { int32 Status =1; } //------------------------------------------ // GET //------------------------------------------ message GetCategoryRequest { string Slug = 1; } message GetCategoryResponse { Category Category = 1; } //------------------------------------------ // FIND //------------------------------------------ message FindCategoryRequest { string Slug = 1; } message FindCategoryResponse { repeated Category Categories = 1; } //------------------------------------------ // CATEGORY //------------------------------------------ message Category { string Slug = 1; string ParentId = 2; string Path = 3; string Name = 4; int32 Status = 5; } 

Agora que descobrimos em termos gerais por que um protofile é necessário, vamos ver como será o processo de desenvolvimento de nossos microsserviços:

  1. Nós descrevemos a estrutura do serviço no protofile;
  2. Se iniciarmos o gerador de código (./bin/protogen.sh), ele gerará a parte principal do código do servidor para nós + criará o código do cliente, por exemplo, para o API Gateway + criará documentação atualizada no formato swagger;
  3. Tudo o que temos a fazer com nossas próprias mãos é escrever o código para a implementação de interfaces em um arquivo especial /protobuf/functions.go.

Além disso, se quisermos fazer alterações em um de nossos microsserviços, procederemos de acordo com o algoritmo acima: editamos o protofile, executamos o protogen, editamos a implementação em functions.go, e as alterações “saem” automaticamente da documentação e dos clientes.

Continua no artigo "Escrevendo um blog sobre microsserviços, parte 2 da Gateway API" .

Source: https://habr.com/ru/post/pt473514/


All Articles