最近一段时间对分布式很迷惑,安静下来想想,为什么程序可以再不同的机器上,无非他们之间是通过网络来通信的,那他们之间的交流主要是什么内容呢,我想无非是运行业务方法需要的一些参数罢了,而对于远程的机器怎么知道另一台机器的业务方法呢?这就出现了面向接口的编程。(以下将从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的远程调用,由于这上面不能画图,我在这里就描述一下,贯穿上面两个例子的思想就是:客户端对业务方法的调用时通过实现业务共同的接口,并把实际的操作权给我远程的服务器端。即:业务接口--->客户端--->远程服务器端--->业务实现类--->接口
分享到:
相关推荐
基于模型的系统工程(MBSE)的案例研究,第 2 部分 为分布式系统的分析和设计开发以数据为中心的流程.pdf基于模型的系统工程(MBSE)的案例研究,第 2 部分 为分布式系统的分析和设计开发以数据为中心的流程.pdf基于模型的...
分析了.NET 平台下 3 种分布式开发技术,通过使用第三方提供的火车时刻表 Web 接口和自行 设计学生信息查询接口的实验,实现了 WebService 技术在分布式开发中的应用
#资源达人分享计划#
分布式光伏开发模式分析.pdf
分布式调度系统选择分析,用亿图软件做的一个分布式调度系统的分析的脑图,包含,Time ,Spring 的@Scheduled,Quartz 分布式集群开源工具,基于Quartz自己开发 等几个分析
#资源达人分享计划#
基于 Spring + SpringMVC + Mybatis 分布式敏捷开发系统架构,提供整套公共微服务服务模块:集中权限管理(单点登录)、内容管理、支付中心、用户管理(支持第三方登录)、微信平台、存储系统、配置中心、日志分析、...
Hadoop分布式文件系统的模型分析,Hadoop 分布式文件系统是遵循Google 文件系统原理进行开发和实现的,受到了业界极大关注,并 已被广泛应用。 鉴于当前缺乏从系统设计理论的角度对其开展的相关研究,本文从 Hadoop ...
#资源达人分享计划#
本文结合CORBA技术、数值计算方法、OpenGL图形仿真技术,以C++Builder为开发工具开发了基于CORBA的分布式多连杆仿真系统,实现了分布式环境下的多连杆系统的分析、仿真及灵敏度分析,用户可以在客户端提供相应参数,由...
#资源达人分享计划#
#资源达人分享计划#
介绍了分布式医学影像分析与处理平台DMIP(Distributing Medical Imaging Analyzing and Processing Platform)的设计以及在此基础上开发的数字医疗软件。DMIP采用分布式数据存储技术以及面向对象和基于构件的软件...
本文就采用面对对象的方法以UML为建模语言,使用PowerDesigner这个case工具分析设计一个分布式的B/S结构的基于COM+和XML的网络考试系统。并使用Delphi、VBScript、ADO、XML、HTML等编程工具、语言和技术实现了这个...
#资源达人分享计划#
在应用系统当中,需要确保数据访问所具备的时效性, 将关键性的业务数据全都存储在内存当中。不过如果出现业务 范围持续拓展的情况,只是利用一台机器已然无法实现对全部 关键性业务数据的上传,所以,应该针对...
#资源达人分享计划#
《大规模分布式存储系统:原理解析与架构实战》是分布式系统领域的经典著作,由阿里巴巴高级技术专家“阿里日照”(OceanBase核心开发人员)撰写,阳振坤、章文嵩、杨卫华、汪源、余锋(褚霸)、赖春波等来自阿里、...