gRPC e seu Papel na Comunicação entre Microsserviços

gRPC (gRPC Remote Procedure Calls) é um moderno framework RPC (Chamada de Procedimento Remoto) de código aberto e alto desempenho desenvolvido pelo Google. Ele é projetado para facilitar a comunicação eficiente entre sistemas distribuídos, tornando-se particularmente adequado para arquiteturas de microserviços. Abaixo está uma explicação sobre gRPC e seu papel na comunicação entre microserviços:

O que é gRPC?

gRPC é um protocolo que permite que aplicativos cliente e servidor se comuniquem de forma transparente, facilitando a construção de sistemas distribuídos. Ele utiliza HTTP/2 para transporte, Protocol Buffers (Protobuf) como sua linguagem de definição de interface (IDL) e oferece recursos como autenticação, balanceamento de carga e mais.

Aqui estão algumas características do gRPC:

  1. Independente de linguagem. O gRPC suporta várias linguagens de programação, incluindo Java, Python, Go, C++ e mais.
  2. Comunicação eficiente. Ele utiliza serialização binária com Protobuf, que é mais rápida e compacta do que formatos baseados em texto como JSON.
  3. Baseado em HTTP/2. O gRPC aproveita o HTTP/2, permitindo recursos como multiplexação, streaming e redução de latência.
  4. Fortemente tipado. Serviços e mensagens são definidos usando Protobuf, garantindo segurança de tipos e reduzindo erros.
  5. Suporte a streaming. gRPC suporta quatro tipos de streaming: unário, streaming do servidor, streaming do cliente e streaming bidirecional.

Como o gRPC Funciona

1. Defina Serviços e Mensagens

Usando Protobuf, você define a interface do serviço (métodos) e a estrutura das mensagens a serem trocadas.

ProtoBuf

 

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloResponse);
}

message HelloRequest {
  string name = 1;
}

message HelloResponse {
  string message = 1;
}

2. Gere o Código

O compilador Protobuf (protoc) gera código para cliente e servidor na linguagem de programação escolhida.

ProtoBuf

 

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloResponse);
}

message HelloRequest {
  string name = 1;
}

message HelloResponse {
  string message = 1;
}

3. Implemente o Servidor

Implemente a lógica do lado do servidor para o serviço definido.

4. Crie o Cliente

Use o código do cliente gerado para chamar os métodos do servidor.

Papel do gRPC na Comunicação entre Microserviços

Arquiteturas de microserviços envolvem desmembrar aplicações em serviços menores e independentes que se comunicam pela rede. O gRPC desempenha um papel crucial nesse contexto devido à sua eficiência e flexibilidade.

1. Alta Performance

  • gRPC utiliza serialização binária com Protobuf, que é mais rápida e compacta do que formatos baseados em texto como JSON ou XML.
  • HTTP/2 reduz a latência e melhora a capacidade de transmissão ao permitir multiplexação e compressão de cabeçalhos.

2. Definição de Contrato Forte

  • Protobuf impõe um contrato rigoroso entre os serviços, reduzindo a probabilidade de erros de comunicação.
  • Alterações na definição do serviço podem ser gerenciadas com versionamento, garantindo compatibilidade retroativa.

3. Capacidades de Streaming

  • gRPC suporta streaming bidirecional, tornando-o ideal para comunicação em tempo real, como aplicações de chat ou feeds de dados ao vivo.
  • A streaming do lado do servidor e do lado do cliente permite o manuseio eficiente de grandes conjuntos de dados ou fluxos de dados contínuos.

4. Interoperabilidade

  • gRPC é agnóstico em relação a linguagens, permitindo que microserviços escritos em diferentes linguagens se comuniquem de forma transparente.
  • Isso é particularmente útil em ambientes de microserviços poliglotas.

5. Recursos Integrados

  • gRPC fornece suporte embutido para recursos como autenticação, criptografia (via TLS) e balanceamento de carga, reduzindo a necessidade de bibliotecas ou ferramentas adicionais.

