Client-Server model: request, reply
server always on, and powerful
client is personal computer
workstation (client) request service from server
Pear-to-pear: not-client server model
RPC: abstract away the network
handles message format, sending, receiving, timeout
make remote procedure calls as close to local function call as possible
RPC Package in Golang: (assume you have Golang on both side)
Provides access to the exported methods of an object across a network or other I/O connection.
A server registers an object, making it visible as a service with the name of the type of the object.
After registration, exported methods of the object will be accessible remotely.
A server may register multiple objects (services) of different types but it is an error to register multiple objects of the same type.
RPC Steps:
client procedure -> client stub
client stub -> client OS
client OS -> server OS
server OS -> server stub
server stub -> server procedure
server procedure -> server stub
server stub -> server OS
server OS -> client OS
client OS -> client stub
client stub -> client procedure
Serialization, pickle, marshals: transform structure data to bytes
Client stub:
serialize arguments into machine-independent format
send request to server
wait for response
un-serialize result and return to caller
Server stub:
un-serialize arguments
call procedure
serialize result
reply
It is like ABI (Application binary interface)-Encoded Constructor Arguments
htonl()
means "host to network byte order, long" (big-endian is standardized to deal with cross-platform variance)
runtime: a process that runs in the background to provide service to other service
Interface Definition Language (IDL): a language to describe interface.
With RPC, though. You can't pass everything. Pointers are problematic to pass to server. So pure functions are good in RPC.
Shallow integration:
user define how to format data
user register functions and invoke methods
Deep integration:
automatic serialization based on nested types, but it is programming language dependent
automatically register functions in an object
Challenges of RPC
memory access
latency
failure: communication failure, machine failure
It is sometimes impossible to distinguish machine failure from communication failures. It is a decision to and not to break transparency and make failure visible.
There are choices to tolerate network failure: (semantics)
Exactly once: impossible due to failure
At Least once: server is memoryless, server's application is idempotent (idempotent operations)
At Most once: message de-duping before go into server application (either zero or once), the client may or may not only send once. However, this is usually implemented as a fire-and-forget strategy like heartbeat.
You might also want to design a RPC in distributed filesystem or on distributed shared memory?
In reality, you either use
RPC
, orRESTful
, orGraphQL
. You typically decide on usinggRPC
orhttp
.
gRPC: Google's RPC that is also language agnostic.
The underlying gRPC framework handles all the complexities that are normally associated with making RPCs, enforcing strict service contracts:
data serialization
network AND communication
authentication
access control
observability
gRPC also pulls features:
protocol buffers: takes care of performant marshaling/serialization/pickling
HTTP/2: enables streaming, bi-directional communication, flow control, etc
Why not RESTful:
test-based message is slow
fewer error when deploy, code can't be mechanically checked
no type check
Table of Content