SOFTMOA TECHNOLOGY

Spring gRPC로 마이크로서비스 통신 구현하기

소프트모아가 정리한 기술 기록입니다.

Contents
작성일 2026. 02. 11.

개요

gRPC는 Google이 개발한 고성능 RPC 프레임워크로, Protocol Buffers를 사용하여 JSON보다 빠르고 작은 페이로드를 제공합니다. Spring Boot에서 gRPC를 사용하면 REST API 대비 10배 이상 빠른 마이크로서비스 간 통신을 구현할 수 있습니다. 이 문서에서는 Spring Boot 3.5와 gRPC-Spring-Boot-Starter를 활용한 실전 구현 방법을 다룹니다.

의존성 및 플러그인 설정

gRPC와 Protobuf 코드 생성을 위한 의존성을 추가합니다.

<properties>
    <grpc.version>1.60.0</grpc.version>
    <protobuf.version>3.25.1</protobuf.version>
</properties>

<dependencies>
    <dependency>
        <groupId>net.devh</groupId>
        <artifactId>grpc-spring-boot-starter</artifactId>
        <version>3.1.0.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>io.grpc</groupId>
        <artifactId>grpc-protobuf</artifactId>
        <version>1.60.0</version>
    </dependency>
    <dependency>
        <groupId>io.grpc</groupId>
        <artifactId>grpc-stub</artifactId>
        <version>1.60.0</version>
    </dependency>
</dependencies>

<build>
    <extensions>
        <extension>
            <groupId>kr.motd.maven</groupId>
            <artifactId>os-maven-plugin</artifactId>
            <version>1.7.1</version>
        </extension>
    </extensions>
    <plugins>
        <plugin>
            <groupId>org.xolstice.maven.plugins</groupId>
            <artifactId>protobuf-maven-plugin</artifactId>
            <version>0.6.1</version>
            <configuration>
                <protocArtifact>
                    com.google.protobuf:protoc:3.25.1:exe:detect
                </protocArtifact>
                <pluginId>grpc-java</pluginId>
                <pluginArtifact>
                    io.grpc:protoc-gen-grpc-java:1.60.0:exe:detect
                </pluginArtifact>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>compile</goal>
                        <goal>compile-custom</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

Protocol Buffers 정의

서비스와 메시지 타입을 .proto 파일로 정의합니다.

// src/main/proto/user_service.proto
syntax = "proto3";

option java_multiple_files = true;
option java_package = "com.example.grpc.user";

package user;

service UserService {
  rpc GetUser(UserRequest) returns (UserResponse);
  rpc CreateUser(CreateUserRequest) returns (UserResponse);
  rpc StreamUsers(StreamRequest) returns (stream UserResponse);
}

message UserRequest {
  int64 id = 1;
}

message CreateUserRequest {
  string name = 1;
  string email = 2;
}

message UserResponse {
  int64 id = 1;
  string name = 2;
  string email = 3;
  int64 created_at = 4;
}

message StreamRequest {
  int32 limit = 1;
}

gRPC 서버 구현

@GrpcService 어노테이션으로 서비스를 구현합니다.

@GrpcService
@RequiredArgsConstructor
public class UserGrpcService extends UserServiceGrpc.UserServiceImplBase {

    private final UserRepository userRepository;

    @Override
    public void getUser(UserRequest request,
                        StreamObserver<UserResponse> responseObserver) {
        User user = userRepository.findById(request.getId())
            .orElseThrow(() -> new StatusRuntimeException(
                Status.NOT_FOUND.withDescription("User not found")
            ));

        UserResponse response = UserResponse.newBuilder()
            .setId(user.getId())
            .setName(user.getName())
            .setEmail(user.getEmail())
            .setCreatedAt(user.getCreatedAt().toEpochSecond())
            .build();

        responseObserver.onNext(response);
        responseObserver.onCompleted();
    }

    @Override
    public void createUser(CreateUserRequest request,
                           StreamObserver<UserResponse> responseObserver) {
        User user = new User(request.getName(), request.getEmail());
        User saved = userRepository.save(user);

        UserResponse response = UserResponse.newBuilder()
            .setId(saved.getId())
            .setName(saved.getName())
            .setEmail(saved.getEmail())
            .setCreatedAt(saved.getCreatedAt().toEpochSecond())
            .build();

        responseObserver.onNext(response);
        responseObserver.onCompleted();
    }

    @Override
    public void streamUsers(StreamRequest request,
                            StreamObserver<UserResponse> responseObserver) {
        userRepository.findAll(PageRequest.of(0, request.getLimit()))
            .forEach(user -> {
                UserResponse response = UserResponse.newBuilder()
                    .setId(user.getId())
                    .setName(user.getName())
                    .setEmail(user.getEmail())
                    .build();

                responseObserver.onNext(response);
            });

        responseObserver.onCompleted();
    }
}

gRPC 클라이언트 구현

@GrpcClient 어노테이션으로 다른 서비스를 호출합니다.

@Service
public class OrderService {

    @GrpcClient("user-service")
    private UserServiceGrpc.UserServiceBlockingStub userStub;

    public Order createOrder(Long userId, OrderRequest request) {
        // gRPC로 사용자 정보 조회
        UserResponse user = userStub.getUser(
            UserRequest.newBuilder()
                .setId(userId)
                .build()
        );

        // 주문 생성 로직
        Order order = new Order(user.getName(), request.getProduct());
        return orderRepository.save(order);
    }
}
# application.yml
grpc:
  server:
    port: 9090
  client:
    user-service:
      address: 'static://localhost:9090'
      negotiationType: plaintext  # 개발 환경
      # 프로덕션: TLS 설정
      # enableKeepAlive: true
      # keepAliveTime: 30s

활용 팁

  • 에러 처리: StatusRuntimeException으로 gRPC 표준 에러 코드를 반환합니다. (NOT_FOUND, INVALID_ARGUMENT, PERMISSION_DENIED 등)
  • 인터셉터: @GrpcGlobalServerInterceptor로 인증, 로깅, 메트릭 수집을 전역 처리할 수 있습니다.
  • 스트리밍: Server/Client/Bidirectional 스트리밍으로 실시간 데이터 전송이 가능합니다.
  • TLS 보안: 프로덕션 환경에서는 반드시 TLS를 활성화하여 데이터를 암호화해야 합니다.
  • 성능: JSON REST API 대비 직렬화 속도가 5~10배 빠르고, 페이로드 크기가 30~50% 작습니다.

마무리

Spring Boot와 gRPC의 조합은 마이크로서비스 간 통신 성능을 극대화합니다. Protocol Buffers의 타입 안정성 덕분에 컴파일 타임에 계약을 검증할 수 있고, HTTP/2 기반으로 멀티플렉싱과 스트리밍을 지원합니다. REST API는 외부 클라이언트용으로 유지하고, 내부 서비스 간 통신은 gRPC로 전환하면 전체 시스템 성능을 크게 개선할 수 있습니다. 특히 높은 처리량이 요구되는 결제, 추천, 검색 등의 서비스에서 즉각적인 효과를 체감할 수 있습니다.

Share this

Spring

Have a questions?

견적 및 기술문의

mobile : 010-7931-4813

Contact Form