What is RPC?

Baidu Baike explains: “Remote Procedure Call (RPC) — Remote Procedure Call, which is a protocol for requesting services from Remote computer programs over the network without understanding the underlying network technology.”

REST Vs RPC

In microservices, there are two types of communication between services: RESTful and RPC. But REST and RPC do not fall into the same category of comparison. Rest defines a design style and development approach, while RPC defines a protocol.

Different categories

REST is short for Representational State Transfer, which describes Representational State Transfer. Representational State Transfer is a snapshot of instantaneous Representational State data, including the content and representation format of resource data, such as XML and JSON.

REST is a software architecture style. A typical application of this style is HTTP. It is widely favored by developers because of its simplicity and strong scalability.

Remote Procedure Call Protocol (RPC) enables a client to Call a server’s service (method) just as it calls a local service (method).

RPC is a TCP-based communication protocol. It should not be discussed together with REST, but REST is the most popular API design standard for Internet applications. In a sense, When we say REST we really mean HTTP.

Different ways of use

In terms of usage, the HTTP interface only cares about the service provider, not how the client invokes it. The interface only needs to ensure that the corresponding data is returned when the client calls it. RPC requires the client interface to be consistent with the server interface.

  • REST is when the server writes the method, and the client doesn’t know the method. The client just wants to get the resource, so it makes an HTTP request, and the server receives the request and goes through a series of routes based on the URI to the method
  • PRC is the server to provide a good method to the client to call, the client needs to know the server specific class, specific method, and then call it directly like calling the local method.

Object orientation is different

By design, RPC, known as remote procedure calls, is method-oriented, and REST: The so-called Representational State Transfer is resource-oriented

Different serialization protocols

An interface call usually consists of two parts, serialization and communication protocol.

Communication protocols, as mentioned above, REST is based on HTTP, while RPC can be based on TCP/UDP or HTTP.

Common serialization protocols include JSON, XML, hession, Protobuf, Thrift, text, bytes, etc. REST usually uses JSON or XML, while RPC uses JSON-RPC or XML-RPC.

application

  • REST interfaces are more standardized and require high adaptability. It is recommended that all external interfaces be REST (there are exceptions, such as Zabbix, whose API is based on JSON-RPC 2.0 protocol). For each module inside the component, RPC can be selected. One is that it does not need to spend too much energy to develop and maintain multiple SETS of HTTP interfaces, and the call performance of an RPC is better
  • From the point of view of performance, HTTP itself provides rich state functions and extension functions, but also because HTTP provides too many functions, the network transmission, need to carry more information, from the point of view of performance, relatively inefficient. However, only the data related to the service content is transmitted on the RPC service network, resulting in smaller data transmission and higher performance.

Python implementation

Python3 comes with XMLRPC, and third parties provide JSONRPC and ZerorPC.

xmlrpc

  • Server (single thread)
from xmlrpc.server import SimpleXMLRPCServer
from xmlrpc.server import SimpleXMLRPCRequestHandler

class RequestHandler(SimpleXMLRPCRequestHandler):
    rpc_paths = ('/RPC2', '/RPC3')
    
class Calculate:
    def add(self, x, y):
        return x + y

    def multiply(self, x, y):
        return x * y

    def subtract(self, x, y):
        return abs(x - y)

    def divide(self, x, y):
        return x / y


with SimpleXMLRPCServer(('localhost', 8000),
                        requestHandler=RequestHandler) as server:
    server.register_introspection_functions()
    server.register_function(pow)


    @server.register_function(name='add1')
    def adder_function(x, y):
        return x + y + 1


    @server.register_function
    def mul(x, y):
        return x * y


    server.register_instance(Calculate())

    server.serve_forever()
Copy the code
  • client
import xmlrpc.client

server = xmlrpc.client.ServerProxy("http://localhost:8000")

print(server.add(1, 2))
print(server.add1(1, 2))
print(server.pow(1, 2))
print(server.multiply(1, 2))
print(server.system.listMethods())

Copy the code
  • Server (Multi-threaded)
