First, RPC introduction
RPC, called remote Procedure call, is a computer communication protocol. It allows the remote service to be invoked just like the local service. It can be implemented in a different way. such as RMI (remote method call), Hessian, Http invoker, and so on. In addition, RPC is language-independent. RPC schematic
As shown in the figure above, assuming that Computer1 is calling the Sayhi () method, the call to the Sayhi () method for Computer1 is like invoking a local method, calling –> return. However, it can be seen from subsequent calls that Computer1 calls the Sayhi () method in Computer2, RPC masks the underlying implementation details, so that the caller does not need to pay attention to network communications, data transmission and other details. II. Implementation of RPC framework
The core principle of RPC is described above: RPC enables local applications to invoke processes (services) in the server simply and efficiently. It is mainly used in distributed systems. such as the IPC component in Hadoop. But how to implement an RPC framework.
Think from the following aspects, for reference only:
1. Communication model: Assuming that the communication is a machine and B machine, there is a communication model between A and B, which is generally based on bio or NiO in Java;.
2. Process (service) Positioning: the use of a given means of communication, and determine the IP and port and method name to determine the specific process or method;
3. Remote Proxy object: The locally invoked method (service) is actually the local proxy for the remote method, so a remote proxy object may be required, and for Java, the remote proxy object can be implemented using Java dynamic object, encapsulating the invocation of the remote method call;
4. Serialization, the object name, method name, parameters, and other object information network transmission needs to be converted into binary transmission, here may require different serialization technology scenarios. such as: Protobuf,arvo and so on. Three, Java implementation RPC Framework
1, the realization of technical solutions
The following uses the original scheme to implement the RPC framework, using socket communication, dynamic Proxy and reflection and Java native serialization.
2. RPC Framework Architecture
The RPC schema is divided into three parts:
1 service provider, run on the server side, provide service interface definition and service implementation class.
2 Service Center, running on the server side, is responsible for the local service to be published as a remote service, the management of remote services, provided to service consumers to use.
3 service consumer, run on the client, invoke remote service via remote proxy object.
3, Concrete realization
The service provider interface is defined and implemented with the following code:
Public interface HelloService {
string Sayhi (string name);
}
Helloservices Interface Implementation class:
public class Helloserviceimpl implements HelloService {public
string Sayhi (string name) {return
"Hi," + name;
}
}
Service Center code implementation, the code is as follows:
Public interface Server {public
void Stop ();
public void Start () throws IOException;
public void register (class Serviceinterface, class Impl);
public boolean isrunning ();
public int getport ();
}
Service Center Implementation class:
public class Servicecenter implements Server {private static Executorservice executor = Executors.newfixedthreadpool (
Runtime.getruntime (). Availableprocessors ());
Private static final hashmap<string, class> serviceregistry = new hashmap<string, class> ();
private static Boolean isrunning = false;
private static int port;
public servicecenter (int port) {this.port = port;
public void Stop () {isrunning = false;
Executor.shutdown ();
public void Start () throws IOException {ServerSocket server = new ServerSocket ();
Server.bind (New Inetsocketaddress (port));
SYSTEM.OUT.PRINTLN ("Start Server"); try {while (true) {//1. A TCP connection that listens to a client, encapsulates it as a task, and is executed by the thread pool Executor.execut
E (New Servicetask (Server.accept ()));
finally {server.close (); } public void register (Class serviceinterface, ClasS impl) {serviceregistry.put (Serviceinterface.getname (), impl);
public boolean isrunning () {return isrunning;
public int Getport () {return port;
private static class Servicetask implements Runnable {Socket clent = null;
Public Servicetask (Socket client) {this.clent = client;
public void Run () {ObjectInputStream input = null;
ObjectOutputStream output = null; try {//2. Deserializes the code stream sent by the client into an object, reflection invokes the service implementation, gets the execution result input = new ObjectInputStream (clent.getinputs
Tream ());
String serviceName = Input.readutf ();
String methodname = Input.readutf ();
Class<?>[] Parametertypes = (class<?>[]) input.readobject ();
object[] arguments = (object[]) input.readobject ();
Class ServiceClass = Serviceregistry.get (serviceName); if (serviCeclass = = null) {throw new ClassNotFoundException (ServiceName + "not Found");
Method method = Serviceclass.getmethod (methodname, parametertypes);
Object result = Method.invoke (Serviceclass.newinstance (), arguments);
3. Deserialize the execution result and send it to the client via the socket output = new ObjectOutputStream (Clent.getoutputstream ());
Output.writeobject (result);
catch (Exception e) {e.printstacktrace ();
Finally {if (output!= null) {try {output.close ();
catch (IOException e) {e.printstacktrace ();
} if (input!= null) {try {input.close ();
catch (IOException e) {e.printstacktrace (); }
} if (Clent!= null) {try {clent.close ();
catch (IOException e) {e.printstacktrace (); }
}
}
}
}
}
Remote proxy object for client:
public class Rpcclient<t> {public static <T> T getremoteproxyobj (final class<?> serviceinterface, F Inal inetsocketaddress addr) {//1. Converts a local interface call into a dynamic proxy for JDK, which implements the remote call return (T) Proxy.newproxyinstance of an interface in a dynamic proxy (
Serviceinterface.getclassloader (), New Class<?>[]{serviceinterface}, new Invocationhandler () {
public object invoke (object proxy, Method method, object[] args) throws Throwable {
Socket socket = NULL;
ObjectOutputStream output = null;
ObjectInputStream input = null;
try {//2. Create a socket client that connects the remote service provider socket = new socket () according to the specified address;
Socket.connect (addr); 3. Encode the interface class, method name, and parameter list required by the remote service invocation to the service provider output = new ObjectOutputStream (socket.getoutputstream
()); Output.writeutf (Serviceinterface.getname ());
Output.writeutf (Method.getname ());
Output.writeobject (Method.getparametertypes ());
Output.writeobject (args);
4. Synchronous blocking waits for the server to return the reply, gets the reply to return input = new ObjectInputStream (Socket.getinputstream ());
return Input.readobject ();
finally {if (socket!= null) socket.close ();
if (output!= null) output.close ();
if (input!= null) input.close ();
}
}
}); }
}
Finally for the test class:
public class Rpctest {public
static void Main (string[] args) throws IOException {
new Thread (new Runnable () {
public void Run () {
try {
Server serviceserver = new Servicecenter (8088);
Serviceserver.register (Helloservice.class, helloserviceimpl.class);
Serviceserver.start ();
} catch (IOException e) {
e.printstacktrace ();}}}
). Start ();
HelloService service = Rpcclient.getremoteproxyobj (Helloservice.class, new inetsocketaddress ("localhost", 8088));
System.out.println (Service.sayhi ("Test"));
}
Run Result:
Regeist service HelloService
start server
Hi, test
Iv. Summary
RPC essence is the message processing model, RPC masks the details of communication between the underlying different hosts, making the process call remote services like a local service.
v. Areas that can be improved
The simple RPC framework implemented here is developed using the Java language, is highly coupled to the Java language, and the socket used in the communication mode is based on the bio, Io is inefficient, and Java native serialization mechanism takes up too much memory and is inefficient. You can consider improvements from the following methods.
You can use the RPC framework based on JSON data transfer;
You can use NIO or use Netty directly instead of bio implementations;
Use open source serialization mechanisms, such as Hadoop Avro and Google Protobuf;
Service registration can be managed using zookeeper to make applications more stable.
————————————————————————————————————————————————— – Java Architect Project Combat, high concurrency cluster distributed, large data high availability video tutorials, total 760G
Download Address:
https://item.taobao.com/item.htm?id=555888526201
01. High-level architect 42 Phases
02.Java Advanced System Training Architecture Course 148 hours
03.Java Senior Internet Architect Course
04.Java Internet Architecture Netty, Nio, Mina, etc.-Video tutorials
05.Java Advanced Architecture Design 2016 finishing-video tutorials
06. Architect Foundation, advanced film
07.Java Architect Required Linux Operation series courses
08.Java Advanced System Training Architecture Course 116 hours
+
Hadoop series tutorials, Java design patterns and data structures, Spring Cloud Micro service, Springboot Primer
—————————————————————————————————————————————————–