Introduction to RPC, Principles and examples

Source: Internet
Author: User

RPC (remote Procedure call, long-distance procedure calls) is built on the socket, and for an analogy, the main program running on one machine can invoke the prepared subroutine on the other machine, just like LPC (local procedure Call). The lower the level, the more complex the code, the greater the flexibility, the higher the efficiency, the higher the abstraction, the simpler the code, and the less efficient . The difference between socket and RPC illustrates this again. In traditional programming concepts, the process is done locally by the programmer, and can only be confined to a piece of code that runs locally, that is, the running relationship between its main program and the process is a local call relationship . Therefore, this kind of structure is unable to adapt to the actual demand today with the development of the network.

RPC Benefits:

1 Make full use of the resources of other hosts on the network (e.g. CPU, memory, etc.)

2 increase the degree of sharing of the code between entities and make full use of the host resources.

With RPC, we can take advantage of non-shared-memory multi-processor environments, such as multiple workstations connected over a local area network, so you can easily distribute your applications across multiple workstations , as if the application were running on a multiprocessor computer. You can easily realize the process code sharing , improve the utilization of system resources, can also be a large number of numerical processing operations on the processing capacity of the system to run , thereby reducing the burden on the front-end machine.

RPC, as a general method of C/s development, is efficient and reliable. But the basic principle of the RPC method is to ignore the specifics of the communication with the simplicity of the module invocation , so that the programmer does not care about the communication protocol between C/S. Focus on the implementation process. This determines that the RPC-generated communication packets cannot be the most appropriate approach for each application, and that the same valid data is transferred, compared to the socket method, and that RPC consumes more network bandwidth.
RPC is implemented on the basis of a socket, which requires more network and system resources than a socket. In addition, while optimizing the program, the programmer can directly modify the Rpcgen generated by the puzzling source program, But for RPC, which is designed to be highly efficient, the simplicity of the acquisition is greatly weakened.

The structure principle of RPC and its calling mechanism

As mentioned above, RPC is actually a C/s programming mode, a bit like the C/S Socket programming mode, but it is more layer than it . When we set up the RPC service, the client's invocation parameters pass through the underlying RPC transport channel, either UDP or TCP (or ti-rpc-independent), and go to the appropriate RPC application server based on the destination address provided before the transfer and the RPC upper application number. And the client is waiting until an answer is received or the time out timeout is signaled. When the server-side obtains the request message, it performs the appropriate operation and returns the result to the client, based on the instance entry address that tells the RPC system when the RPC is registered.

When an RPC call is finished, the corresponding thread sends the corresponding signal, and the client program continues to run.

In this process, a remote procedure has three elements that are uniquely identified: The program number, the version number, and the procedure number.

A program number is a remote procedure that distinguishes a set of related and unique processes. A program can have one or several different versions, and each version of the program contains a series of processes that can be called remotely, through the introduction of the version, so that the different versions of RPC can provide services at the same time. Each version contains a number of procedures that are available for remote invocation, each with its own unique procedure number.

RPC Call Classification

RPC calls are divided into the following two types:

    1. Synchronous invocation
      The client waits for the call execution to complete and returns the result.
    2. asynchronous invocation
      The client does not have to wait for the result to return after the call, but can still get the return result by callback notification. If the client does not care about invoking the return result, it becomes a one-way asynchronous call, and one-way invocation does not return results.

The distinction between asynchronous and synchronous is whether to wait for the service side to finish and return the results.

RPC Fabric Disassembly

As shown in.

The RPC server exports the (export) remote interface method through Rpcserver, and the client rpcclient to introduce the (import) remote interface method. The client side calls the remote interface method like the local method, the RPC framework provides the proxy implementation of the interface, and the actual invocation is delegated to the proxy rpcproxy. The agent encapsulates the invocation information and transfers the call to the Rpcinvoker to actually execute. The client's rpcinvoker through the connector Rpcconnector to maintain the channel Rpcchannel with the server, and uses RpcProtocol to execute the Protocol encoding (encode) and send the encoded request message through the channel to the service party.

The RPC service-side sink Rpcacceptor receives a call request from the client and also uses RpcProtocol to perform protocol decoding (decode). The decoded invocation information is passed to the Rpcprocessor to control the processing of the call procedure, and then the delegate calls to Rpcinvoker to actually execute and return the result of the call.

RPC Component Responsibilities

