分布式计算:CORBA、Java Applets、RMI 与 EJB 全面解析
1. 命名服务与 CORBA 基础
在分布式计算中,命名服务起着关键作用。它负责将对象引用转换为字符串名称,以及将字符串名称解析为对象引用,就像电话簿一样,服务器和客户端都可以查询和操作。创建对象到字符串的映射称为绑定对象,移除映射称为解绑,通过字符串获取对象引用称为解析名称。
1.1 示例需求
我们要实现一个能查询准确时间的服务器,以及一个请求准确时间的客户端。这里我们使用 Java 实现,但实际情况中也可使用不同语言。
1.2 操作步骤
1.2.1 编写 IDL 源文件
首先,编写服务的 IDL 描述,通常由服务器程序员完成。IDL 文件会分发给客户端程序员,成为不同语言间的桥梁。以下是 ExactTime 服务器的 IDL 描述:
//: c15:corba:ExactTime.idl
//# You must install idltojava.exe from
//# java.sun.com and adjust the settings to use
//# your local C preprocessor in order to compile
//# This file. See docs at java.sun.com.
module remotetime {
interface ExactTime {
string getTime();
};
}; ///:~
此代码声明了 remotetime 命名空间内的 ExactTime 接口,该接口包含一个返回当前时间字符串格式的方法。
1.2.2 创建存根和骨架
使用 JavaIDL 产品中的 idltojava 工具编译 IDL 文件,生成用于实现客户端和服务器的 Java 存根和骨架代码:
idltojava remotetime.idl
这将自动生成存根和骨架的代码。idltojava 会生成一个以 IDL 模块命名的 Java 包 remotetime,并将生成的 Java 文件放在 remotetime 子目录中。
_ExactTimeImplBase.java
是用于实现服务器对象的骨架,
_ExactTimeStub.java
用于客户端。
1.2.3 实现服务器和客户端
以下是服务器端代码:
//: c15:corba:RemoteTimeServer.java
import remotetime.*;
import org.omg.CosNaming.*;
import org.omg.CosNaming.NamingContextPackage.*;
import org.omg.CORBA.*;
import java.util.*;
import java.text.*;
// Server object implementation
class ExactTimeServer extends _ExactTimeImplBase {
public String getTime(){
return DateFormat.
getTimeInstance(DateFormat.FULL).
format(new Date(
System.currentTimeMillis()));
}
}
// Remote application implementation
public class RemoteTimeServer {
// Throw exceptions to console:
public static void main(String[] args)
throws Exception {
// ORB creation and initialization:
ORB orb = ORB.init(args, null);
// Create the server object and register it:
ExactTimeServer timeServerObjRef =
new ExactTimeServer();
orb.connect(timeServerObjRef);
// Get the root naming context:
org.omg.CORBA.Object objRef =
orb.resolve_initial_references(
"NameService");
NamingContext ncRef =
NamingContextHelper.narrow(objRef);
// Assign a string name to the
// object reference (binding):
NameComponent nc =
new NameComponent("ExactTime", "");
NameComponent[] path = { nc };
ncRef.rebind(path, timeServerObjRef);
// Wait for client requests:
java.lang.Object sync =
new java.lang.Object();
synchronized(sync){
sync.wait();
}
}
} ///:~
服务器对象的实现很简单,是一个继承自 IDL 编译器生成的骨架代码的普通 Java 类。但与 ORB 和其他 CORBA 服务交互时会更复杂。
客户端代码如下:
//: c15:corba:RemoteTimeClient.java
import remotetime.*;
import org.omg.CosNaming.*;
import org.omg.CORBA.*;
public class RemoteTimeClient {
// Throw exceptions to console:
public static void main(String[] args)
throws Exception {
// ORB creation and initialization:
ORB orb = ORB.init(args, null);
// Get the root naming context:
org.omg.CORBA.Object objRef =
orb.resolve_initial_references(
"NameService");
NamingContext ncRef =
NamingContextHelper.narrow(objRef);
// Get (resolve) the stringified object
// reference for the time server:
NameComponent nc =
new NameComponent("ExactTime", "");
NameComponent[] path = { nc };
ExactTime timeObjRef =
ExactTimeHelper.narrow(
ncRef.resolve(path));
// Make requests to the server object:
String exactTime = timeObjRef.getTime();
System.out.println(exactTime);
}
} ///:~
客户端代码的前几行与服务器进程类似,初始化 ORB 并解析命名服务的引用。然后通过解析字符串名称获取服务器对象引用,最后调用
getTime()
方法。
1.3 激活服务
在运行服务器和客户端之前,必须启动命名服务进程。在 JavaIDL 中,命名服务是一个随产品包提供的 Java 应用程序,默认在 JVM 实例中运行并监听网络端口 900。启动顺序为:先启动命名服务,再启动服务器,最后启动客户端。
以下是整个流程的 mermaid 流程图:
graph LR
A[编写 IDL 源文件] --> B[创建存根和骨架]
B --> C[实现服务器和客户端]
C --> D[激活命名服务]
D --> E[启动服务器]
E --> F[启动客户端]
2. Java Applets 与 CORBA
Java applets 可以作为 CORBA 客户端,访问以 CORBA 对象形式暴露的远程信息和服务。但 applet 只能与它下载自的服务器连接,这与 CORBA 追求的完全位置透明性相悖,是网络安全问题。解决方案包括在内部网络中放宽浏览器的安全限制,或设置防火墙策略以连接外部服务器。部分 Java ORB 产品提供专有解决方案,如 HTTP Tunneling 或特殊防火墙功能。
3. CORBA 与 RMI 对比
CORBA 的主要特性之一是支持远程过程调用(RPC),允许本地对象调用远程对象的方法。Java 本身的 RMI 也能实现相同功能,但 RMI 仅支持 Java 对象间的 RPC,而 CORBA 支持任何语言实现的对象间的 RPC。不过,RMI 也可调用远程非 Java 代码,只需在服务器端为非 Java 代码创建一个 Java 包装对象,该对象通过 RMI 与 Java 客户端连接,内部使用 JNI 或 J/Direct 等技术与非 Java 代码连接。
3.1 对比总结
| 特性 | CORBA | RMI |
|---|---|---|
| 支持语言 | 任何语言 | Java |
| 集成层 | 需要第三方 ORB | 无需第三方 |
| 跨语言能力 | 强 | 弱 |
4. 企业 JavaBeans(EJB)
开发分布式对象系统时,除了业务问题,还需考虑性能、可扩展性、安全性、分布式事务、可重用性和可用性等问题。为解决这些问题,Sun 等公司创建了 Enterprise JavaBeans 规范(EJB)。EJB 描述了一个服务器端组件模型,采用标准方法解决上述问题,使开发者能创建专注于提供业务逻辑的业务组件 EJBs,且 EJBs 与底层“管道”代码分离,具有厂商无关性。
4.1 JavaBeans 与 EJBs 的区别
JavaBeans 组件模型和 Enterprise JavaBeans 规范虽都旨在促进 Java 代码在开发和部署工具间的重用和可移植性,但解决的问题不同。JavaBeans 标准用于创建可重用组件,常用于 IDE 开发工具,通常是可视化组件;而 EJB 规范用于开发服务器端 Java 代码,由于 EJBs 可能在无可视化显示的大型机等多种服务器端平台上运行,因此不能使用 AWT 或 Swing 等图形库。
4.2 EJB 规范中的角色
EJB 规范定义了六个角色,用于开发、部署和运行分布式系统,如下表所示:
| 角色 | 职责 |
| ---- | ---- |
| 企业 Bean 提供者 | 负责创建可重用的 EJB 组件,并将其打包到特殊的 jar 文件(ejb - jar 文件)中 |
| 应用程序组装者 | 从一组 ejb - jar 文件创建和组装应用程序,包括编写使用这些 EJBs 的应用程序(如 servlet、JSP、Swing 等) |
| 部署者 | 将组装者和/或 Bean 提供者提供的 ejb - jar 文件部署到运行时环境(一个或多个 EJB 容器)中 |
| EJB 容器/服务器提供者 | 提供用于部署、管理和运行 EJB 组件的运行时环境和工具 |
| 系统管理员 | 管理不同组件和服务,确保它们正确配置和交互,并保证系统正常运行 |
4.3 EJB 相关组件和服务
- EJB 组件 :遵循 EJB 规范严格标准和设计模式的可重用业务逻辑元素,具有可移植性,可由其他服务(如安全、缓存和分布式事务)为其提供支持。
- EJB 容器 :包含并运行 EJB 组件的运行时环境,提供分布式事务、安全、Bean 生命周期管理、缓存、线程和会话管理等底层“管道”功能。
- EJB 服务器 :包含并运行一个或多个 EJB 容器的应用服务器。
- Java 命名和目录接口(JNDI) :用于 EJB 组件在网络上的命名服务以及其他容器服务(如事务),与 CORBA CosNaming 等命名和目录标准映射紧密,可作为其包装实现。
- Java 事务 API/Java 事务服务(JTA/JTS) :作为 EJB 中的事务 API,企业 Bean 提供者可使用 JTS 创建事务代码,不过 EJB 容器通常实现 EJB 中的事务。
以下是 EJB 开发和部署流程的 mermaid 流程图:
graph LR
A[企业 Bean 提供者创建 EJB 组件] --> B[应用程序组装者组装应用程序]
B --> C[部署者部署到 EJB 容器]
C --> D[EJB 容器/服务器提供者提供运行环境]
D --> E[系统管理员管理系统]
综上所述,分布式计算涵盖了多种技术和规范,每种都有其特点和适用场景。CORBA 提供了跨语言的分布式计算能力,RMI 则专注于 Java 对象间的交互,而 EJB 为开发分布式企业应用提供了全面的解决方案。开发者应根据具体需求选择合适的技术。
5. 分布式计算技术的应用场景分析
不同的分布式计算技术在实际应用中有着各自独特的优势和适用场景,下面我们来详细分析一下。
5.1 CORBA 的应用场景
CORBA 由于支持任何语言实现的对象间的 RPC,非常适合构建大型的、跨平台和跨语言的分布式系统。例如,在企业级的信息系统集成中,可能涉及到多种不同语言编写的组件,如 C++ 编写的高性能计算模块、Java 编写的业务逻辑层以及 Python 编写的数据处理脚本。CORBA 可以将这些不同语言的组件无缝地集成在一起,实现高效的通信和协作。
操作步骤如下:
1. 确定系统中需要集成的各个组件及其功能。
2. 为每个组件编写 IDL 描述,定义其接口和方法。
3. 使用 IDL 编译器生成相应的存根和骨架代码。
4. 实现各个组件的具体逻辑,并将其注册到 CORBA 命名服务中。
5. 客户端通过命名服务查找并调用所需的组件。
5.2 RMI 的应用场景
RMI 专注于 Java 对象间的交互,因此在纯 Java 开发的分布式系统中具有明显的优势。例如,在 Java 开发的 Web 应用中,服务器端的不同模块之间可能需要进行远程调用,RMI 可以提供简单、高效的解决方案。
操作步骤如下:
1. 定义远程接口,继承
java.rmi.Remote
接口。
2. 实现远程接口的具体类,继承
UnicastRemoteObject
类。
3. 启动 RMI 注册表,使用
rmiregistry
命令。
4. 将远程对象绑定到 RMI 注册表中。
5. 客户端通过 RMI 注册表查找并调用远程对象。
5.3 EJB 的应用场景
EJB 为开发分布式企业应用提供了全面的解决方案,适用于构建复杂的、多层架构的企业级应用。例如,在电子商务系统中,需要处理大量的用户请求、订单管理、库存管理等业务逻辑,同时还需要保证系统的性能、可扩展性和安全性。EJB 可以帮助开发者快速构建这样的系统,将业务逻辑封装在 EJB 组件中,由 EJB 容器提供事务管理、安全控制等功能。
操作步骤如下:
1. 企业 Bean 提供者创建 EJB 组件,编写业务逻辑。
2. 应用程序组装者将 EJB 组件组装成完整的应用程序。
3. 部署者将应用程序部署到 EJB 容器中。
4. EJB 容器/服务器提供者提供运行环境,管理 EJB 组件的生命周期。
5. 系统管理员监控和管理整个系统的运行。
5.4 应用场景对比
| 技术 | 适用场景 | 优势 |
|---|---|---|
| CORBA | 跨平台、跨语言的大型分布式系统 | 支持多种语言,实现不同组件的集成 |
| RMI | 纯 Java 开发的分布式系统 | 简单高效,与 Java 语言紧密结合 |
| EJB | 复杂的企业级分布式应用 | 提供全面的企业级服务,如事务管理、安全控制等 |
6. 分布式计算技术的未来发展趋势
随着信息技术的不断发展,分布式计算技术也在不断演进。以下是一些可能的未来发展趋势:
6.1 云原生与分布式计算的融合
云原生技术的兴起,如容器化、微服务架构等,为分布式计算带来了新的机遇。未来,分布式计算技术将与云原生技术深度融合,实现更加灵活、高效的分布式系统部署和管理。例如,使用 Kubernetes 等容器编排工具来管理分布式计算任务,提高系统的可扩展性和容错性。
6.2 人工智能与分布式计算的结合
人工智能领域的发展需要大量的计算资源和数据处理能力,分布式计算可以为人工智能提供强大的支持。未来,分布式计算技术将与人工智能算法相结合,实现分布式机器学习、深度学习等应用,加速人工智能的发展。
6.3 区块链与分布式计算的协同
区块链技术的核心是分布式账本和共识机制,与分布式计算有着天然的联系。未来,区块链与分布式计算将相互协同,为金融、供应链等领域提供更加安全、可信的分布式解决方案。
6.4 安全性能的提升
随着分布式系统的广泛应用,安全问题变得越来越重要。未来,分布式计算技术将更加注重安全性能的提升,采用更加先进的加密算法、身份认证机制等,保障分布式系统的安全运行。
7. 总结与建议
分布式计算技术在现代信息技术中扮演着重要的角色,不同的技术有着各自的特点和适用场景。在实际开发中,开发者应根据具体需求选择合适的技术。
7.1 选择建议
- 如果需要构建跨平台、跨语言的大型分布式系统,建议选择 CORBA。
- 如果是纯 Java 开发的分布式系统,RMI 是一个不错的选择。
- 如果要开发复杂的企业级分布式应用,EJB 可以提供全面的解决方案。
7.2 学习建议
- 对于初学者来说,可以先从 RMI 入手,了解 Java 分布式编程的基本概念和方法。
- 掌握 RMI 后,可以进一步学习 CORBA,了解跨语言分布式计算的原理和实现。
- 最后,可以学习 EJB,深入了解企业级分布式应用的开发和管理。
总之,分布式计算技术是一个不断发展和演进的领域,开发者需要不断学习和实践,才能跟上技术的发展步伐,构建出高效、稳定的分布式系统。
超级会员免费看
1477

被折叠的 条评论
为什么被折叠?