6. Escalabilidade

  • A natureza leve do gRPC e a comunicação eficiente o tornam adequado para implantações de microserviços em larga escala.
  • Ele se integra bem com plataformas de orquestração de contêineres como Kubernetes.

Casos de Uso para gRPC em Microserviços

  1. Comunicação entre serviços. gRPC é ideal para comunicação entre microserviços, especialmente em cenários críticos de desempenho.
  2. Sistemas em tempo real. Suas capacidades de streaming o tornam adequado para aplicações em tempo real como jogos, IoT ou análises ao vivo.
  3. Ambientes poliglotas. Quando os microserviços são escritos em diferentes linguagens, o gRPC garante uma comunicação sem costura.
  4. Aplicações nativas da nuvem. gRPC se integra bem com tecnologias nativas da nuvem como Kubernetes e malhas de serviços (por exemplo, Istio).

Vantagens do gRPC

  • Eficiência. A serialização binária e o HTTP/2 tornam o gRPC mais rápido e eficiente em termos de recursos.
  • Segurança de tipos. Protobuf garante forte tipagem, reduzindo erros em tempo de execução.
  • Suporte a múltiplas linguagens. Funciona em várias linguagens de programação.
  • Streaming. Suporta padrões avançados de streaming para comunicação em tempo real.

Desafios do gRPC

  • Complexidade. Configurar o gRPC pode ser mais complexo do que o REST devido à necessidade de definições Protobuf e geração de código.
  • Ferramentas. Depurar e testar serviços gRPC pode ser mais difícil em comparação com o REST, já que ferramentas como Postman não são projetadas nativamente para gRPC.
  • Suporte a navegadores. O gRPC não é suportado nativamente em navegadores, exigindo ferramentas como gRPC-Web para clientes baseados na web.

Por que usar gRPC com Spring Boot?

Spring Boot é um framework popular para construir aplicações Java, e combiná-lo com gRPC permite que os desenvolvedores criem serviços de alto desempenho, escaláveis e interoperáveis. Com a auto-configuração e a injeção de dependências do Spring Boot, integrar gRPC torna-se simples.

Etapas para construir a aplicação

Vamos construir um simples serviço gRPC chamado Greeter que permite a um cliente enviar um nome para o servidor e receber uma resposta “Olá, {nome}!”. Aqui está como vamos fazer isso:

  1. Defina o Serviço gRPC usando Protocol Buffers.
  2. Gere classes Java a partir do arquivo .proto.
  3. Implemente o Servidor gRPC no Spring Boot.
  4. Implemente o Cliente gRPC no Spring Boot.
  5. Adicione um Controlador REST para invocar o cliente gRPC para testes.
  6. Execute a aplicação e teste a comunicação.

1. Defina o Serviço gRPC (Arquivo .proto)

A primeira etapa é definir o serviço gRPC usando Protocol Buffers. Crie um arquivo chamado greeter.proto no diretório src/main/proto:

ProtoBuf

 

syntax = "proto3";

option java_multiple_files = true;
option java_package = "com.example.grpc";
option java_outer_classname = "GreeterProto";
service Greeter {
  rpc SayHello (HelloRequest) returns (HelloResponse);
}
message HelloRequest {
  string name = 1;
}
message HelloResponse {
  string message = 1;
}

Este arquivo define:

  • Um serviço Greeter com um método RPC SayHello.
  • Uma mensagem HelloRequest contendo um campo name.
  • Uma mensagem HelloResponse contendo um campo message.

2. Adicione Dependências

Para usar gRPC com Spring Boot, adicione as seguintes dependências ao seu pom.xml:

XML

 

<dependencies>
    <!-- Spring Boot Starter -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
