Remote Procedure Call (RPC) is a powerful technique used in computer networks and distributed systems to enable a program on one computer (the client) to execute code on a remote system (the server) as if it were a local procedure call. By abstracting the complexity of network communication, RPC simplifies the development of distributed applications by allowing developers to write code that looks like standard, local procedure calls.
How RPC works
Consider an example of online shop with the payment system for customers. When customer makes payment on online shop website, under the hood it sends request to a third-party service on another server that processes the payment card details.
When call is made to the payment service, the code that resides on the online shopping site makes an RPC call to the cardholder’s bank via the third-party payment processing service.
The pseudo code for such interaction might look like the following:
// Function to process payment during checkout
function processPayment(orderDetails, paymentInfo) {
// Prepare the payment request object with necessary details
paymentRequest = {
orderId: orderDetails.orderId,
amount: orderDetails.totalAmount,
currency: orderDetails.currency,
paymentMethod: paymentInfo.method, // e.g., 'CreditCard', 'PayPal'
cardNumber: paymentInfo.cardNumber,
cardExpiry: paymentInfo.cardExpiry,
cardSVC: paymentInfo.cardSVC,
billingAddress: paymentInfo.billingAddress,
customerEmail: orderDetails.customerEmail,
// Additional fields as required...
}
// Create an RPC client proxy to the payment processing service
paymentService = createRPCProxy("https://payment-service.com/api")
// Make the remote procedure call to process the payment
try {
// Invoke the 'processPayment' method on the payment service
paymentResponse = paymentService.processPayment(paymentRequest)
// Check the response status
if (paymentResponse.status == "Success") {
// Payment was successful
updateOrderStatus(orderDetails.orderId, "Paid")
sendConfirmationEmail(orderDetails.customerEmail)
displayMessage("Your payment was successful. Thank you for your purchase!")
} else {
// Payment failed
displayMessage("Payment failed: " + paymentResponse.errorMessage)
// Optionally, prompt the user to try again or use a different payment method
}
} catch (rpcError) {
// Handle any errors that occurred during the RPC call
displayMessage("An error occurred while processing your payment. Please try again later.")
logError(rpcError)
// Additional error handling as needed...
}
}
Making the RPC Call:
The call is made with
processPayment(paymentRequest)
as if it were a local function.The RPC mechanism handles serialization of
paymentRequest
and communication over the network (using JSON, XML, etc formats for data representation).
In detail the communication with payment service involves:
Core Concepts
Transparency: RPC aims to make the remote call appear identical to a local call from the programmer's perspective. This means handling data serialization, network communication, and error detection behind the scenes.
Client-Server Model: The architecture typically involves a client making a request to a server, which performs the desired operation and returns the result to the client.
Stubs and Skeletons:
Client Stub: Acts as a proxy for the client, responsible for packaging the procedure call into a message format suitable for transmission over the network (marshalling).
Server Skeleton: Receives the message on the server side, unpacks it (unmarshalling), and invokes the appropriate procedure.
Marshalling and Unmarshalling:
Marshalling: The process of converting procedure parameters into a standard format for transmission.
Unmarshalling: The reverse process, converting the received data back into a format usable by the server's procedure.
RPC Procedure
Procedure Call: The client invokes a procedure as if it were local.
Client Stub Processing: The client stub intercepts the call, marshals the parameters, and sends a message to the server.
Network Communication: The message is transmitted over the network using a communication protocol (e.g., TCP/IP).
Server Skeleton Processing: The server skeleton receives the message, unmarshals the parameters, and invokes the corresponding procedure on the server.
Execution and Response: The server executes the procedure and sends the result back through the skeleton.
Result Handling: The client stub receives the response, unmarshals the data, and returns it to the client application.
Types of RPC
Synchronous RPC: The client waits (blocks) until the server responds. This is the traditional form of RPC.
Asynchronous RPC: The client continues processing and can handle the server's response at a later time, improving concurrency and resource utilization.
Protocols and Implementations
ONC RPC (Open Network Computing RPC): Developed by Sun Microsystems, commonly used in UNIX systems.
DCE RPC (Distributed Computing Environment RPC): Developed by the Open Software Foundation, provides additional features like authentication and directory services.
XML-RPC and JSON-RPC: Use XML or JSON over HTTP for communication, making them suitable for web-based applications.
gRPC: An open-source RPC framework developed by Google, which uses HTTP/2 and Protocol Buffers for efficient communication.
Applications of RPC
Distributed Systems: Facilitates communication between different components in a distributed architecture.
Microservices: Enables services to communicate in a microservices architecture.
File Systems: NFS (Network File System) uses RPC for remote file operations.
Web Services: Underlying mechanism for many SOAP-based web services.
Advantages
Simplifies Development: Abstracts the complexity of network programming.
Interoperability: Allows systems written in different languages to communicate.
Modularity: Encourages a modular approach to system design.
Disadvantages
Latency and Network Issues: Network communication introduces latency and potential for failures.
Security Risks: Exposing procedures over a network can introduce security vulnerabilities.
Complex Debugging: Errors may occur in the network layer, making debugging more challenging.
Security Considerations
Authentication and Authorization: Ensuring only authorized clients can make RPC calls.
Encryption: Protecting data transmitted over the network using SSL/TLS.
Input Validation: Preventing injection attacks by validating input parameters.
Practice: Making an RPC call to a Service Running on EC2 Instance
This example demonstrates how to make a Remote Procedure Call from your local laptop to a service running on a remote AWS EC2 instance. It uses Python's built-in xmlrpc
library for simplicity. Example also provides Terraform code to provision the necessary AWS infrastructure, including the EC2 instance and networking components.
To learn more, checkout this repository:
https://github.com/Brain2life/terraform-cookbook/tree/main/example-rpc-call-to-ec2