from socketserver import ThreadingMixIn class ThreadXMLRPCServer(ThreadingMixIn, SimpleXMLRPCServer): Pass # multithreaded class MultRequestHandler (SimpleXMLRPCRequestHandler) : Rpc_paths = ('/MRPC',) # Multithreading with ThreadXMLRPCServer(('localhost', 8001), requestHandler=MultRequestHandler, allow_none=True) as mserver: mserver.register_introspection_functions() mserver.register_multicall_functions() @mserver.register_function(name='add')  def madd(a, b): return a + b mserver.serve_forever()Copy the code
  • The output
## Server 127.0.0.1 - - [02/Feb/2021 10:21:14] "POST /RPC2 HTTP/1.1" 200-127.0.0.1 - [02/Feb/2021 10:21:14] "POST /RPC2 HTTP/1.1" 200-127.0.0.1 - - [02/Feb/2021 10:21:14] "POST /RPC2 HTTP/1.1" 200-127.0.0.1 - - [02/Feb/2021 10:21:14] "POST /RPC2 HTTP/1.1" 200-127.0.0.1 - - [02/Feb/2021 10:21:14 10:21:14] "POST /RPC2 HTTP/1.1" 200-127.0.0.1 - - [02/Feb/2021 10:21:14] "POST /RPC2 HTTP/1.1" 200 - ## 2 ['add', 'add1', 'divide', 'mul', 'multiply', 'pow', 'subtract', 'system.listMethods', 'system.methodHelp', 'system.methodSignature']Copy the code

jsonrpc

  • The installation
# python3
pip3 install jsonrpclib-pelix
Copy the code
  • Server (single thread)
The from jsonrpclib. SimpleJSONRPCServer import SimpleJSONRPCServer # single-threaded server = SimpleJSONRPCServer ((' localhost ' 8080)) server.register_function(lambda x, y: x + y, 'add') server.serve_forever()Copy the code
  • client
import jsonrpclib

server = jsonrpclib.Server("http://localhost:8080")
print(server.add(1, 2))
Copy the code
  • Server (Multi-threaded)
Import threadpool from jsonrpclib.threadpool import threadpool from jsonrpclib.threadpool between 0 and 10 threads pool = ThreadPool(max_threads=10, min_threads=0) # Don't forget to start it pool.start() # Setup the server server = SimpleJSONRPCServer(('localhost', 8080)) server.set_notification_pool(pool) # Register methods server.register_function(pow) server.register_function(lambda x, y: x + y, 'add') server.register_function(lambda x: x, 'ping') try: server.serve_forever() finally: # Stop the thread pool (let threads finish their current task) pool.stop() server.set_notification_pool(None)Copy the code
  • The output
# server 127.0.0.1 - - [02/Feb/2021 10:54:04] "POST/HTTP/1.1" 200 - # Client 3 Process Finished with exit code 0Copy the code

zerorpc

XMLRPC and JSONRPC are both a combination of HTTP and TCP. Zerorpc fully implements TCP and has higher performance than HTTP.

  • The installation
pip3 install zerorpc
Copy the code
  • server
import zerorpc class caculate(object): def hello(self, name): return 'hello, {}'.format(name) def add(self, x, y): return x + y def multiply(self, x, y): return x * y def subtract(self, x, y): return abs(x - y) def divide(self, x, y): Return x/y s = zerorpc.server (caculate()) s.bind(" TCP :// 0.0.0.00:4242 ") s.run()Copy the code
  • client
Import zerorpc c = zerorpc.client () c.onnect (" TCP ://127.0.0.1:4242") print(c.dd (1, 2))Copy the code

The performance test

Out of curiosity, test zerorPC and JsonRPC (single-threaded) cases and count the total usage time of each client loop 10,000 times.

  • jsonrpc
All time is  27.96554207801819
Copy the code
  • zerorpc
All time is  10.987850904464722
Copy the code

Zerorpc is more objective than JSONRPC.

reference

From 0 to 1: Fully understand RPC remote calls