gRPC (gRPC Remote Procedure Calls) è un framework moderno, open-source e ad alte prestazioni per le chiamate di procedura remota (RPC) sviluppato da Google. È progettato per facilitare la comunicazione efficiente tra sistemi distribuiti, rendendolo particolarmente adatto per architetture a microservizi. Di seguito una spiegazione di gRPC e del suo ruolo nella comunicazione tra microservizi:
Cosa è gRPC?
gRPC è un protocollo che consente alle applicazioni client e server di comunicare in modo trasparente, semplificando la costruzione di sistemi distribuiti. Utilizza HTTP/2 per il trasporto, Protocol Buffers (Protobuf) come linguaggio di definizione dell’interfaccia (IDL) e offre funzionalità come l’autenticazione, il bilanciamento del carico e altro ancora.
Ecco alcune caratteristiche di gRPC:
- Indipendente dal linguaggio. gRPC supporta più linguaggi di programmazione, inclusi Java, Python, Go, C++ e altri.
- Comunicazione efficiente. Utilizza la serializzazione binaria con Protobuf, che è più veloce e compatta rispetto ai formati basati su testo come JSON.
- Basato su HTTP/2. gRPC sfrutta HTTP/2, abilitando funzionalità come il multiplexing, lo streaming e la riduzione della latenza.
- Tipizzazione forte. I servizi e i messaggi sono definiti utilizzando Protobuf, garantendo la sicurezza dei tipi e riducendo gli errori.
- Supporto allo streaming. gRPC supporta quattro tipi di streaming: unario, server-streaming, client-streaming e streaming bidirezionale.
Come funziona gRPC
1. Definire Servizi e Messaggi
Utilizzando Protobuf, definisci l’interfaccia del servizio (metodi) e la struttura dei messaggi da scambiare.
service Greeter {
rpc SayHello (HelloRequest) returns (HelloResponse);
}
message HelloRequest {
string name = 1;
}
message HelloResponse {
string message = 1;
}
2. Generare Codice
Il compilatore Protobuf (protoc
) genera codice client e server nel linguaggio di programmazione scelto.
service Greeter {
rpc SayHello (HelloRequest) returns (HelloResponse);
}
message HelloRequest {
string name = 1;
}
message HelloResponse {
string message = 1;
}
3. Implementare il Server
Implementa la logica lato server per il servizio definito.
4. Creare il Client
Utilizza il codice client generato per chiamare i metodi del server.
Ruolo di gRPC nella Comunicazione tra Microservizi
Le architetture dei microservizi comportano la suddivisione delle applicazioni in servizi più piccoli e indipendenti che comunicano attraverso la rete. gRPC gioca un ruolo cruciale in questo contesto grazie alla sua efficienza e flessibilità.
1. Alta Prestazione
- gRPC utilizza la serializzazione binaria con Protobuf, che è più veloce e compatta rispetto ai formati basati su testo come JSON o XML.
- HTTP/2 riduce la latenza e migliora il throughput abilitando il multiplexing e la compressione degli header.
2. Definizione di Contratti Forti
- Protobuf impone un contratto rigoroso tra i servizi, riducendo la probabilità di errori di comunicazione.
- Le modifiche alla definizione del servizio possono essere gestite con versioning, garantendo la retrocompatibilità.
3. Capacità di Streaming
- gRPC supporta lo streaming bidirezionale, rendendolo ideale per la comunicazione in tempo reale, come le applicazioni di chat o i feed di dati in diretta.
- Lo streaming lato server e lato client permette di gestire in modo efficiente set di dati di grandi dimensioni o flussi continui di dati.
4. Interoperabilità
- gRPC è senza vincoli linguistici, consentendo a microservizi scritti in lingue diverse di comunicare in modo fluido.
- Questo è particolarmente utile negli ambienti di microservizi poliglotti.
5. Funzionalità Incorporate
- gRPC fornisce supporto integrato per funzionalità come autenticazione, crittografia (tramite TLS) e bilanciamento del carico, riducendo la necessità di librerie o strumenti aggiuntivi.
6. Scalabilità
- La natura leggera di gRPC e la comunicazione efficiente lo rendono adatto per distribuzioni di microservizi su larga scala.
- Si integra bene con piattaforme di orchestrazione dei contenitori come Kubernetes.
Utilizzi di gRPC nei Microservizi
- Comunicazione tra servizi. gRPC è ideale per la comunicazione tra microservizi, specialmente in scenari critici per le prestazioni.
- Sistemi in tempo reale. Le sue capacità di streaming lo rendono adatto per applicazioni in tempo reale come i giochi, l’IoT o le analisi in diretta.
- Ambienti poliglotti. Quando i microservizi sono scritti in lingue diverse, gRPC garantisce una comunicazione senza soluzione di continuità.
- Applicazioni native del cloud. gRPC si integra bene con le tecnologie native del cloud come Kubernetes e le mesh di servizio (ad es. Istio).
Vantaggi di gRPC
- Efficienza. La serializzazione binaria e HTTP/2 rendono gRPC più veloce e più efficiente in termini di risorse.
- Sicurezza del tipo. Protobuf garantisce un tipaggio forte, riducendo gli errori in fase di esecuzione.
- Supporto multi-linguaggio. Funziona su diverse lingue di programmazione.
- Streaming. Supporta modelli di streaming avanzati per la comunicazione in tempo reale.
Sfide di gRPC
- Complessità. Configurare gRPC può essere più complesso rispetto a REST a causa della necessità di definizioni Protobuf e generazione di codice.
- Strumenti. Il debug e i test dei servizi gRPC possono essere più difficili rispetto a REST, poiché strumenti come Postman non sono progettati nativamente per gRPC.
- Supporto del browser. gRPC non è nativamente supportato nei browser, richiedendo strumenti come gRPC-Web per i client basati sul web.
Perché utilizzare gRPC con Spring Boot?
Spring Boot è un framework popolare per la creazione di applicazioni Java e combinarlo con gRPC consente ai programmatori di creare servizi ad alte prestazioni, scalabili e interoperabili. Grazie alla configurazione automatica e all’iniezione delle dipendenze di Spring Boot, l’integrazione di gRPC diventa semplice.
Passaggi per la creazione dell’applicazione
Costruiremo un semplice servizio gRPC chiamato Greeter
che consente a un client di inviare un nome al server e ricevere una risposta “Ciao, {name}!”. Ecco come lo faremo:
- Definire il servizio gRPC utilizzando Protocol Buffers.
- Generare classi Java dal file
.proto
. - Implementare il server gRPC in Spring Boot.
- Implementare il client gRPC in Spring Boot.
- Aggiungere un controller REST per invocare il client gRPC per il testing.
- Eseguire l’applicazione e testare la comunicazione.
1. Definire il servizio gRPC (File .proto)
Il primo passo è definire il servizio gRPC utilizzando Protocol Buffers. Creare un file chiamato greeter.proto
nella directory src/main/proto
:
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;
}
Questo file definisce:
- Un servizio
Greeter
con un metodo RPCSayHello
. - Un messaggio
HelloRequest
contenente un camponame
. - Un messaggio
HelloResponse
contenente un campomessage
.
2. Aggiungere Dipendenze
Per utilizzare gRPC con Spring Boot, aggiungere le seguenti dipendenze al tuo file pom.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>
Queste dipendenze includono:
- Spring Boot Starter per la configurazione di base dell’applicazione.
- Spring Boot Web per il supporto del controller REST.
- Librerie gRPC per l’implementazione del server e del client.
- Protobuf per la serializzazione e deserializzazione.
3. Generare Classi Java
Eseguire il seguente comando Maven per generare classi Java dal file .proto
:
mvn clean compile
Questo genererà le classi GreeterGrpc
correlate nella directory target/generated-sources
.
4. Implementare il Server gRPC
Successivamente, implementare il server gRPC in Spring Boot. Creare una classe chiamata GreeterService
:
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();
// Invia la risposta
responseObserver.onNext(response);
responseObserver.onCompleted();
}
}
Questa classe estende il generato GreeterGrpc.GreeterImplBase
e implementa il metodo sayHello
per gestire le richieste in arrivo.
5. Implementare il Client gRPC
Ora, implementare il client gRPC in Spring Boot. Creare una classe chiamata GreeterClient
:
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();
}
}
Questo client si connette al server gRPC e invia una richiesta al metodo SayHello
.
6. Aggiungere un Controller REST per il Testing
Per facilitare il testing del client gRPC, aggiungeremo un controller REST che espone un endpoint per invocare il GreeterClient
. Creare una classe chiamata GreeterController
:
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);
}
}
Questo controller espone un endpoint /greet
che accetta un parametro name
e restituisce la risposta dal server gRPC.
7. Creare l’Applicazione Spring Boot
Infine, creare un’applicazione Spring Boot per eseguire il server e il client:
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. Configurare la Porta del Server
Aggiungere la seguente configurazione a application.properties
:
# porta del server gRPC
grpc.server.port=9090
# porta del server Spring Boot
server.port=8080
9. Eseguire l’Applicazione
- Avviare l’applicazione Spring Boot.
- Il server gRPC partirà sulla porta
9090
. - Il controller REST sarà disponibile sulla porta
8080
.
Puoi testare l’applicazione inviando una richiesta GET all’endpoint /greet
:
curl http://localhost:8080/greet?name=World
La risposta sarà:
"Hello, World!"
Scegliere la libreria gRPC giusta per Spring Boot
Nel costruire applicazioni Spring Boot che richiedono integrazione gRPC, gli sviluppatori spesso si trovano di fronte a una scelta tra diverse librerie. Le opzioni più comunemente discusse sono net.devh.grpc
, org.lognet.grpc
e org.springframework.grpc
.
Ognuna di queste librerie ha i propri punti di forza, debolezze e casi d’uso. Esploriamo le differenze tra queste librerie, le loro caratteristiche e quale dovresti utilizzare per il tuo progetto.
1. net.devh.grpc (grpc-spring-boot-starter)
net.devh.grpc
, anche conosciuta come grpc-spring-boot-starter
, è una libreria ampiamente utilizzata per integrare gRPC con Spring Boot. È attivamente mantenuta e fornisce un insieme robusto di funzionalità per costruire server e client gRPC in un’applicazione Spring Boot.
Caratteristiche principali
- Auto-configurazione. Semplifica la configurazione di server e client gRPC.
- Integrazione Spring. Supporta l’iniezione delle dipendenze e altre funzionalità di Spring.
- Sicurezza Spring. Si integra facilmente con Spring Security per una comunicazione sicura.
- Controlli di salute. Fornisce controlli di salute tramite Spring Boot Actuator.
- Comunicazione sincrona e asincrona. Supporta entrambi gli stili di comunicazione.
Perché usarlo?
- Manutenzione attiva. La libreria è attivamente mantenuta e aggiornata.
- Documentazione completa. Ben documentata con una grande community di supporto.
- Pronto per la produzione. Ampiamente utilizzato in ambienti di produzione.
Quando usarlo?
- Se stai costruendo una nuova applicazione Spring Boot e hai bisogno di un’integrazione gRPC affidabile e ricca di funzionalità.
- Se desideri un’integrazione senza soluzione di continuità con le funzionalità di Spring Boot come l’iniezione delle dipendenze, la sicurezza e i controlli di integrità.
2. org.lognet.grpc (grpc-spring-boot-starter)
org.lognet.grpc
è un’altra libreria per l’integrazione di gRPC con Spring Boot. Tuttavia, è meno attivamente mantenuta rispetto a net.devh.grpc
e manca di alcune delle funzionalità avanzate offerte da quest’ultima.
Caratteristiche principali
- Configurazione di base di gRPC. Fornisce supporto di base per server e client gRPC.
- Integrazione con Spring Boot. Funziona con Spring Boot ma con meno funzionalità.
Perché usarlo?
- Utilizzo storico. Era una delle prime librerie per l’integrazione di gRPC e Spring Boot.
- Semplicità. Adatto per casi d’uso semplici.
Quando usarlo?
- Se stai lavorando su un progetto più vecchio che utilizza già questa libreria.
- Non raccomandato per nuovi progetti a causa della manutenzione limitata e di meno funzionalità.
3. org.springframework.grpc (Spring gRPC)
org.springframework.grpc
è uno sforzo sperimentale o guidato dalla comunità per integrare gRPC con Spring. Non è un progetto ufficiale di Spring e potrebbe non essere maturo o ricco di funzionalità come net.devh.grpc
.
Caratteristiche Chiave
- Integrazione gRPC di base. Fornisce supporto di base per server e client gRPC.
- Allineamento con l’ecosistema Spring. Progettato per allinearsi strettamente con l’ecosistema Spring.
Perché Usarlo?
- Uso sperimentale. Adatto per esperimenti o per contribuire al progetto.
- Allineamento con Spring. Se preferisci usare qualcosa che si allinei strettamente con Spring.
Quando Usarlo?
- Solo se stai esplorando o contribuendo al progetto.
- Non raccomandato per l’uso in produzione a causa della sua natura sperimentale.
Quale Dovresti Usare?
Per Nuovi Progetti
Usa net.devh.grpc
(grpc-spring-boot-starter). È l’opzione più matura, attivamente mantenuta e ricca di funzionalità per integrare gRPC con Spring Boot. La sua integrazione senza soluzione di continuità con le funzionalità di Spring Boot lo rende la scelta migliore per nuovi progetti.
Per Progetti Esistenti
Se stai già utilizzando org.lognet.grpc
, considera di migrare a net.devh.grpc
per un migliore supporto e funzionalità. Mentre org.lognet.grpc
potrebbe funzionare per progetti più vecchi, manca della manutenzione attiva e delle funzionalità avanzate di net.devh.grpc
.
Per Uso Sperimentale
Se stai esplorando o contribuendo all’integrazione di Spring gRPC, puoi esaminare org.springframework.grpc
. Tuttavia, non è consigliato per l’uso in produzione a causa della sua natura sperimentale.
Considerazioni Chiave
- Supporto della community.
net.devh.grpc
ha una community più ampia e una documentazione migliore, rendendo più facile trovare aiuto e risorse. - Prontezza alla produzione.
net.devh.grpc
è ampiamente utilizzato in ambienti di produzione ed è considerato stabile e affidabile. - Facilità d’uso.
net.devh.grpc
fornisce auto-configurazione e integrazione senza soluzione di continuità con Spring Boot, riducendo la complessità della configurazione.
Conclusione
gRPC è uno strumento potente per la comunicazione tra microservizi, offrendo elevate prestazioni, tipizzazione forte e funzionalità avanzate come lo streaming. Sebbene richieda una configurazione iniziale più impegnativa rispetto a REST, la sua efficienza e scalabilità lo rendono una scelta eccellente per i sistemi moderni e distribuiti.
Con l’aumentare della complessità delle architetture a microservizi, gRPC gioca un ruolo sempre più importante nel facilitare la comunicazione senza soluzione di continuità tra i servizi. In questo articolo, abbiamo costruito un semplice client e server gRPC utilizzando Spring Boot 3, definendo un servizio gRPC con Protocol Buffers, generando classi Java, implementando il server e il client, e aggiungendo un controller REST per un facile testing. Questo esempio mostra la potenza e la semplicità di gRPC per la costruzione di servizi ad alte prestazioni, scalabili e interoperabili. Puoi estenderlo ulteriormente con servizi più complessi, streaming o gestione degli errori. Buon coding!
Repo di GitHub: grpc-client-and-server-with-spring-boot.
Source:
https://dzone.com/articles/understanding-grpc-and-its-role-in-microservices-c