Introdução à arquitetura de microsserviços
Parte 1 de 10
Adaptação de artigos de Ewan Valentine.
Esta é uma série de dez partes, tentarei escrever sobre a construção de microsserviços no Golang uma vez por mês. Vou usar protobuf e gRPC como o principal protocolo de transporte.
A pilha que usei: golang, mongodb, grpc, docker, Google Cloud, Kubernetes, NATS, CircleCI, Terraform e go-micro.
Por que eu preciso disso? Já que demorei muito tempo para descobrir e resolver os problemas acumulados. Eu também queria compartilhar com você o que aprendi sobre a criação, teste e implantação de microsserviços no Go e outras novas tecnologias.
Nesta parte, quero mostrar os conceitos e tecnologias básicos para a construção de microsserviços. Vamos escrever uma implementação simples. O projeto terá as seguintes entidades:
- carga
- inventário
- julgamento
- os usuários
- os papéis
- autenticação

Para ir além, você precisa instalar o Golang e as bibliotecas necessárias, além de criar um repositório git.
Teoria
O que é arquitetura de microsserviço?
Os microsserviços isolam uma funcionalidade separada em um serviço, auto-suficiente em termos da função desempenhada por esse serviço. Para compatibilidade com outros serviços, ele possui uma interface bem conhecida e predefinida.
Os microsserviços se comunicam usando mensagens transmitidas por algum intermediário, intermediário de mensagens.

