Netty Implement simple RPC Calls

Source: Internet
Author: User
Tags serialization throwable

RPC, remote Procedure call, which is generally speaking, calls a service on a remote computer as if it were a local service.

RPC can be based on HTTP or TCP protocol, Web Service is RPC based on HTTP protocol, it has good cross-platform, but its performance is inferior to RPC based on TCP protocol. Two aspects will directly affect the performance of RPC, one is the transmission mode, the second is serialization.

As we all know, TCP is the Transport layer protocol, HTTP is the application layer protocol, and the transport layer is lower than the application layer, in the data transmission, the lower the faster, so, in general, TCP must be faster than HTTP. In the case of serialization, Java provides the default serialization method, but in high concurrency, this approach will bring some performance bottlenecks, so there are a series of excellent serialization framework, such as: Protobuf, Kryo, Hessian, Jackson, etc., they can replace Java default serialization, which provides more efficient performance.
The following is a simple implementation based on Netty RPC calls.

First, define the entity classes for message passing

Span style= "FONT-SIZE:14PX;" >public class ClassInfo implements Serializable {private static final long Serialversionuid =-8970942815543515  

    064L; private string classname;//class name private string methodname;//function name private class<?>[] types;//parameter type P  
    Rivate object[] objects;//argument list public String GetClassName () {return className;  
    } public void Setclassname (String className) {this.classname = ClassName;  
    Public String Getmethodname () {return methodname;  
    } public void Setmethodname (String methodname) {this.methodname = methodname;  
    Class<?>[] GetTypes () {return types;  
    } public void Settypes (class<?>[] types) {this.types = types;  
    Object[] GetObjects () {return objects;  
    } public void SetObjects (object[] objects) {this.objects = objects; }  
}

Two, create the service side of the Netty operation, and the concrete Operation
1. Service Side

public class Rpcserver {private int port;  
    public rpcserver (int port) {this.port = port;  
        public void Start () {Eventloopgroup bossgroup = new Nioeventloopgroup ();  

        Eventloopgroup Workergroup = new Nioeventloopgroup (); try {serverbootstrap serverbootstrap = new Serverbootstrap (). Group (Bossgroup, Workergroup). Channel (Nioserve  Rsocketchannel.class). LocalAddress (Port). Childhandler (New channelinitializer<socketchannel> () {@Override protected void Initchannel (Socketchannel ch) throws Exce    
                             ption {Channelpipeline pipeline = Ch.pipeline ();    
                                Pipeline.addlast (New Lengthfieldbasedframedecoder (Integer.max_value, 0, 4, 0, 4));    
                                Pipeline.addlast (New Lengthfieldprepender (4)); Pipeline.addlast ("encoder", New ObjeCtencoder ());    
                                Pipeline.addlast ("Decoder", New Objectdecoder (Integer.max_value, classresolvers.cachedisabled (null)));   
                        Pipeline.addlast (New Invokerhandler ()); }). Option (Channeloption.so_backlog, 128). Childoption (Channeloption.so_  
            KEEPALIVE, True);      
            Channelfuture future = Serverbootstrap.bind (port). sync ();    
            System.out.println ("Server start listen at" + port);    
        Future.channel (). Closefuture (). sync ();    
             catch (Exception e) {bossgroup.shutdowngracefully ();  
        Workergroup.shutdowngracefully ();    
        } public static void Main (string[] args) throws Exception {int port;    
        if (Args.length > 0) {port = Integer.parseint (Args[0]);    
        else {port = 8080;    
      }  New Rpcserver (Port). Start ();   }    
}
Service-side operations, by the service side we see the specific data transmission operation is serialized, the specific operation or relatively simple, is to obtain the information sent over, so you can get the class name through reflection, according to the function name and parameter value, perform specific operations, the results sent to the client
public class Invokerhandler extends Channelinboundhandleradapter {public static concurrenthashmap<string, Object  
    > classmap = new concurrenthashmap<string,object> (); @Override public void Channelread (Channelhandlercontext ctx, Object msg) throws Exception {ClassInfo  
        ClassInfo = (ClassInfo) msg;  
        Object claszz = null; if (!classmap.containskey (Classinfo.getclassname ())) {try {claszz = Class.forName (classinf  
                O.getclassname ()). Newinstance ();  
            Classmap.put (Classinfo.getclassname (), CLASZZ); catch (Instantiationexception | illegalaccessexception |  
            ClassNotFoundException e) {e.printstacktrace ();  
        }}else {claszz = Classmap.get (Classinfo.getclassname ());    
        Method method = Claszz.getclass (). GetMethod (Classinfo.getmethodname (), classinfo.gettypes ()); Object result = Method.invoke (clAszz, Classinfo.getobjects ());  
        Ctx.write (result);    
        Ctx.flush ();  
    Ctx.close ();    
         @Override public void Exceptioncaught (Channelhandlercontext ctx, Throwable cause) throws Exception {    
         Cause.printstacktrace ();    
    Ctx.close ();  
 }    

}

Third, the client, through the proxy mechanism to trigger the remote call
(1) client, when the implementation of specific functions will invoke remote operations, the specific operation of the class, function and parameter information sent to the service side

public class RpcProxy {@SuppressWarnings (' unchecked ') public static <T> T Create (Object target) { Return (T) proxy.newproxyinstance (Target.getclass (). getClassLoader (), Target.getclass (). Getinterfaces (), New Invocationhandler () {@Override public object Invoke (Object Proxy, Method method, object[] Arg  
                s) throws Throwable {ClassInfo ClassInfo = new ClassInfo ();  
                Classinfo.setclassname (Target.getclass (). GetName ());  
                Classinfo.setmethodname (Method.getname ());  
                Classinfo.setobjects (args);  

                Classinfo.settypes (Method.getparametertypes ());  
                Resulthandler Resulthandler = new Resulthandler ();    
                Eventloopgroup Group = new Nioeventloopgroup ();    
                    try {Bootstrap b = new Bootstrap (); B.group (Group). Channel (Niosocketchannel.class). Option (Channeloption.tcp_nodelay, True). Handler (  New Channelinitializer<socketchannel> () {@Override public void Initchannel (Socketchannel ch) throws Exception {Channelpipeline pipeline = Ch.pipe    
                             Line ();    
                             Pipeline.addlast ("Framedecoder", New Lengthfieldbasedframedecoder (Integer.max_value, 0, 4, 0, 4));    
                             Pipeline.addlast ("Frameencoder", New Lengthfieldprepender (4));      
                             Pipeline.addlast ("encoder", New Objectencoder ());    
                             Pipeline.addlast ("Decoder", New Objectdecoder (Integer.max_value, classresolvers.cachedisabled (null)));  
                         Pipeline.addlast ("handler", Resulthandler);    

                    }    
                     }); Channelfuture FutuRe = B.connect ("localhost", 8080). sync ();  
                    Future.channel (). Writeandflush (ClassInfo). sync ();    
                Future.channel (). Closefuture (). sync ();    
                finally {group.shutdowngracefully ();  
            return Resulthandler.getresponse ();  
    }  
        });   }  
}
Gets the result value returned by the remote call
public class Resulthandler extends Channelinboundhandleradapter {  

    private Object response;    

    Public Object GetResponse () {return    
    response;    
}    

    @Override public    
    void Channelread (Channelhandlercontext ctx, Object msg) throws Exception {    
        response=msg;    
        SYSTEM.OUT.PRINTLN ("Client receives the message returned by the server:" + msg);    
    }    

    @Override public    
    void Exceptioncaught (Channelhandlercontext ctx, Throwable cause) throws Exception {    
        SYSTEM.OUT.PRINTLN ("Client exception is General");    
    }    
  

Iv. interface, implementation class and main operation

Public interface Hellorpc {  
    string hello (string name);  
}  
public class Hellorpcimpl implements HELLORPC {  

    @Override public  
    string Hello (string name) {return  
        " Hello "+name;  
    }  

}"  

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.