<!-- Spring Boot Web for REST Controller -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- gRPC dependencies -->
    <dependency>
        <groupId>net.devh</groupId>
        <artifactId>grpc-spring-boot-starter</artifactId>
        <version>2.14.0.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>io.grpc</groupId>
        <artifactId>grpc-netty-shaded</artifactId>
        <version>1.54.0</version>
    </dependency>
    <dependency>
        <groupId>io.grpc</groupId>
        <artifactId>grpc-protobuf</artifactId>
        <version>1.54.0</version>
    </dependency>
    <dependency>
        <groupId>io.grpc</groupId>
        <artifactId>grpc-stub</artifactId>
        <version>1.54.0</version>
    </dependency>
    <!-- Protobuf Java Format -->
    <dependency>
        <groupId>com.google.protobuf</groupId>
        <artifactId>protobuf-java</artifactId>
        <version>3.22.2</version>
    </dependency>
</dependencies>
<build>
    <plugins>
        <!-- Protobuf Compiler Plugin -->
        <plugin>
            <groupId>org.xolstice.maven.plugins</groupId>
            <artifactId>protobuf-maven-plugin</artifactId>
            <version>0.6.1</version>
            <configuration>
                <protocArtifact>com.google.protobuf:protoc:3.22.2:exe:${os.detected.classifier}</protocArtifact>
                <pluginId>grpc-java</pluginId>
                <pluginArtifact>io.grpc:protoc-gen-grpc-java:1.54.0:exe:${os.detected.classifier}</pluginArtifact>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>compile</goal>
                        <goal>compile-custom</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

Essas dependências incluem:

  • Spring Boot Starter para configuração básica da aplicação.
  • Spring Boot Web para suporte ao controlador REST.
  • Bibliotecas gRPC para implementação do servidor e do cliente.
  • Protobuf para serialização e desserialização.

3. Gere Classes Java

Execute o seguinte comando Maven para gerar classes Java a partir do arquivo .proto:

Plain Text

 

mvn clean compile

Isso irá gerar o GreeterGrpc e classes relacionadas no diretório target/generated-sources.

4. Implemente o Servidor gRPC

Em seguida, implemente o servidor gRPC no Spring Boot. Crie uma classe chamada GreeterService:

Java

 

package com.example.grpc.server;

import com.example.grpc.GreeterGrpc;
import com.example.grpc.GreeterProto.HelloRequest;
import com.example.grpc.GreeterProto.HelloResponse;
import io.grpc.stub.StreamObserver;
import net.devh.boot.grpc.server.service.GrpcService;
@GrpcService
public class GreeterService extends GreeterGrpc.GreeterImplBase {
    @Override
    public void sayHello(HelloRequest request, StreamObserver responseObserver) {
        String name = request.getName();
        String message = "Hello, " + name + "!";
        HelloResponse response = HelloResponse.newBuilder().setMessage(message).build();
        // Envie a resposta
        responseObserver.onNext(response);
        responseObserver.onCompleted();
    }
}

Esta classe estende o GreeterGrpc.GreeterImplBase gerado e implementa o método sayHello para lidar com solicitações recebidas.

5. Implemente o Cliente gRPC

Agora, implemente o cliente gRPC no Spring Boot. Crie uma classe chamada GreeterClient:

Java

 

package com.example.grpc.client;
import com.example.grpc.GreeterGrpc;
import com.example.grpc.GreeterProto.HelloRequest;
import com.example.grpc.GreeterProto.HelloResponse;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import org.springframework.stereotype.Service;
@Service
public class GreeterClient {
    private final GreeterGrpc.GreeterBlockingStub blockingStub;
    public GreeterClient() {
        ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 9090)
                .usePlaintext()
                .build();
        this.blockingStub = GreeterGrpc.newBlockingStub(channel);
    }
    public String sayHello(String name) {
        HelloRequest request = HelloRequest.newBuilder().setName(name).build();
        HelloResponse response = blockingStub.sayHello(request);
        return response.getMessage();
    }
}

