On the RMI underlying principle in Java __java

Source: Internet
Author: User

Foreword: As a system is recognized by the user, the business volume, the request quantity unceasingly rises, then the stand-alone system certainly cannot satisfy, then the system slowly moves toward the distributed, along with it is the system "the communication" the barrier. In general, there are two ways to resolve communication between systems: remote invocation and message. RMI (remote method invocation) is a way of remote invocation, which is also the main introduction of this article.


One , a simple example of RMI

This example is split into the server side and the client, placed in two idea projects, and through the stand-alone and dual-machine two environment testing, is a true sense of distributed applications.

Project structure

Service-side application: Server

Main program: Com.jnu.wwt.entry.Server

Service Interface: Com.jnu.wwt.service.IOperation

Service implementation: Com.jnu.wwt.service.impl.OperationImpl

Client application: Clients

Main program: Com.jnu.wwt.entry.Client

Service Interface: Com.jnu.wwt.service.IOperation


Source:

Server.java

/**
 * Created by WWT on 2016/9/14.
 */Public
class Server {public

    static void Main (String args[]) throws exception{

        // Take 1099 as the port where the Locateregistry receives the client request, and register the service mapping relationship
        Registry registry=locateregistry.createregistry (1099);

        IOperation ioperation=new Operationimpl ();
        Naming.rebind ("Rmi://127.0.0.1:1099/operation", ioperation);

        SYSTEM.OUT.PRINTLN ("service running ...");
    }

Ioperation.java (both the server and client need one)

/**
 * Server-side interface must implement Java.rmi.Remote
 * Created by WWT on 2016/9/14.
 * * Public
interface IOperation extends remote{

    /**
     * The method on the remote interface must throw remoteexception because network traffic is unstable and cannot eat the exception
      a
      b
     @return
*/int Add (int a, int b) throws remoteexception;     


Operationimpl.java

/**
 * Created by WWT on 2016/9/14.
 *
/public class Operationimpl extends UnicastRemoteObject implements ioperation{public

    Operationimpl () throws remoteexception {
        super ();
    }

    @Override public
    int Add (int a, int b) throws remoteexception{return
        a+b
    }

}

Client.java

/**
 * Created by WWT on 2016/9/15.
 *
/public class Client {public

    static void Main (String args[]) throws exception{
        ioperation ioperation= ( ioperation) naming.lookup ("Rmi://127.0.0.1:1099/operation");
        System.out.println (Ioperation.add (1,1));
    }


Run results

Running server applications first, the service is up. Then switch to the client application, click Run, and the client invokes the server's service to return the results.




Ii. What did RMI do?

Now let's forget about the RMI thing in Java. Suppose we need to implement the effect in the example above. The steps you can think of are:

Write the service-side service and expose it to the client for invocation through the port of one of the server machines. The client program is written by specifying the host and port number where the service resides, encapsulating and serializing the request, and eventually sending it to the server via a network protocol. Server-side parsing and deserialization requests, invoking services on the service side, serializing the results and returning them to the client. The client receives and deserializes the results returned by the server and feeds back to the user.

This is a rough process, and it's not hard to imagine that RMI is actually a common part of the package that encapsulates some of the details, such as serialization and deserialization, connection creation and release, and the following are the specific processes of RMI:


Several new concepts are involved here:

Stub and skeleton: The identities of the two are identical, both as proxies. The client is called a stub, and the service side is called a skeleton. To do this, the two proxies are essential, including details such as network connectivity, for the programmer to mask the details of the remote method call.

Registry: As the name suggests, you can think of Registry as a "registry" that provides a mapping of service names to services. Without it, it means that the client needs to remember the port number where each service resides, a design that is clearly not elegant.


before you go into the RMI principle, take a look at the classes and their hierarchies and the main methods used.





Don't know where to look at any time to look at the structure ... Here we go



the bottom principle of the four or one step anatomy rmi
Service-side start Registry Service

Registry registry=locateregistry.createregistry (1099);
Starting with the code above, it goes back and finds that the server has created a Registryimpl object, which makes a judgment. If the server-side specified port number is 1099 and the system has security Manager enabled, the system's security checksum can be bypassed within the restricted permission set (listen and accept). Conversely, you must perform a security check. This is purely for efficiency reasons. The real thing to do in the Setup () method, continue to look down.
public registryimpl (final int var1) throws RemoteException {if (var1 = = 1099 && Sys Tem.getsecuritymanager ()!= null) {try {accesscontroller.doprivileged, new privilegedexceptionaction ( {public Void run () throws RemoteException {liveref var1x = new Liveref (registryimp
                    L.id, var1);
                    RegistryImpl.this.setup (New Unicastserverref (var1x));
                return null; }, (AccessControlContext) null, new permission[]{new socketpermission ("localhost:" + var1, "Listen,accept")})
        ;
        catch (Privilegedactionexception Var3) {throw (remoteexception) var3.getexception ();
        } else {Liveref var2 = new Liveref (ID, var1);
    This.setup (New Unicastserverref (VAR2)); }

}
The SetUp () method assigns the remote reference ref (REMOTEREF) that points to the Registryimpl object being initialized to the incoming Unicastserverref object, which involves an upward transition. Then continue to hand over the Unicastserverref ExportObject () method.
private void Setup (Unicastserverref var1) throws RemoteException {
    this.ref = var1;
    Var1.exportobject (this, (Object) null, true);
Enter the Unicastserverref exportobject () method. As you can see, here we first create a proxy for the incoming Registryimpl, which we can infer is the Registryimpl stub object that serves the client later. The Unicastserverref Skel (Skeleton) object is then set to the current Registryimpl object. Finally, a target object is constructed with skeleton, stub, Unicastserverref object, ID, and a Boolean value, which means that the target object basically contains all the information. Call the ExportObject () method of the Unicastserverref ref (LIVEREF) variable.
Public remote ExportObject (remote var1, Object var2, Boolean var3) throws RemoteException {
    Class VAR4 = Var1.getclass ();

    Remote VAR5;
    try {
        var5 = Util.createproxy (VAR4, This.getclientref (), this.forcestubuse);
    } catch ( IllegalArgumentException var7) {
        throw new Exportexception ("remote object implements illegal remote interface", VAR7 );
    }

    if (var5 instanceof remotestub) {
        This.setskeleton (var1);
    }

    Target VAR6 = new Target (var1, this, VAR5, This.ref.getObjID (), VAR3);
    This.ref.exportObject (VAR6);
    This.hashtomethod_map = (Map) hashtomethod_maps.get (VAR4);
    return VAR5;
}
So far, all we see are assignments and creation of variables, not to the connection layer, which will be used by stub and skeleton objects. The next step is the connection layer. Tracing the ExportObject () method of Liveref, it is easy to find the Tcptransport exportobject () method. What this method does is expose the target object that is constructed above. The Listen () method of the Tcptransport is invoked, and the Listen () method creates a serversocket and initiates a thread waiting for the client's request. The target object is then deposited into the objecttable by invoking the ExportObject () of the parent class transport.
public void ExportObject (Target var1) throws RemoteException {
    synchronized (this) {
        this.listen ();
        ++this.exportcount;
    }

    Boolean var2 = false;
    Boolean var12 = false;

    try {
        var12 = true;
        Super.exportobject (var1);
        Var2 = true;
        Var12 = false;
    } Finally {
        if (var12) {
            if (!var2) {
                synchronized (this) {
                    this.decrementexportcount ();
                }
            }

        }
    }

    if (!VAR2) {
        synchronized (this) {
            this.decrementexportcount ();
        }
    }

}
Here, we have created the Registryimpl object and started a request for the service to wait for the client. Client Get server Rgistry proxy

IOperation ioperation= (ioperation) naming.lookup ("Rmi://127.0.0.1:1099/operation");
From the code above, it is easy to trace back to the Locateregistry GetRegistry () method. The thing that this method does is to construct the Remoteref object through the incoming host and port and create a local proxy. You can find through the debug feature that this proxy object is actually a Registryimpl_stub object. This allows the client to have a REGISTRYIMPL proxy on the server (depending on the ignorestubclasses variable). But note that this time the agent has not actually been associated with the server-side Registryimpl object, after all, is two VM above the object, here we can also guess, agent and Remote registry object is through the socket message to complete.

public static Registry GetRegistry (String host, int port, rmiclientsocketfactory CSF)

    Throws RemoteException {Registry Registry = null;

    if (port <= 0) port = registry.registry_port;
        if (host = = NULL | | host.length () = = 0) {//If host is blank (as returned by ' file: ' URL in 1.0.2 used in java.rmi.Naming), try to convert to real local host name so//that the Registryimpl ' s checkaccess would not FA
        Il. try {host = Java.net.InetAddress.getLocalHost (). gethostaddress ();
        catch (Exception e) {//If that is failed, at least try "" (localhost) anyway ... host = ""; } liveref liveref = new Liveref (new ObjID (objid.registry_id), New Tcpendpoint (ho
    St, Port, CSF, NULL), FALSE); Remoteref ref = (CSF = null)?

    New Unicastref (LIVEREF): New UnicastRef2 (LIVEREF); Return (Registry) Util.createproxy (Registryimpl.class, ref, FALSE); }


The service-side creation of the service object is seen from the Operationimpl constructor. The constructor for the parent class UnicastRemoteObject is invoked, traced back to the UnicastRemoteObject private Method ExportObject (). This makes a judgment that the implementation of the service is not a unicastremoteobject subclass and, if so, directly assigns its ref (REMOTEREF) object to the incoming Unicastserverref object. Conversely, the Unicastserverref ExportObject () method is invoked. Here we are the first kind of situation.

private static remote ExportObject (remote obj, unicastserverref sref)
    throws RemoteException
{
    //If obj Extends UnicastRemoteObject, set its ref.
    

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.