Graças à arquitetura do microsserviço, o aplicativo não pode ser escalado por inteiro, mas por partes. Por exemplo, se o serviço de autorização "se contrair" com mais frequência do que outros, podemos aumentar o número de instâncias. Esse conceito está alinhado com os conceitos de computação em nuvem e contêiner em geral.
Por que golang
Os microsserviços são suportados em quase todos os idiomas; afinal, microsserviços são um conceito, não uma estrutura ou ferramenta específica. No entanto, alguns idiomas são mais adequados e, além disso, têm melhor suporte para microsserviços do que outros. Um idioma com grande apoio é o Golang.
Conheça protobuf / gRPC
Como mencionado anteriormente, os microsserviços são divididos em bases de código separadas, um dos problemas importantes associados aos microsserviços é a comunicação. Se você possui um monólito, basta chamar o código diretamente de outro local do seu programa.
Para resolver o problema de comunicação, podemos usar a abordagem REST tradicional e transferir dados no formato JSON ou XML via HTTP. Mas essa abordagem tem suas desvantagens, por exemplo, que antes de enviar uma mensagem, você precisa codificar seus dados e decodificá-los de volta no lado receptor. E isso é sobrecarga e aumenta a complexidade do código.
Existe uma solução! Este é o protocolo gRPC - um protocolo leve e baseado em binário que elimina a transmissão de cabeçalhos HTTP, e isso nos poupará alguns bytes. O futuro HTTP2 também implica o uso de dados binários, que novamente falam a favor do gRPC. HTTP2 permite comunicação bidirecional, e é incrível!
O GRPC também permite que você defina a interface para o seu serviço em um formato amigável - isto é> protobuf .
Prática
Crie o arquivo /project/consigment.proto.
Documentação oficial do protobuf
consigment.proto//consigment.proto syntax = "proto3"; package go.micro.srv.consignment; service ShippingService { rpc CreateConsignment(Consignment) returns (Response) {} } message Consignment { string id = 1; string description = 2; int32 weight = 3; repeated Container containers = 4; string vessel_id = 5; } message Container { string id = 1; string customer_id = 2; string origin = 3; string user_id = 4; } message Response { bool created = 1; Consignment consignment = 2; }
Este é um exemplo simples que contém o serviço que você deseja fornecer a outros serviços: service ShippingService, então definiremos nossas mensagens. Protobuf é um protocolo estaticamente tipado, e podemos criar tipos personalizados (semelhantes às estruturas em golang). Aqui o contêiner está aninhado no lote.
Instale as bibliotecas, o compilador e compile nosso protocolo:
$ go get -u google.golang.org/grpc $ go get -u github.com/golang/protobuf/protoc-gen-go $ sudo apt install protobuf-compiler $ mkdir consignment && cd consignment $ protoc -I=. --go_out=plugins=grpc:. consignment.proto
A saída deve ser um arquivo:
consignment.pb.go
Se, então algo deu errado. Preste atenção aos argumentos -I é o caminho em que o compilador está procurando arquivos, --go_out, onde um novo arquivo será criado. Sempre há ajuda
$ protoc -h
Este é o código gerado automaticamente pelas bibliotecas gRPC / protobuf para que você possa associar sua definição de protobuf ao seu próprio código.
Vamos escrever main.go
main.go package seaport import ( "log" "net"
Leia com atenção os comentários deixados no código. Aparentemente, aqui estamos criando uma lógica de implementação na qual nossos métodos gRPC interagem usando os formatos gerados, criando um novo servidor gRPC na porta 50051. Agora, nosso serviço gRPC estará lá.
Você pode executar isso com $ go run main.go , mas não verá nada e não poderá usá-lo ... Então, vamos criar um cliente para vê-lo em ação.
Vamos criar uma interface de linha de comando que pegue um arquivo JSON e interaja com nosso serviço gRPC.
No diretório raiz, crie um novo subdiretório $ mkdir consignment-cli . Nesse diretório, crie um arquivo cli.go com o seguinte conteúdo:
cli.go package main import ( "encoding/json" "io/ioutil" "log" "os" pbf "seaport/consignment" "golang.org/x/net/context" "google.golang.org/grpc" ) const ( address = "localhost:50051" defaultFilename = "consignment.json" )
Agora crie um lote (consignment-cli / consignment.json):
{ "description": " ", "weight": 100, "containers": [ { "customer_id": "_001", "user_id": "_001", "origin": " " } ], "vessel_id": "_001" }
Agora, se você executar $ go, execute main.go no pacote seaport e, em seguida, execute $ go, execute cli.go em um painel de terminal separado. Você deverá ver a mensagem "Created: true".
Mas como podemos verificar exatamente o que foi criado? Vamos atualizar nosso serviço usando o método GetConsignments para que possamos visualizar todos os lotes criados.
Portanto, aqui criamos um novo método em nosso serviço chamado GetConsignments , também criamos um novo GetRequest , que ainda não contém nada. Também adicionamos um campo de lotes enviados à nossa mensagem de resposta. Você notará que o tipo aqui tem a palavra-chave repetida até o tipo. Isso, como você provavelmente adivinhou, significa simplesmente tratar esse campo como uma matriz desses tipos.
Não se apresse em executar o programa, a implementação de nossos métodos gRPC é baseada na correspondência da interface criada pela biblioteca protobuf, precisamos garantir que nossa implementação corresponda à nossa definição de proto.
Aqui nós incluímos nosso novo método GetConsignments, atualizamos nosso repositório e interface, respectivamente criados na definição consignments.proto. Se você executar $ go, execute main.go novamente , o programa deverá funcionar novamente.
Vamos atualizar nossa ferramenta CLI para incluir a capacidade de chamar esse método e é possível listar nossas partes:
cli.go package main import ( "encoding/json" "io/ioutil" "log" "os" pbf "seaport/consignment" "golang.org/x/net/context" "google.golang.org/grpc" ) const ( address = "localhost:50051" defaultFilename = "consignment.json" )
Adicione o código acima ao cli.go e execute $ go execute cli.go novamente . O cliente executará CreateConsignment e depois chamar GetConsignments. E você deve ver que na lista de respostas contém a composição da parte.
Assim, temos o primeiro microsserviço e cliente a interagir com ele usando protobuf e gRPC.
A próxima parte desta série incluirá a integração go-micro, que é uma base poderosa para a criação de microsserviços baseados em gRPC. Também criaremos nosso segundo serviço. Considere o trabalho de nossos serviços em contêineres do Docker, na próxima parte desta série de artigos.