Este cliente se conecta ao servidor gRPC e envia uma solicitação ao método SayHello.

6. Adicione um Controlador REST para Testes

Para facilitar o teste do cliente gRPC, adicionaremos um controlador REST que expõe um endpoint para invocar o GreeterClient. Crie uma classe chamada GreeterController:

Java

 

package com.example.grpc.controller;
import com.example.grpc.client.GreeterClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class GreeterController {

    private final GreeterClient greeterClient;

    @Autowired
    public GreeterController(GreeterClient greeterClient) {
        this.greeterClient = greeterClient;
    }

    @GetMapping("/greet")
    public String greet(@RequestParam String name) {
        return greeterClient.sayHello(name);
    }
}

Este controlador expõe um endpoint /greet que aceita um parâmetro name e retorna a resposta do servidor gRPC.

7. Crie a Aplicação Spring Boot

Finalmente, crie uma aplicação Spring Boot para executar o servidor e o cliente:

Java

 

package com.example.grpc;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class GrpcApplication {
    public static void main(String[] args) {
        SpringApplication.run(GrpcApplication.class, args);
    }
}

8. Configure a Porta do Servidor

Adicione a seguinte configuração ao application.properties:

Plain Text

 

# porta do servidor gRPC
grpc.server.port=9090

# porta do servidor Spring Boot
server.port=8080

9. Execute a Aplicação

  1. Inicie a aplicação Spring Boot.
  2. O servidor gRPC será iniciado na porta 9090.
  3. O controlador REST estará disponível na porta 8080.

Você pode testar a aplicação enviando uma solicitação GET para o endpoint /greet:

Plain Text

 

curl http://localhost:8080/greet?name=World

A resposta será:

Plain Text

 

"Hello, World!"

Escolhendo a Biblioteca gRPC Certa para o Spring Boot

Ao construir aplicações Spring Boot que exigem integração com gRPC, os desenvolvedores frequentemente se deparam com a escolha entre várias bibliotecas. As opções mais comumente discutidas são net.devh.grpc, org.lognet.grpc e org.springframework.grpc.

Cada uma dessas bibliotecas possui seus pontos fortes, pontos fracos e casos de uso. Vamos explorar as diferenças entre essas bibliotecas, seus recursos e qual você deve usar para o seu projeto.

1. net.devh.grpc (grpc-spring-boot-starter)

net.devh.grpc, também conhecido como grpc-spring-boot-starter, é uma biblioteca amplamente utilizada para integrar gRPC com o Spring Boot. É mantida ativamente e oferece um conjunto robusto de recursos para construir servidores e clientes gRPC em uma aplicação Spring Boot.

Recursos Principais

  • Autoconfiguração. Simplifica a configuração de servidores e clientes gRPC.
  • Integração com o Spring. Suporta injeção de dependência e outros recursos do Spring.
  • Segurança do Spring. Integra facilmente com o Spring Security para comunicação segura.
  • Verificações de saúde. Fornece verificações de saúde via Spring Boot Actuator.
  • Comunicação síncrona e assíncrona. Suporta ambos os estilos de comunicação.

Por que usar?

  • Manutenção ativa. A biblioteca é ativamente mantida e atualizada.
  • Documentação abrangente. Bem documentada com uma grande comunidade de suporte.
  • Pronto para produção. Amplamente utilizado em ambientes de produção.

Quando usar?

  • Se você está construindo uma nova aplicação Spring Boot e precisa de uma integração gRPC confiável e rica em recursos.
  • Se você deseja integração perfeita com recursos do Spring Boot como injeção de dependência, segurança e verificações de saúde.

2. org.lognet.grpc (grpc-spring-boot-starter)

org.lognet.grpc é outra biblioteca para integrar gRPC com o Spring Boot. No entanto, é menos ativamente mantida em comparação com net.devh.grpc e carece de alguns dos recursos avançados oferecidos por este último.

