Java implements a simple RPC framework

Source: Internet
Author: User
Tags static class

I. Introduction of RPC

RPC, called remote Procedure call, is a computer communication protocol. It allows the remote service to be called as if it were a local service. It can be implemented in different ways. such as RMI (remote method call), Hessian, Http invoker, and so on. In addition, RPC is language-independent.

Rpc

As shown, assuming that Computer1 calls the Sayhi () method, calling the Sayhi () method for Computer1 is like calling a local method, calling –> back. However, it can be seen from subsequent calls that Computer1 calls the Sayhi () method in Computer2, and RPC masks the underlying implementation details so that callers do not have to focus on the details of network communication, data transfer, and so on.

II. implementation of RPC framework

The core principle of RPC is described above:RPC enables local applications to easily and efficiently invoke processes (services) in the server. It is mainly used in distributed systems. such as the IPC components in Hadoop. But how do you implement an RPC framework?

Consider from the following aspects, for reference only:

1. Communication model: Suppose that the communication is between a machine and a B machine, a communication model between A and B, generally based on bio or NiO in Java;

2. Process (service) Positioning: Using a given communication method, with the determination of IP and port and method name to determine the specific process or method;

3. Remote Proxy object: A locally invoked method (service) is actually a local proxy for a remote method, so a remote proxy object may be required, and for Java, the remote proxy object can use Java's dynamic object implementation to encapsulate the invocation of a remote method;

4. Serialization, the object name, method name, parameters and other object information network transmission needs to be converted to binary transmission, here may require a different serialization technology scheme. such as: Protobuf,arvo and so on.

Third, Java implementation of RPC Framework 1, the implementation 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, running on the server side, provides service interface definitions and service implementation classes.

2) service Center, running on the server side, is responsible for publishing local services to remote services, management of remote services, provided to the service consumer use.

3) The service consumer, which runs on the client, invokes the remote service through the remote proxy object.

3. Concrete Realization

Service Provider Interface definition and implementation, the code is as follows:

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 (R    Untime.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. Listens for TCP connections to the client, encapsulates it as a task after receiving a TCP connection, executes executor.execute by the thread pool (n            EW 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's executor, gets the execution result input = new ObjectInputStream (clent.getinputstr                EAM ());                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 = Serviceclass.getmethod (MethodName, parametertypes);                Object result = Method.invoke (Serviceclass.newinstance (), arguments);                3. Deserialize the execution result, sent via socket to client 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, fi nal inetsocketaddress addr) {//1. Convert the local interface call to the dynamic proxy of the JDK and implement the remote call to the interface in the dynamic proxy return (T) proxy.newproxyinstance (ser                    Viceinterface.getclassloader (), New Class<?>[]{serviceinterface}, new Invocationhandler () { public object invoke (object proxy, Method method, object[] args) throws Throwable {Socke                        t socket = null;                        ObjectOutputStream output = null;                        ObjectInputStream input = null;                            try {//2. Create a socket client to connect the remote service provider socket = new socket () according to the specified address;                            Socket.connect (addr); 3. Encode the required interface class, method name, parameter list, and so on for the remote service call 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 an answer, and returns input = new ObjectInputStream (Socket.getinputstream ()) after obtaining an answer;                        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"));}    }
   

Operation Result:

Regeist service Helloservicestart Serverhi, test
Iv. Summary

RPC is essentially a message processing model, and RPC masks the details of the communication between the underlying hosts, allowing the process to invoke the remote service as if it were a local service.

Five, can improve the place

The simple RPC framework implemented here is developed using the Java language, which is highly coupled with the Java language, and the socket used for communication is based on bio, the IO efficiency is not high, and the Java Native serialization mechanism accounts for too much memory and is not running efficiently. There are several ways to consider improvements.

    1. Can adopt the RPC framework based on JSON data transmission;
    2. Can be implemented using NIO or directly using Netty instead of bio;
    3. Use open-source serialization mechanisms, such as Hadoop Avro and Google Protobuf;
    4. Service registration can be managed using zookeeper to make the application more stable.

Java implements a simple RPC framework

Related Article

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.