🚀 RPC(Remote Procedure Call): 분산 시스템의 핵심 통신 기법
RPC(Remote Procedure Call)는 네트워크에 연결된 다른 컴퓨터의 메서드를 마치 로컬에서 실행하듯이 호출할 수 있게 해주는 기술이다.
이 기술은 gRPC, Thrift, RMI 등의 프레임워크에서 기본적으로 사용되며, 마이크로서비스 아키텍처(MSA)와 분산 시스템의 핵심 기법 중 하나이다.
이번 글에서는 RPC의 작동 원리, 장단점, 구현 방법, 그리고 예제에 대해 다뤄보도록 한다.
🔍 RPC란 무엇인가?
클라이언트는 마치 로컬에서 함수를 호출하는 것처럼 원격 서버의 메서드를 호출하고, 서버는 그 결과를 반환한다.
예시 시나리오
- 클라이언트 -> getUserData() 호출 -> 네트워크를 통해 서버에서 함수 실행 -> 결과 반환
- 개발자는 함수가 로컬에 있는 것처럼 사용할 수 있으며, 네트워크 복잡성은 숨겨진다.
🏗 RPC의 구성 요소
RPC는 크게 클라이언트, 서버, 스텁(Stub) 세 가지 주요 구성 요소로 이루어진다.
구성 요소 설명
- Client: 요청을 보내는 주체, 원격 메서드를 호출
- Client Stub: 클라이언트와 서버 사이의 통신을 담당하는 프록시
- Server Stub: 요청을 받아 서버의 메서드를 호출하고 응답을 반환
- Network: 클라이언트와 서버 사이의 데이터 전송을 담당하는 네트워크
- Service: 실제로 실행되는 서버 측의 메서드
예시 흐름
1. 클라이언트 → getUser() 메서드 호출
2. Client Stub → 호출 내용을 직렬화하여 전송
3. Server Stub → 데이터를 역직렬화하고, 서버의 함수를 호출
4. 결과 반환 → 응답 데이터를 직렬화하여 클라이언트로 전송
5. 클라이언트 → 결과 값 수신 및 출력
⚙️ RPC의 작동 원리
1️⃣ 클라이언트-서버 모델
RPC는 클라이언트-서버 아키텍처를 기반으로 동작한다.
- 클라이언트: 요청을 보내는 주체 (메서드 호출)
- 서버: 요청을 수신하고 해당 작업을 수행한 뒤 응답 반환
동작 순서
- 클라이언트가 원격 함수를 호출
- 서버에서 함수 실행
- 결과 반환
2️⃣ 프로시저 호출
- 클라이언트 로컬 함수 호출 방식으로 원격 프로시저를 호출
- 내부적으로는 네트워크를 통해 서버로 전달되고, 응답이 반환됨
예시 코드 (의사 코드)
// 클라이언트 측
String result = server.getUserData(1);
3️⃣ 스텁(Stub)
Stub은 클라이언트와 서버 간의 통신을 추상화해 주는 역할을 한다.
- Client Stub -> 클라이언트가 메서드를 호출할 때 사용
- Server Stub -> 서버 측에서 데이터를 수신하고, 메서드를 실행
스텁 동작 예시
public class UserServiceStub implements UserService {
@Override
public String getUserData(int userId) {
// 네트워크 통신 대신 시뮬레이션
return "User ID: " + userId + ", Name: Alice (From Server)";
}
}
4️⃣ 마샬링과 언마샬링 (Marshalling & Unmarshalling)
- 마샬링(Marshalling): 데이터나 객체를 네트워크 전송이 가능한 형태(바이너리, JSON 등)로 직렬화
- 언마샬링(Unmarshalling): 네트워크로 전송된 데이터를 다시 원래의 형태로 역직렬화
예시 (Java에서 직렬화/역직렬화)
// 직렬화 (마샬링)
ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream());
outputStream.writeObject(user);
// 역직렬화 (언마샬링)
ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream());
User user = (User) inputStream.readObject();
👍 RPC의 장점
추상화
RPC는 복잡성을 숨기고 로컬 함수 호출처럼 원격 호출을 단순화해준다.
📌 추상화의 중요성
- 복잡성(Complexity) 감소 -> 네트워크 통신을 추상화
- 개발자 친화적 -> 로컬 메서드 호출처럼 직관적 사용 가능
- 오류 감소 -> 직접 네트워크 요청을 구현하지 않아도 됨
추상화 구현 예시
public interface UserService {
String getUserData(int userId);
}
- 인터페이스 정의 → 클라이언트는 네트워크 구현을 몰라도 사용 가능
언어 독립성
RPC는 다양한 프로그래밍 언어에서 동일한 인터페이스로 통신할 수 있도록 지원한다.
📌 언어 독립성의 구현 방법
- 표준화된 프로토콜 -> gRPC, Thrift 등
- 데이터 직렬화 -> Protocol Buffers, JSON 등
- 언어 독립적인 인터페이스 -> 모든 언어에서 공통적으로 사용할 수 있는 API 설계
분산 처리 용이성
분산 시스템 환경에서 다양한 서비스 간의 통신을 간편하고 효율적으로 처리할 수 있다.
📌 분산 처리 구현 예시
- 서비스 지향 아키텍처(SOA) -> 서비스 단위로 모듈화
- 마이크로서비스 아키텍처(MSA) -> 각 서비스가 독립적으로 배포되고 실행
- 분산 컴퓨팅 -> 여러 서버에서 병렬 작업 실행
👎 RPC의 단점
네트워크 신뢰성 문제
네트워크에 의존하기 때문에 연결이 끊어지거나 지연되면 호출 실패 가능성이 존재한다.
📌 해결 방안
- 타임아웃 및 재시도 -> 일정 시간 동안 응답이 없을 시 재시도
- 로드 밸런싱 -> 서버 간 부하 분산
- Failover -> 장애 발생 시 다른 서버로 요청 전환
디버깅의 어려움
원격 호출이기 때문에 문제 발생 시 원인을 찾기 어렵다.
📌 해결 전략
- 로깅과 모니터링 -> 각 요청 및 응답 로그 기록
- 분산 트레이싱 도구 사용 -> Jeager, Zipkin 등
- 환경 일관성 유지 -> 로컬 및 프로덕션 환경에서 동일한 구성 사용
RPC와 gRPC의 차이점
기능 | RPC | gRPC |
프로토콜 | HTTP, TCP | ✅ HTTP/2 |
직렬화 포맷 | 텍스트 기반 (XML, JSON) | ✅ 바이너리 기반 (Protocol Buffers) |
성능 | 일반적 | ✅ 더 빠르고 효율적 |
스트리밍 지원 | 제한적 | ✅ 양방향 스트리밍 지원 |
언어 지원 | 제한적 | ✅ 다중 언어 지원 (Java, Go, Python 등) |
보안 | 수동 설정 | ✅ 기본 TLS 지원 |
'기술(Tech) > Network & System' 카테고리의 다른 글
[gRPC] RESTful API와 gRPC 간 변환 방법 (with. gRPC-Web) (1) | 2025.03.02 |
---|---|
[gRPC] gRPC 서비스 요청 방식과 내부 동작 원리 (0) | 2025.02.23 |
[gRPC] Protocol Buffers(ProtoBuf): 고성능 데이터 직렬화 포맷 (0) | 2025.02.15 |
[gRPC] gRPC에 대해 알아보자 (0) | 2025.02.15 |
모바일 애플리케이션 및 웹 애플리케이션 최적화 전략 (1) | 2025.02.09 |
🚀 RPC(Remote Procedure Call): 분산 시스템의 핵심 통신 기법
RPC(Remote Procedure Call)는 네트워크에 연결된 다른 컴퓨터의 메서드를 마치 로컬에서 실행하듯이 호출할 수 있게 해주는 기술이다.
이 기술은 gRPC, Thrift, RMI 등의 프레임워크에서 기본적으로 사용되며, 마이크로서비스 아키텍처(MSA)와 분산 시스템의 핵심 기법 중 하나이다.
이번 글에서는 RPC의 작동 원리, 장단점, 구현 방법, 그리고 예제에 대해 다뤄보도록 한다.
🔍 RPC란 무엇인가?
클라이언트는 마치 로컬에서 함수를 호출하는 것처럼 원격 서버의 메서드를 호출하고, 서버는 그 결과를 반환한다.
예시 시나리오
- 클라이언트 -> getUserData() 호출 -> 네트워크를 통해 서버에서 함수 실행 -> 결과 반환
- 개발자는 함수가 로컬에 있는 것처럼 사용할 수 있으며, 네트워크 복잡성은 숨겨진다.
🏗 RPC의 구성 요소
RPC는 크게 클라이언트, 서버, 스텁(Stub) 세 가지 주요 구성 요소로 이루어진다.
구성 요소 설명
- Client: 요청을 보내는 주체, 원격 메서드를 호출
- Client Stub: 클라이언트와 서버 사이의 통신을 담당하는 프록시
- Server Stub: 요청을 받아 서버의 메서드를 호출하고 응답을 반환
- Network: 클라이언트와 서버 사이의 데이터 전송을 담당하는 네트워크
- Service: 실제로 실행되는 서버 측의 메서드
예시 흐름
1. 클라이언트 → getUser() 메서드 호출
2. Client Stub → 호출 내용을 직렬화하여 전송
3. Server Stub → 데이터를 역직렬화하고, 서버의 함수를 호출
4. 결과 반환 → 응답 데이터를 직렬화하여 클라이언트로 전송
5. 클라이언트 → 결과 값 수신 및 출력
⚙️ RPC의 작동 원리
1️⃣ 클라이언트-서버 모델
RPC는 클라이언트-서버 아키텍처를 기반으로 동작한다.
- 클라이언트: 요청을 보내는 주체 (메서드 호출)
- 서버: 요청을 수신하고 해당 작업을 수행한 뒤 응답 반환
동작 순서
- 클라이언트가 원격 함수를 호출
- 서버에서 함수 실행
- 결과 반환
2️⃣ 프로시저 호출
- 클라이언트 로컬 함수 호출 방식으로 원격 프로시저를 호출
- 내부적으로는 네트워크를 통해 서버로 전달되고, 응답이 반환됨
예시 코드 (의사 코드)
// 클라이언트 측
String result = server.getUserData(1);
3️⃣ 스텁(Stub)
Stub은 클라이언트와 서버 간의 통신을 추상화해 주는 역할을 한다.
- Client Stub -> 클라이언트가 메서드를 호출할 때 사용
- Server Stub -> 서버 측에서 데이터를 수신하고, 메서드를 실행
스텁 동작 예시
public class UserServiceStub implements UserService {
@Override
public String getUserData(int userId) {
// 네트워크 통신 대신 시뮬레이션
return "User ID: " + userId + ", Name: Alice (From Server)";
}
}
4️⃣ 마샬링과 언마샬링 (Marshalling & Unmarshalling)
- 마샬링(Marshalling): 데이터나 객체를 네트워크 전송이 가능한 형태(바이너리, JSON 등)로 직렬화
- 언마샬링(Unmarshalling): 네트워크로 전송된 데이터를 다시 원래의 형태로 역직렬화
예시 (Java에서 직렬화/역직렬화)
// 직렬화 (마샬링)
ObjectOutputStream outputStream = new ObjectOutputStream(socket.getOutputStream());
outputStream.writeObject(user);
// 역직렬화 (언마샬링)
ObjectInputStream inputStream = new ObjectInputStream(socket.getInputStream());
User user = (User) inputStream.readObject();
👍 RPC의 장점
추상화
RPC는 복잡성을 숨기고 로컬 함수 호출처럼 원격 호출을 단순화해준다.
📌 추상화의 중요성
- 복잡성(Complexity) 감소 -> 네트워크 통신을 추상화
- 개발자 친화적 -> 로컬 메서드 호출처럼 직관적 사용 가능
- 오류 감소 -> 직접 네트워크 요청을 구현하지 않아도 됨
추상화 구현 예시
public interface UserService {
String getUserData(int userId);
}
- 인터페이스 정의 → 클라이언트는 네트워크 구현을 몰라도 사용 가능
언어 독립성
RPC는 다양한 프로그래밍 언어에서 동일한 인터페이스로 통신할 수 있도록 지원한다.
📌 언어 독립성의 구현 방법
- 표준화된 프로토콜 -> gRPC, Thrift 등
- 데이터 직렬화 -> Protocol Buffers, JSON 등
- 언어 독립적인 인터페이스 -> 모든 언어에서 공통적으로 사용할 수 있는 API 설계
분산 처리 용이성
분산 시스템 환경에서 다양한 서비스 간의 통신을 간편하고 효율적으로 처리할 수 있다.
📌 분산 처리 구현 예시
- 서비스 지향 아키텍처(SOA) -> 서비스 단위로 모듈화
- 마이크로서비스 아키텍처(MSA) -> 각 서비스가 독립적으로 배포되고 실행
- 분산 컴퓨팅 -> 여러 서버에서 병렬 작업 실행
👎 RPC의 단점
네트워크 신뢰성 문제
네트워크에 의존하기 때문에 연결이 끊어지거나 지연되면 호출 실패 가능성이 존재한다.
📌 해결 방안
- 타임아웃 및 재시도 -> 일정 시간 동안 응답이 없을 시 재시도
- 로드 밸런싱 -> 서버 간 부하 분산
- Failover -> 장애 발생 시 다른 서버로 요청 전환
디버깅의 어려움
원격 호출이기 때문에 문제 발생 시 원인을 찾기 어렵다.
📌 해결 전략
- 로깅과 모니터링 -> 각 요청 및 응답 로그 기록
- 분산 트레이싱 도구 사용 -> Jeager, Zipkin 등
- 환경 일관성 유지 -> 로컬 및 프로덕션 환경에서 동일한 구성 사용
RPC와 gRPC의 차이점
기능 | RPC | gRPC |
프로토콜 | HTTP, TCP | ✅ HTTP/2 |
직렬화 포맷 | 텍스트 기반 (XML, JSON) | ✅ 바이너리 기반 (Protocol Buffers) |
성능 | 일반적 | ✅ 더 빠르고 효율적 |
스트리밍 지원 | 제한적 | ✅ 양방향 스트리밍 지원 |
언어 지원 | 제한적 | ✅ 다중 언어 지원 (Java, Go, Python 등) |
보안 | 수동 설정 | ✅ 기본 TLS 지원 |
'기술(Tech) > Network & System' 카테고리의 다른 글
[gRPC] RESTful API와 gRPC 간 변환 방법 (with. gRPC-Web) (1) | 2025.03.02 |
---|---|
[gRPC] gRPC 서비스 요청 방식과 내부 동작 원리 (0) | 2025.02.23 |
[gRPC] Protocol Buffers(ProtoBuf): 고성능 데이터 직렬화 포맷 (0) | 2025.02.15 |
[gRPC] gRPC에 대해 알아보자 (0) | 2025.02.15 |
모바일 애플리케이션 및 웹 애플리케이션 최적화 전략 (1) | 2025.02.09 |