We have further disassembled the various components of the RPC implementation structure, and we describe in detail the division of responsibilities for each component below.

      1. Rpcserver
        Responsible for exporting the Remote Interface (export)
      2. Rpcclient
        The proxy implementation that is responsible for importing (import) the remote interface
      3. RpcProxy
        Proxy implementations of remote interfaces
      4. Rpcinvoker
        Client-side implementation: Responsible for encoding call information and sending call requests to the service party and waiting for the call result to return
        Service-Side implementation: Responsible for invoking the specific implementation of the server-side interface and returning the result of the call
      5. RpcProtocol
        Responsible for protocol compilation/decoding
      6. Rpcconnector
        Responsible for maintaining the connection channel between the client and the service party and sending the data to the service party
      7. Rpcacceptor
        Responsible for receiving client requests and returning request results
      8. Rpcprocessor
        Responsible for controlling the call process in the service side, including managing the call thread pool, time-out, etc.
      9. Rpcchannel
        Data transmission Channel
RPC Implementation Analysis

After further dismantling the components and dividing the responsibilities, here is an example of implementing the RPC framework conceptual model in the Java platform, in detail to analyze the factors that need to be considered in the implementation.

Export Remote Interface

Exporting a remote interface means that only the exported interface can be called remotely, and an interface that is not exported cannot. The code snippet for exporting an interface in Java might look like this:

Demoservice Demo   =new...; Rpcserver   =new...; Server.export (Demoservice. class, demo, options);

We can export the entire interface, or we can only export some methods in the interface at a finer granularity, such as:

// Only the method Server.export (Demoservice ) that is signed as Hi (String s) in Demoservice is exported .  Class, demo, "Hi", newclass<?>[] {String.  Class}, Options);

In Java there is a more special call is polymorphic , that is, an interface may have multiple implementations, then the remote invocation of which is called exactly? The semantics of this local invocation are implicitly implemented by the reference polymorphism provided by the JVM, and for RPC, cross-process calls cannot be implicitly implemented. If the previous Demoservice interface has 2 implementations, you need to specifically tag different implementations when exporting the interface, such as:

Demoservice Demo   =new...;D emoservice demo2  =new...; Rpcserver   =new...; Server.export (Demoservice. class , demo, options); Server.export ("Demo2", Demoservice. class, Demo2, Options);

The above Demo2 is another implementation, we mark it as Demo2 to export, then the remote call also need to pass the token to invoke the correct implementation class, which solves the semantics of the polymorphic call.

Import the remote interface with the client Agent

The import is relative to the export remote interface, in order for the client code to be able to invoke a method or procedure definition that must obtain the remote interface. At present, most of the cross-language platform RPC framework uses code generator to generate stub code based on the IDL definition, in this way the actual import process is done through the coding generator at compile time. Some of the cross-lingual platform RPC frameworks I've used, such as Corbar, WebService, ICE, and Thrift, are all of these ways.

The way code is generated is an inevitable choice for cross-language platform RPC frameworks, and RPC for the same language platform can be implemented through shared interface definitions. The code snippet for importing an interface in Java might look like this:

Rpcclient client =new= Client.refer (demoservice.  Class);d Emo.hi ("How is?");

Import is a keyword in Java, so we use refer to express the meaning of the import interface in the code snippet. The import method here is essentially a code generation technique, but it is generated at run time, which is more concise than the code generation at the static compile time. Java provides at least two techniques to provide dynamic code generation, one is the JDK dynamic agent, and the other is bytecode generation. Dynamic proxies are easier to use than bytecode generation, but the dynamic proxy approach is less performance-generated than direct bytecode generation, and bytecode generation is much worse in code readability. The tradeoff between the two is that it is more important for individuals to sacrifice some performance to gain code readability and maintainability.

Protocol encoding and decoding

The client agent needs to encode the invocation information before initiating the call, which takes into account what information needs to be encoded and in what format to be transmitted to the server to allow the server to complete the call. For efficiency reasons, the less information you encode, the better (less data is transmitted), and the simpler the coding rule is, the better (and the more efficient). Let's start by looking at what we need to code:

Call encoding
    1. Interface method
      Include interface name, method name
    2. Method parameters
      Include parameter type, parameter value
    3. Call Properties
      Includes calling property information, such as calling attachment implicit arguments, calling time-outs, and so on
return encoding
    1. return results
      The return value defined in the interface method
    2. Return code
      Exception return code
    3. Return exception information
      Calling exception information

In addition to these necessary invocation information, we may need some meta-information to facilitate program decoding and possible future extensions. In this way our code message is divided into two parts, part of the meta-information, and the other part is the necessary information to invoke. If you design an RPC protocol message, the meta-information is placed in the protocol message header, and the necessary information is placed in the protocol message body. The following is a conceptual format for RPC protocol message design:

Message header

    • Magic: Protocol magic number, for decoding design
    • Header size: Protocol header length, for extended design
    • Version: Protocol versions, for compatible designs
    • ST: type of message body serialization
    • HB: Heartbeat message marker for long connection transmission layer heartbeat design
    • OW: One-way message flag,
    • RP: Response message token, pail bit default is request message
    • Status code: Response message State Code
    • Reserved: reserved for byte alignment
    • Message ID: Msg ID
    • Body size: Message body length
Message body

