分布式开发的一些分析

最近一段时间对分布式很迷惑,安静下来想想,为什么程序可以再不同的机器上,无非他们之间是通过网络来通信的,那他们之间的交流主要是什么内容呢,我想无非是运行业务方法需要的一些参数罢了,而对于远程的机器怎么知道另一台机器的业务方法呢?这就出现了面向接口的编程。(以下将从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的远程调用,由于这上面不能画图,我在这里就描述一下,贯穿上面两个例子的思想就是:客户端对业务方法的调用时通过实现业务共同的接口,并把实际的操作权给我远程的服务器端。即:业务接口--->客户端--->远程服务器端--->业务实现类--->接口
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值