Remote Procedure Call (RPC). A node requests services provided by another node
To understand remote calls, it is essential to understand local calls first
A local call
In our original singleton application project all the requests were local calls. For example: to modify a student’s information, the foreground HTTP requests the back-end interface first, calls the function specification provided by the current project for parameter transmission, and finally realizes the call modification function
The remote invocation
In the process of appeal, the local HTTP requests the current project to improve student modify functions, but the real change function service running in another project, that is to say you true to access services in another host, you are in the current request interface function change is actually involved RPC process of a call to the local request call transfer, The local service then sends a data request to another host and receives the data return from the server. The current request is equivalent to the Client.
In the design of microservices, if A service A accesses service B under another Module, it can use HTTP REST to transfer data and carry out serialization and deserialization operations between the two services, and service B returns the execution results.
Why not just Http
When you look at the remote call process above, you might wonder, why doesn’t the client directly remote the HTTP request server? There are two main reasons: 1.HTTP is completed in the application layer, and the cost of the whole communication is high. Remote procedure calls are directly made based on TCP, and data transmission is completed in the TCP layer of the transport layer, which is more suitable for scenarios requiring high efficiency. The underlying implementation is more complex than REST. 2. Because of the adoption of RPC, various vendors follow the RPC specification to adapt to different platforms, and the specific call transmission, which serialization technology is chosen by them, so there are many RPC frameworks, such as Dubbo
The following will be attached with the process of custom RPC implementation source code, it is recommended that you do not understand the Socket IO network to understand these basic concepts
The Server side
Business logic code
package com.demo.provider;
import rpcservice.RpcRequest;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.Socket;
public class ProcessorHandler implements Runnable{
private Socket socket;
private Object service;
public ProcessorHandler(Socket socket, Object service) {
this.socket = socket;
this.service = service;
}
@Override
public void run(a) {
ObjectOutputStream objectOutputStream = null;
ObjectInputStream objectInputStream = null;
try {
// Obtain the input flow of the client request and related parameter information
objectInputStream = new ObjectInputStream(socket.getInputStream());
// Convert the flow information to objects
RpcRequest request = (RpcRequest)objectInputStream.readObject();
// Execute business logic
Object result =invoke(request);
// Return result to client
objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
objectOutputStream.writeObject(result);
objectOutputStream.flush();
} catch (IOException | ClassNotFoundException | NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}finally {
if(objectInputStream! =null) {try {
objectInputStream.close();
} catch(IOException e) { e.printStackTrace(); }}if(objectOutputStream! =null) {try {
objectOutputStream.close();
} catch(IOException e) { e.printStackTrace(); }}}}private Object invoke(RpcRequest request) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
// Execute the method through reflection
String className = request.getClassName();
Object[] parameters = request.getParameters();
Class[] types = new Class[parameters.length];
for (int i = 0; i < parameters.length; i++) { types[i]=parameters[i].getClass(); } Class<? > aClass = Class.forName(className); Method method = aClass.getMethod(request.getMethodName(),types); Object result = method.invoke(service, parameters);returnresult; }}Copy the code
The Client side
JDK dynamic proxy
Client Service logic execution
package com.rpc.client;
import rpcservice.RpcRequest;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
public class RpcNetTransport {
private String host;
private int port;
public RpcNetTransport(String host, int port) {
this.host = host;
this.port = port;
}
public Object send(RpcRequest request){
Object result = null;
ObjectInputStream objectInputStream = null;
ObjectOutputStream objectOutputStream = null;
try {
// The client requests the remote server
Socket socket = new Socket(host, port);
// Transfer data
objectOutputStream = new ObjectOutputStream(socket.getOutputStream());
objectOutputStream.writeObject(request);
objectOutputStream.flush();
// Receive the parameters returned by the Server
objectInputStream = new ObjectInputStream(socket.getInputStream());
result = objectInputStream.readObject();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}finally {
if(objectInputStream! =null) {try {
objectInputStream.close();
} catch(IOException e) { e.printStackTrace(); }}if(objectOutputStream! =null) {try {
objectOutputStream.close();
} catch(IOException e) { e.printStackTrace(); }}}returnresult; }}Copy the code