Using serialized encoding, the following format is common

    • XML: such as Webservie SOAP
    • JSON: such as Json-rpc
    • Binary: As thrift; Hession; Kryo, etc.

The format is determined after the codec is simple, concerned about the message because the length of the head must be so we compare the body of the serialization method. Serialization we care about three areas:

    1. The more efficient the serialization and deserialization, the faster the better.
    2. The byte length after serialization, the smaller the better.
    3. serialization and deserialization compatibility, interface parameter object if the field is added, whether it is compatible.

Above these three points is sometimes the fish and bear paw can not have, which involves the specific serialization library implementation details, not in this article further analysis.

Transfer Service

After the protocol is encoded, it is natural to transfer the encoded RPC request message to the service party after the service party executes and returns the result message or acknowledgment message to the client. The application scenario of RPC is essentially a reliable request-reply message flow, similar to HTTP. Therefore, the choice of long-connection TCP protocol is more efficient, unlike HTTP is at the protocol level we define a unique ID for each message, so it is easier to reuse the connection.

With long connections, the first question is how many root connections are needed between the client and server? In fact, single-connection and multi-connection in the use of no difference, for the low data transmission of the application type, a single connection is basically enough. The biggest difference between single-and multi-connection is that each connection has its own private send and receive buffers, so a large amount of data can be distributed over different connection buffers for better throughput efficiency. So, if your data transfer volume is not enough to keep a single-connected buffer saturated, then using multiple connections does not create any noticeable elevation, but increases the overhead of connection management.

The connection is initiated and maintained by the client side. If the client and server are directly connected, the connection is generally uninterrupted (except for physical link failures, of course). If the client and server connections are connected through some load relay devices, it is possible that these intermediate devices will be interrupted when the connection is inactive for a period of time. In order to maintain connectivity it is necessary to periodically send heartbeat data for each connection to maintain the connection uninterrupted. The heartbeat message is an internal message used by the RPC framework library, and there is a dedicated heartbeat bit in the previous protocol header structure that is used to mark the heartbeat message, which is transparent to the business application.

Execute call

What the client stub does is simply encode the message and transfer it to the service party, and the actual invocation process takes place on the service side. Server stub from the previous structure of the disassembly we subdivide the rpcprocessor and rpcinvoker two components, one is responsible for controlling the call process, one responsible for the real call. Here we also take the implementation of these two components in Java as an example to analyze what they need to do?

dynamic interface calls to implement code in Java are now generally invoked through reflection . In addition to the native JDK's own reflection, some third party libraries provide better-performing reflection calls, so rpcinvoker is the implementation detail that encapsulates the reflection invocation.

What are the factors that need to be considered in the control of the calling process, and what rpcprocessor need to provide to invoke the control service? Here are some ideas to enlighten:

    1. Efficiency improvement
      Each request should be executed as soon as possible, so we cannot create threads for each request to execute and need to provide a thread pool service .
    2. Resource Isolation
      When we export multiple remote interfaces, how to prevent a single interface call from occupying all of the thread resources and throwing other interfaces to execute blocking.
    3. Timeout control
      When an interface executes slowly, and the client side has timed out the wait, the server-side thread continues to execute at this point, which makes no sense.
RPC Exception Handling

No matter how RPC tries to disguise remote calls as local calls, they are still very different, and there are some exceptions that are never encountered when called locally. Before we say exception handling, let's compare some of the differences between local calls and RPC calls:

    1. The local call is bound to execute, and the remote call does not necessarily, and the calling message may not be sent to the service party because of network reasons.
    2. A local call throws only the exception that is declared by the interface, and the remote call also runs out of other exceptions when the RPC framework runs.
    3. The performance of local and remote calls can vary greatly, depending on the proportion of RPC intrinsic consumption.

It is these differences that determine the need for more consideration when using RPC. When calling the remote interface to throw an exception, the exception could be a business exception, or it could be a run-time exception thrown by the RPC framework (such as a network outage, etc.). A business exception indicates that the service party has made a call, possibly due to a failure to perform properly for some reason, while the RPC runtime exception may not be executed at all, and the exception handling policy for the caller naturally needs to be differentiated.

Because RPC inherently consumes several orders of magnitude higher than local calls, the intrinsic consumption of local calls is nanosecond, while the intrinsic consumption of RPC is at the millisecond level. It is not appropriate for too lightweight computing tasks to export the remote interface is serviced by a separate process, and it is worthwhile to export the service to the remote interface only if the time spent on the computation task is much higher than the intrinsic consumption of RPC.

Summarize

At this point we present a conceptual framework for RPC implementations and detailed analysis of some of the implementation details that need to be considered. No matter how elegant the concept of RPC, but "there are still a few snakes in the grass hidden", only a deep understanding of the nature of RPC, can be better applied.

Introduction to RPC, Principles and examples

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.