
gRPC는 Google에서 개발한 원격 프로시저 호출(Remote Procedure Call, RPC) 시스템입니다. gRPC를 사용하면 클라이언트와 서버 간의 통신을 쉽게 구현할 수 있습니다. 이 블로그 글에서는 gRPC의 개념을 소개하고, Java로 gRPC 서버와 클라이언트를 구현하는 예제를 보여드리겠습니다.
gRPC는 다음과 같은 특징을 가지고 있습니다:
- 다양한 언어 지원: gRPC는 다양한 프로그래밍 언어(Java, C++, Python, Go 등)를 지원합니다.
- HTTP/2 기반: gRPC는 HTTP/2 프로토콜을 사용하여 고성능, 저지연, 양방향 스트리밍을 제공합니다.
- 프로토콜 버퍼(Protocol Buffers): gRPC는 효율적인 직렬화와 역직렬화를 위해 Protocol Buffers를 사용합니다.
- 서비스 정의: gRPC는 서비스와 메시지를 정의하기 위해
.proto파일을 사용합니다.
이 예제에서는 간단한 gRPC 서버와 클라이언트를 Java로 구현해보겠습니다. 예제 프로젝트는 다음과 같은 파일들로 구성됩니다:
proto디렉토리: gRPC 서비스와 메시지를 정의한.proto파일이 위치합니다.server디렉토리: gRPC 서버 구현 코드가 위치합니다.client디렉토리: gRPC 클라이언트 구현 코드가 위치합니다.
먼저, gRPC 서비스를 정의하는 .proto 파일을 작성합니다. 이 예제에서는 간단한 인사말 서비스를 정의합니다.
proto/greet.proto
syntax = "proto3";
option java_package = "com.example.grpc";
option java_outer_classname = "GreetProto";
service GreetService {
rpc Greet (GreetRequest) returns (GreetResponse);
}
message GreetRequest {
string name = 1;
}
message GreetResponse {
string message = 1;
}
gRPC 서버를 구현합니다. 서버는 GreetService를 구현하여 클라이언트의 요청을 처리합니다.
server/GrpcServer.java
package com.example.grpc.server;
import io.grpc.Server;
import io.grpc.ServerBuilder;
import io.grpc.stub.StreamObserver;
import com.example.grpc.GreetServiceGrpc;
import com.example.grpc.GreetRequest;
import com.example.grpc.GreetResponse;
import java.io.IOException;
public class GrpcServer {
public static void main(String[] args) throws IOException, InterruptedException {
Server server = ServerBuilder.forPort(8080)
.addService(new GreetServiceImpl())
.build();
server.start();
System.out.println("Server started at port 8080");
server.awaitTermination();
}
static class GreetServiceImpl extends GreetServiceGrpc.GreetServiceImplBase {
@Override
public void greet(GreetRequest request, StreamObserver<GreetResponse> responseObserver) {
String name = request.getName();
String message = "Hello, " + name + "!";
GreetResponse response = GreetResponse.newBuilder().setMessage(message).build();
responseObserver.onNext(response);
responseObserver.onCompleted();
}
}
}
gRPC 클라이언트를 구현합니다. 클라이언트는 서버에 요청을 보내고 응답을 받습니다.
client/GrpcClient.java
package com.example.grpc.client;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import com.example.grpc.GreetServiceGrpc;
import com.example.grpc.GreetRequest;
import com.example.grpc.GreetResponse;
public class GrpcClient {
public static void main(String[] args) {
ManagedChannel channel = ManagedChannelBuilder.forAddress("localhost", 8080)
.usePlaintext()
.build();
GreetServiceGrpc.GreetServiceBlockingStub stub = GreetServiceGrpc.newBlockingStub(channel);
GreetRequest request = GreetRequest.newBuilder().setName("World").build();
GreetResponse response = stub.greet(request);
System.out.println(response.getMessage());
channel.shutdown();
}
}
이제 Gradle을 사용하여 프로젝트를 빌드하고 서버와 클라이언트를 실행할 수 있습니다.
build.gradle
plugins {
id 'java'
id 'com.google.protobuf' version '0.8.13'
}
group 'com.example.grpc'
version '1.0-SNAPSHOT'
repositories {
mavenCentral()
}
ext {
grpcVersion = '1.36.0'
protobufVersion = '3.15.3'
}
dependencies {
implementation "io.grpc:grpc-netty:${grpcVersion}"
implementation "io.grpc:grpc-protobuf:${grpcVersion}"
implementation "io.grpc:grpc-stub:${grpcVersion}"
implementation "com.google.protobuf:protobuf-java:${protobufVersion}"
}
protobuf {
protoc {
artifact = "com.google.protobuf:protoc:${protobufVersion}"
}
plugins {
grpc {
artifact = "io.grpc:protoc-gen-grpc-java:${grpcVersion}"
}
}
generateProtoTasks {
all().each { task ->
task.plugins {
grpc {}
}
}
}
}
sourceSets {
main {
java {
srcDirs 'build/generated/source/proto/main/grpc'
srcDirs 'build/generated/source/proto/main/java'
}
}
}
이제 Java로 간단한 gRPC 서버와 클라이언트를 구현해보았습니다. gRPC는 고성능, 다중 언어 지원, 간단한 정의 파일 등을 제공하여 마이크로서비스 간의 통신을 효율적으로 처리할 수 있습니다. 더 복잡한 기능과 활용 방법을 배우고 싶다면 공식 문서와 예제를 참고하세요.