Recursos principais

  • Configuração básica do gRPC. Fornece suporte básico para servidores e clientes gRPC.
  • Integração com o Spring Boot. Funciona com o Spring Boot, mas com menos recursos.

Por que usar?

  • Uso histórico. Foi uma das primeiras bibliotecas para integração de gRPC e Spring Boot.
  • Simplicidade. Adequado para casos de uso simples.

Quando usar?

  • Se você está trabalhando em um projeto mais antigo que já utiliza esta biblioteca.
  • Não recomendado para novos projetos devido à manutenção limitada e menos recursos.

3. org.springframework.grpc (Spring gRPC)

org.springframework.grpc é um esforço experimental ou liderado pela comunidade para integrar gRPC com Spring. Não é um projeto oficial do Spring e pode não ser tão maduro ou rico em recursos quanto net.devh.grpc.

Principais Recursos

  • Integração básica do gRPC. Fornece suporte básico para servidores e clientes gRPC.
  • Alinhamento com o ecossistema Spring. Projetado para alinhar-se de perto com o ecossistema Spring.

Por que usá-lo?

  • Uso experimental. Adequado para experimentação ou contribuição para o projeto.
  • Alinhamento com o Spring. Se você prefere usar algo que se alinhe de perto com o Spring.

Quando usá-lo?

  • Somente se você estiver explorando ou contribuindo para o projeto.
  • Não recomendado para uso em produção devido à sua natureza experimental.

Qual você deve usar?

Para Novos Projetos

Use net.devh.grpc (grpc-spring-boot-starter). É a opção mais madura, ativamente mantida e rica em recursos para integrar gRPC com Spring Boot. Sua integração perfeita com os recursos do Spring Boot faz dele a melhor escolha para novos projetos.

Para Projetos Existentes

Se você já está usando org.lognet.grpc, considere migrar para net.devh.grpc para obter melhor suporte e recursos. Embora org.lognet.grpc possa funcionar para projetos mais antigos, ele carece de manutenção ativa e recursos avançados do net.devh.grpc.

Para Uso Experimental

Se você está explorando ou contribuindo para a integração do Spring gRPC, pode considerar org.springframework.grpc. No entanto, não é recomendado para uso em produção devido à sua natureza experimental.

Considerações Principais

  • Suporte da comunidade. net.devh.grpc tem uma comunidade maior e melhor documentação, tornando mais fácil encontrar ajuda e recursos.
  • Prontidão para produção. net.devh.grpc é amplamente utilizado em ambientes de produção e é considerado estável e confiável.
  • Facilidade de uso. net.devh.grpc fornece auto-configuração e integração perfeita com o Spring Boot, reduzindo a complexidade da configuração.

Conclusão

gRPC é uma ferramenta poderosa para comunicação entre microserviços, oferecendo alto desempenho, tipagem forte e recursos avançados como streaming. Embora exija uma configuração inicial maior em comparação com REST, sua eficiência e escalabilidade fazem dele uma excelente escolha para sistemas modernos e distribuídos.

À medida que as arquiteturas de microserviços crescem em complexidade, o gRPC desempenha um papel cada vez mais importante ao possibilitar a comunicação sem costura entre os serviços. Neste artigo, construímos uma aplicação simples de cliente e servidor gRPC usando o Spring Boot 3, definindo um serviço gRPC com Protocol Buffers, gerando classes Java, implementando o servidor e o cliente, e adicionando um controlador REST para facilitar os testes. Este exemplo demonstra o poder e a simplicidade do gRPC para construir serviços de alto desempenho, escaláveis e interoperáveis. Você pode estendê-lo ainda mais com serviços mais complexos, streaming ou tratamento de erros. Boa codificação!

Repositório do GitHub: grpc-client-and-server-with-spring-boot.

Source:
https://dzone.com/articles/understanding-grpc-and-its-role-in-microservices-c