Who can explain in simple language what is RPC framework?

Author: Hong Chuntao
link: https: //www.zhihu.com/question/25536695/answer/221638079
Source: know almost
copyrighted by the author. Commercial reprint please contact the author authorized, non-commercial reprint please indicate the source.

Not invited, a wave of strong answer. Let us talk about principles. Local procedure call RPC is to function as a local call to the same tune remote function. Before the study RPC, we take a look at how the tone of a local call. Suppose we want to call a function Multiply to calculate the result lvalue * rvalue of:. 1 int Multiply (int L, int R & lt) {
2 int Y = L * R & lt;
. 3 return Y;
. 4}
. 5
. 6 int lvalue. = 10;
. 7 int rvalue = 20 is;
. 8 = int l_times_r the Multiply (lvalue., rvalue);
Then the eighth row, we actually performs the following operations: lvalue and rvalue push into the Multiply function value, the value of the stack 10 and extraction 20, which impart l and 2 of the code to perform row r, l calculated * r, and the result of the presence of y y onto the stack, and then return the Multiply line 8, the return value extracted from the stack 200, and assignment to step 5 above is performed l_times_r local procedure call. (20,190,116 Note: The above steps are only illustrative of the principles often do in fact compiler optimization, parameters and return values ​​in the case of less directly store it in a register, without the need to push the process of popping even need. call to call, but do directly inline operation. Far principle, this 5-step is not a problem.) has brought new problems in the remote procedure call remote call, we need to perform the function body is on a remote machine that is, Multiply is executed in another process. This brings several new issues: Call ID mapping. Tell us how we have to call the remote machine Multiply, rather than the Add or FooBar it? In a local call, the function body is directly specified by the function pointer, we call Multiply, the compiler will automatically help us call it the appropriate function pointer. But in the long-distance call, the function pointer is not enough, because the address space of both processes are completely different. So, in the RPC, all functions must have its own an ID. This ID is the only certainty in all processes. The client when making remote procedure call, you must include this ID. Then we also need the client and server, respectively, to maintain a {function <-> Call ID} correspondence table. Both tables need not necessarily identical, but the same function as the corresponding Call ID must be the same. When a client needs a remote call, it will check this table, find the appropriate Call ID, and then pass it on to the server, the server also look-up table to determine the function of the client need to call, then perform the appropriate function code. Serialization and de-serialization. The client how the parameters passed to the function remote it? In a local call, we just need to arguments onto the stack, and then let yourself go function to read the stack on the line. But in the remote procedure call, the client with the server is a different process, not through memory to pass parameters. And sometimes the client and server are not using the same language (such as server-side use C ++, or Java client with Python). This time we need to put the client first argument turned into a byte stream, passed after the end of the service, then the byte-stream into a format they can read. This process is called serialization and de-serialization. Similarly, the value returned from the server may also require serialization deserialization process. network transmission. Long-distance calls are often used on the network, client and server are connected through a network. All data is transmitted over the network are required, and therefore there is a need for network transport layer. Network transport layer needs to parameter byte after the Call ID and serialized stream to the server, and then calls the serialized result back to the client. As long as both can be completed, it can be used as the transport layer. Thus, in fact it uses the protocol is not limited, to complete the transmission line. Although most RPC framework uses the TCP protocol, UDP but in fact can, and gRPC simply use HTTP2. Java Netty also belong to this layer of things. With these three mechanisms, RPC will be able to achieve the specific process is as follows: // Client-side After the ID parameter byte serialization and passed to the server, and then calls the result of then serialized back to the client. As long as both can be completed, it can be used as the transport layer. Thus, in fact it uses the protocol is not limited, to complete the transmission line. Although most RPC framework uses the TCP protocol, UDP but in fact can, and gRPC simply use HTTP2. Java Netty also belong to this layer of things. With these three mechanisms, RPC will be able to achieve the specific process is as follows: // Client-side After the ID parameter byte serialization and passed to the server, and then calls the result of then serialized back to the client. As long as both can be completed, it can be used as the transport layer. Thus, in fact it uses the protocol is not limited, to complete the transmission line. Although most RPC framework uses the TCP protocol, UDP but in fact can, and gRPC simply use HTTP2. Java Netty also belong to this layer of things. With these three mechanisms, RPC will be able to achieve the specific process is as follows: // Client-side
// int l_times_r = Call(ServerAddr, Multiply, lvalue, rvalue)

  1. This call will be mapped to a Call ID. It is assumed that when the string with the most simple method Call ID
  2. The Call ID, lvalue and rvalue serialization. Their values ​​may be directly packaged in binary form
  3. 2. The obtained data packet to ServerAddr, which requires the use of network transport layer
  4. Wait for the server to return results
  5. If the server call is successful, then the result will be deserialized, and assigns l_times_r

// Server-side

  1. Maintained locally a pointer to the function Call ID map call_id_map, can std :: map <std :: string, std :: function <>>
  2. Waiting for a request
  3. After obtaining a request packet to deserialize give Call ID
  4. By looking call_id_map give the corresponding function pointer
  5. After lvalue and rvalue deserialized Multiply function in a local call, the results obtained
  6. After the sequence of results returned by the network to the Client
    so to achieve a RPC framework, in fact, simply press the above processes to achieve basically completed. Wherein: Call ID mapping function strings may be used directly, you can also use the integer ID. General mapping table is a hash table. Serialization deserialization can write your own, or you can use Protobuf FlatBuffers like. Libraries can write their own transmission network socket, or use asio, ZeroMQ, Netty and the like. Of course, there is also some of the details can be filled, such as how to deal with network errors, how to prevent attacks, how do flow control, and so on. But with more than architecture, which can be sustained added. Finally, we are interested can look at himself in a small but excellent RPC library tinyrpc (hjk41 / tinyrpc), understanding how it works for RPC is very good.
Published 26 original articles · won praise 0 · Views 8158

Guess you like

Origin blog.csdn.net/lynchyueliu/article/details/104940636