항목 | Local Procedure Call (LPC) | Remote Procedure Call (RPC) |
---|---|---|
호출 위치 | 동일한 프로세스 또는 같은 시스템 내에서 호출됨 | 네트워크를 통해 다른 시스템(원격 서버)에서 호출됨 |
통신 방식 | 메모리 내 함수 호출로 직접 실행 | 네트워크를 통한 메시지 기반 통신 사용 |
속도 | 매우 빠름 (메모리 접근 수준) | 상대적으로 느림 (네트워크 지연 발생 가능) |
복잡성 | 단순하고 추가 설정 필요 없음 | 네트워크 설정, 데이터 직렬화/역직렬화 등 복잡성 존재 |
의존성 | 네트워크와 무관 | 네트워크 상태 및 연결에 의존 |
오류 처리 | 로컬 오류만 처리 | 네트워크 오류, 타임아웃 등 추가적인 오류 처리 필요 |
Service Stub → RPC Client ←transport→ RPC Server ← Service Implementation
@Rpc
어노테이션과 RemoteService
인터페이스로 RPC 서비스를 정의한다.@Serializable
어노테이션을 사용한다.import kotlinx.rpc.RemoteService
import kotlinx.rpc.annotations.Rpc
import kotlinx.serialization.Serializable
@Rpc
interface OrderPlacement : RemoteService {
suspend fun placeOrder(orderLines: List<OrderLine>): OrderId
@Serializable
data class OrderLine(val beverageName: String, val quantity: Int)
}
// OrderPlacement 구현
class NoOpOrderPlacementProcessor(
override val coroutineContext: CoroutineContext
) : OrderPlacement {
override suspend fun placeOrder(orderLines: List<OrderPlacement.OrderLine>): OrderId {
log.info { "Placing order with $orderLines lines" }
return OrderId(Uuid.random().toString())
}
}
import io.ktor.server.engine.*
import io.ktor.server.netty.*
import io.ktor.server.routing.*
import kotlinx.rpc.krpc.ktor.server.Krpc
import kotlinx.rpc.krpc.ktor.server.rpc
import kotlinx.rpc.krpc.serialization.json.json
import kotlinx.serialization.json.Json
fun main() {
embeddedServer(Netty, port = SERVER_PORT, host = SERVER_HOST) {
install(Krpc)
routing {
rpc("/order") {
rpcConfig {
serialization { json(Json) }
}
registerService<OrderPlacement> { ctx ->
NoOpOrderPlacementProcessor(ctx)
}
}
}
}.start(wait = true)
}
embeddedServer
를 사용해 Ktor 서버 구성Krpc
는 kotlinx.rpc
에서 제공하는 Ktor 플러그인으로, RPC 통신을 처리하는 데 필요한 기능을 제공registerService<T>
는 특정 서비스 인터페이스(OrderPlacement
)를 구현하는 객체를 등록OrderPlacement
)의 구현체(NoOpOrderPlacementProcessor
)를 호출하여 요청을 처리val httpClient = HttpClient {
install(WebSockets)
install(Krpc)
}
val stup = httpClient.rpc {
url {
host = "localhost"
port = 8080
encodedPath = "/order"
}
rpcConfig {
serialization { json() }
}
}.withService<OrderPlacement>()
val orderLines = listOf(OrderPlacement.OrderLine(beverageName = "ESPRESSO", quantity = 1))
val orderId = stup.placeOrder(orderLines)
HttpClient
를 사용해 서버와 통신httpClient.rpc { ... }
는 클라이언트가 서버의 특정 RPC 엔드포인트에 연결하도록 설정withService<T>()
.withService<OrderPlacement>()
는 클라이언트 측에서 사용할 서비스 스텁(stub)을 생성kotlinx.rpc
는 Kotlin Multiplatform 프로젝트에서 쉽게 사용할 수 있도록 설계되었다.kotlinx.rpc
는 HTTP, WebSocket 등 다양한 전송 프로토콜을 지원하며, 사용자는 전송 방식의 세부 사항을 신경 쓰지 않아도 된다.kotlinx.serialization
, 바이너리 포맷, WebSocket 등을 활용하여 경량화되고 빠른 RPC 통신을 제공References