`
wujianjun12315
  • 浏览: 110120 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

分布式开发的一些分析

阅读更多
    最近一段时间对分布式很迷惑,安静下来想想,为什么程序可以再不同的机器上,无非他们之间是通过网络来通信的,那他们之间的交流主要是什么内容呢,我想无非是运行业务方法需要的一些参数罢了,而对于远程的机器怎么知道另一台机器的业务方法呢?这就出现了面向接口的编程。(以下将从RMI编程到Socket实现底层讲起)
     下面就对于常用的RMI的分布式的编程步骤分析一下:
1:由于不同机器之间的通信交流,他们有一个共同的出发点就是针对处理业务而存在,而又不暴露业务方法,所以,业务方法的借口就这样被定义出来了。如定义一个RmiMonitorService.java,这里必须继承Remote类
package com.test.service;

import java.rmi.Remote;
import java.rmi.RemoteException;
/**
 * 定义业务方法接口
 * @author  wkf45150/wujianjun
 * @version  [v1.0, 2011-6-21]
 * @see  [相关类/方法]
 * @since  SmartCare1.1
 */
public interface RmiMonitorService extends Remote
{
    public String interactive() throws RemoteException;//必须抛出异常
}

2:编写业务层的实现类,这里必须继承UnicastRemoteObject类
如RmiMonitorServiceImpl.java
package com.test.serviceImpl;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import com.test.service.RmiMonitorService;
/**
 * 实现类
 * @author  wkf45150/wujianjun
 * @version  [v1.0, 2011-6-21]
 * @see  [相关类/方法]
 * @since  SmartCare1.1
 */
public class RmiMonitorServiceImpl extends UnicastRemoteObject implements RmiMonitorService
{
    private static final long serialVersionUID = -3771656108378649574L;
    static int num = 0;
      
        /**  
         * 必须定义构造方法,因为要抛出RemoteException异常  
         */  
        public RmiMonitorServiceImpl() throws RemoteException 
        {   
            super();   
        }

        @Override
        public String interactive() throws RemoteException
        {
            //这里面就是一些实现业务的具体方法,以下面得例子测试
            System.out.println("我被人调用了第"+num+"次");
            num++;
            return "hello RMI,我是从服务器端返回来的";
        }   
}


3:实现服务器端的编程,如RmiServer.java
package com.rmi.service;

import java.rmi.Naming;
import java.rmi.registry.LocateRegistry;
import com.test.service.RmiMonitorService;
import com.test.serviceImpl.RmiMonitorServiceImpl;
/**
 * 服务器端
 * @author  wkf45150/wujianjun
 * @version  [v1.0, 2011-6-21]
 * @see  [相关类/方法]
 * @since  SmartCare1.1
 */
public class RmiServer
{
    public static void main(String[] args)
    {
        int port = 8080;
        String ip = "localhost";
        try
        {
            //注册端口
            LocateRegistry.createRegistry(port);
            //调用业务方法
            RmiMonitorService comm = new RmiMonitorServiceImpl();  
            //将业务方法绑定到固定的IP和端口上
            Naming.bind("//" + ip + ":" + port + "/comm", comm);   
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }   
    }
}

4:客户端编程(由于客户端在调用服务器端的时候对业务方法是不知情的,所以客户端和服务器端需要提供相同的接口),在这里也需要定义相同的接口,否者编译通不过,如果在同一台机器,可以共用一个接口。代码如:
package com.rmi.service;

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import com.test.service.RmiMonitorService;
/**
 * 客户端
 * @author  wkf45150/wujianjun
 * @version  [v1.0, 2011-6-21]
 * @see  [相关类/方法]
 * @since  SmartCare1.1
 */
public class MonitorClient
{
    public static void main(String[] args)
    {
        int port = 8080;
        //服务器端IP
        String ip = "10.110.189.46";
        try
        {
            //對綁定业务方法的IP进行调用,返回业务方法的代理,我们可以理解为建立连接
            RmiMonitorService monitorService = (RmiMonitorService) Naming.lookup("rmi://" + ip + ":" + port + "/comm");
            //这一步可以形象理解为服务器传值,并取回服务器返回的值
            monitorService.interactive();
        }
        catch (MalformedURLException e)
        {
            e.printStackTrace();
        }
        catch (RemoteException e)
        {
            e.printStackTrace();
        }
        catch (NotBoundException e)
        {
            e.printStackTrace();
        }   
    }
}

在这里关于Rmi进行分布式编程的流程就说完了,以上例子经过测试时可以跑通的。以上的例子,我觉得就是一个利用接口和网络实现的代理模式,嘿嘿。。。。

======================================================================
   以下从socket和流的方面分析一下分布式开发(其实模式和上面的RMI编程一样,知识所举的例子有所不一样):
1:首先定义接口Person.java
public interface Person {   
    public int getAge(); throws Throwable;   
    public String getName(); throws Throwable;   
}  


2:实现类(这里有两个)
A:PersonServer.java-------处理业务方法
public class PersonServer implements Person {   
    int age;   
    String name;   
  
    public PersonServer(String name, int age); {   
        this.age = age;   
        this.name = name;   
    }   
  
    public int getAge(); {   
        return age;   
    }   
  
    public String getName(); {   
        return name;   
    }   
}  

3:客户端程序,这里也实现了Person接口,通过接口调用业务方法(对客户端的调用就像在远程上对本地业务的调用一样,这一点很重要)如:PersonStub.java
import java.io.ObjectOutputStream;   
import java.io.ObjectInputStream;   
import java.net.Socket;   
  
public class Person_Stub implements Person {   
    Socket socket;   
  
    public Person_Stub(); throws Throwable {   
        // connect to skeleton   
        socket = new Socket("computer_name", 9000);;   
    }   
  
    public int getAge(); throws Throwable {   
        // pass method name to skeleton   
        ObjectOutputStream outStream =   
            new ObjectOutputStream(socket.getOutputStream(););;   
        outStream.writeObject("age");;   
        outStream.flush();;   
  
        ObjectInputStream inStream =   
            new ObjectInputStream(socket.getInputStream(););;   
        return inStream.readInt();;   
    }   
  
    public String getName(); throws Throwable {   
        // pass method name to skeleton   
        ObjectOutputStream outStream =   
            new ObjectOutputStream(socket.getOutputStream(););;   
        outStream.writeObject("name");;   
        outStream.flush();;   
  
        ObjectInputStream inStream =   
            new ObjectInputStream(socket.getInputStream(););;   
        return (String);inStream.readObject();;   
    }  
    //客户端的调用
    public static void main(String [] args); {  
            //注意这里的调用 
            Person person = new Person_Stub();;   
            int age = person.getAge();;   
            String name = person.getName();;   
            System.out.println(name + " is " + age + " years old");;   
        } catch(Throwable t); {   
            t.printStackTrace();;   
        }   
    }   
 
}  

4:服务器端的编程(这里主要是通过和客户端的通信来调用业务方法)
如:Person_Skeleton.java
import java.io.ObjectOutputStream;   
import java.io.ObjectInputStream;   
import java.net.Socket;   
import java.net.ServerSocket;   
  
public class Person_Skeleton extends Thread {   
    PersonServer myServer;   
  
    public Person_Skeleton(PersonServer server); {   
        // get reference of object server   
        this.myServer = server;   
    }   
  
    public void run(); {   
        try {   
            // new socket at port 9000   
            ServerSocket serverSocket = new ServerSocket(9000);;   
            // accept stub's request   
            Socket socket = serverSocket.accept();;   
  
            while (socket != null); {   
                // get stub's request   
                ObjectInputStream inStream =   
                    new ObjectInputStream(socket.getInputStream(););;   
                String method = (String);inStream.readObject();;   
  
                // check method name   
                if (method.equals("age");); {   
                    // execute object server's business method   
                    int age = myServer.getAge();;   
                    ObjectOutputStream outStream =   
                        new ObjectOutputStream(socket.getOutputStream(););;   
  
                    // return result to stub   
                    outStream.writeInt(age);;   
                    outStream.flush();;   
                }   
  
                if(method.equals("name");); {   
                    // execute object server's business method   
                    String name = myServer.getName();;   
                    ObjectOutputStream outStream =   
                        new ObjectOutputStream(socket.getOutputStream(););;   
  
                    // return result to stub   
                    outStream.writeObject(name);;   
                    outStream.flush();;   
                }   
            }   
        } catch(Throwable t); {   
            t.printStackTrace();;   
            System.exit(0);;   
        }   
    }   
  
    public static void main(String args []); {   
        // new object server   
        PersonServer person = new PersonServer("Richard", 34);;   
  
        Person_Skeleton skel = new Person_Skeleton(person);;   
        skel.start();;   
    }   
}  

  以上就是基于socket的远程调用,由于这上面不能画图,我在这里就描述一下,贯穿上面两个例子的思想就是:客户端对业务方法的调用时通过实现业务共同的接口,并把实际的操作权给我远程的服务器端。即:业务接口--->客户端--->远程服务器端--->业务实现类--->接口
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics