43、Java组件通信与服务集成技术解析

Java组件通信与服务集成技术解析

1. Java组件与外部组件通信技术

在实现Java组件与其他应用或系统中的外部组件通信时,有多种技术可供选择。这些技术基于不同的需求和场景,各有其特点和优势。

1.1 套接字(Sockets)

套接字是本章讨论的所有其他技术的基础。借助TCP/IP协议,套接字能在网络上提供可靠的字节流,任何具备套接字API的语言都能使用。它是进程间通信的底层方式,但仅靠套接字本身并不能保证两个不同组件之间的通信,还需要共同遵循一种协议。例如,在实现HTTP规范的一小部分时,我们能体会到实现一个协议的复杂性。以下是对套接字特点的总结:
- 基础构建块 :为其他通信技术提供基础。
- 可靠字节流 :通过TCP/IP在网络上传输数据。
- 依赖协议 :需要共同的协议才能实现通信。

1.2 RMI、CORBA和Web服务

RMI(远程方法调用)、CORBA(公共对象请求代理体系结构)和Web服务都构建在套接字和TCP/IP之上。RMI和CORBA实现了复杂的协议,能提供可靠性、会话、事务和事件回调等功能,是许多现有企业系统的核心技术。Java EE广泛使用RMI,因为RMI与JNDI(Java命名和目录接口)结合,可使系统对象在多台机器上透明分布,而无需修改应用程序代码。此外,RMI在添加了对CORBA的IIOP协议的支持后,与CORBA在一定程度上实现了互操作性,便于开发者将遗留的CORBA系统集成到现代Java EE系统中。
| 技术 | 特点 |
| ---- | ---- |
| RMI | 实现复杂协议,提供多种功能,与Java EE结合紧密 |
| CORBA | 实现复杂协议,具备多种特性,与RMI有一定互操作性 |
| Web服务 | 简单机制,便于信息共享,未来分布式计算的趋势 |

1.3 技术选择与应用场景

不同的技术适用于不同的场景,没有一种技术天生就比其他技术更好,需要根据具体的工作选择合适的工具。
- 套接字 :提供底层API,可用于优化和创建新协议,适用于远程控制外部硬件等项目。
- RMI和CORBA :为分布式系统提供强大的基础,理解它们对于充分发挥Java EE的功能至关重要。在分布式系统中,还需考虑远程方法调用的网络延迟问题。
- Web服务 :是现有Web门户的补充,将成为万维网上信息共享的简单机制,不仅供人类查看,还供机器使用。随着系统和信息集成变得更加容易,以信息为中心的新型应用将不断涌现。

Web服务是分布式计算的未来,它能使当前无结构信息的万维网向结构化信息的方向发展。虽然Web服务在技术上不如RMI或CORBA先进,但它的简单性具有强大的优势。实现Web服务所需的开发工作量最小,且其底层协议都是人类可读的,便于调试。随着OASIS WS - *标准的发展,Web服务有望支持事务、可靠消息传递和更强的安全模型。当WSIT和微软的Indigo等项目成熟时,下一代Web服务的目标将成为现实。

2. 面向服务的集成

在当今的企业环境中,大多数公司都有大量的遗留IT投资,其系统是随着时间的推移为满足特定需求而开发的。随着企业IT基础设施的发展,数据共享和打破信息孤岛变得越来越必要,面向服务的集成应运而生。

2.1 面向服务的架构(SOA)

SOA是一种更稳定的系统设计架构,它通过重用核心业务功能来适应随时间的变化。在SOA中,公司通过围绕现有应用程序创建服务层来充分利用其IT投资。这些服务为跨企业的应用程序功能提供了标准接口,多种使能技术推动了这种设计的实现。

graph LR
    classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
    A(企业应用):::process --> B(服务层):::process
    B --> C(标准接口):::process
    C --> D(跨企业功能):::process
2.2 使能技术

以下三种API在构建面向服务的架构中起着重要作用:
| API | 相关性 |
| ---- | ---- |
| Web服务和XML技术 | 是面向服务架构的公开面,定义了两个系统之间的信息契约 |
| Java管理扩展(JMX) | 提供服务基础设施,用于在网络上部署和管理应用程序 |
| Java消息服务(JMS) | 通过消息端点实现信息的位置无关处理 |

由于Web服务在其他部分已有介绍,这里重点关注JMX和JMS在集成方面的应用。

3. Java管理扩展(JMX)

JMX是一种用于管理和监控应用程序系统及网络设备的技术。它允许将称为MBean的专用Java类部署到软件代理中,并在运行时与它们进行交互。

3.1 JMX的重要性

自JDK 1.5起,JMX成为Java平台的标准部分,也是许多J2EE应用服务器(如JBoss、Websphere和Weblogic)的基础。理解JMX技术有助于开发者使用这些产品,并开发自己的扩展。

3.2 JMX架构

JMX由三层架构组成,每层在创建可管理资源方面都有各自的职责:
| 层 | 描述 |
| ---- | ---- |
| 仪器层(Instrumentation) | 定义要在JMX架构中管理的资源,即MBean,可以是应用程序、服务或网络设备等 |
| 代理层(Agent) | 提供管理、部署、事件通知和监控的基础设施,所有与被管理资源的通信都通过该层进行,最主要的组件是MBeanServer |
| 远程管理层(Remote Management) | 通过指定协议适配器和连接器定义与代理的外部通信,适配器允许客户端应用程序与MBeanServer通信,MBeanServer必须部署至少一个适配器 |

graph LR
    classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
    A(仪器层):::process --> B(代理层):::process
    B --> C(远程管理层):::process
    B --> D(MBeanServer):::process
    C --> E(适配器):::process
    E --> F(客户端应用):::process
3.3 创建和管理标准MBean

下面通过一个简单的例子来说明如何创建和管理标准MBean。
1. 创建管理Bean接口 :定义一个符合MBean规范的接口,例如 WorkerMBean

package wrox.ch12.jmx;
public interface WorkerMBean {
    public boolean isRunning(); 
    public void setRunning(boolean running); 
    public void start();
    public void stop(); 
    public String calcGreeting( ); 
}
  1. 实现接口 :实现类需要遵循以下规则:
    • 与MBean接口在同一包中。
    • 类名与接口名相同,但去掉 MBean 后缀,这里是 Worker
    • 具有公共的无参数构造函数。
package wrox.ch12.jmx;
import java.util.Calendar;
public class Worker implements WorkerMBean {
    boolean running = false;
    public boolean isRunning() {
        return running;
    }
    public void setRunning(boolean running) {
        this.running = running;
    }
    public void start() {
        running = true;
    }
    public void stop() {
        running = false;
    }
    public String calcGreeting() {
        if (!isRunning())
            return "not available";
        Calendar time = Calendar.getInstance();
        if (time.get(Calendar.AM_PM) == 0) {
            return "good morning";
        } else {
            return "good evening";
        }
    }
}
  1. 部署MBean到MBeanServer :请求运行的JVM中的MBeanServer,创建一个 ObjectName 来引用MBean,并将其注册到MBeanServer中。
package wrox.ch12.jmx;
import java.lang.management.ManagementFactory;
import javax.management.MBeanServer;
import javax.management.ObjectName;
public class Agent {
    public static void main(String[] args) {
        Worker worker = new Worker();
        MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
        try {
            ObjectName name = new ObjectName("wrox.ch12.jmx:type=Worker");
            mbs.registerMBean(worker, name);
            System.out.println("Agent Started..");
            Thread.sleep(Long.MAX_VALUE);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
  1. 运行代理并连接到管理控制台
    • 启动代理: C:\> Java -Dcom.sun.management.jmxremote wrox.ch12.jmx.Agent
    • 启动控制台: C:\>jconsole
    • 在JConsole中选择本地连接,并选择启动的代理 wrox.ch12.jmx.Agent
    • 选择 MBeans 选项卡,与部署的MBean进行交互。

通过以上步骤,我们可以实现对Java对象的状态监控和操作,展示了JMX在管理和监控方面的强大功能。

Java组件通信与服务集成技术解析

4. JMX管理

JMX技术由两个JSR(Java Specification Requests)定义:
- JSR 003:Java Management Extensions (JMXTM) Specification API 1.2
- JSR 160:Java Management Extensions (JMX) Remote API 1.0

下面将通过几个示例来展示JMX API的管理功能。

4.1 远程代理(RemoteAgent)

远程代理使用 javax.management javax.management.remote 包,通过创建一个连接器服务器来接收外部进程的请求。以下是实现代码:

package wrox.ch12.jmx;
import javax.management.MBeanServer;
import javax.management.MBeanServerFactory;
import javax.management.remote.JMXConnectorServer;
import javax.management.remote.JMXConnectorServerFactory;
import javax.management.remote.JMXServiceURL;

public class RemoteAgent {
    public static void main(String[] args) throws Exception {
        MBeanServer mbs = MBeanServerFactory.createMBeanServer(); 
        JMXServiceURL url = new
            JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9999/server");
        JMXConnectorServer server = JMXConnectorServerFactory.newJMXConnectorServer(url,
            null, mbs);
        System.out.println("starting rmi connector server");
        server.start(); 
    }
}

操作步骤如下:
1. 启动RMI注册表: C:\>rmiregistry 9999 &
2. 启动代理: c:\>java wrox.ch12.jmx.RemoteAgent
3. 使用JConsole连接到代理,选择远程连接,并指定连接字符串: service:jmx:rmi:///jndi/rmi://localhost:9999/server

4.2 远程客户端(RemoteClient)

远程客户端用于连接到远程代理,并对部署在MBeanServer上的MBeans进行操作。以下是实现代码:

package wrox.ch12.jmx;
import java.util.Iterator;
import java.util.Set;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;
import javax.management.Query;
import javax.management.QueryExp;
import javax.management.remote.JMXConnector;
import javax.management.remote.JMXConnectorFactory;
import javax.management.remote.JMXServiceURL;

public class RemoteClient {
    MBeanServerConnection connection = null;

    public RemoteClient() throws Exception {
        JMXServiceURL url = new JMXServiceURL(
            "service:jmx:rmi:///jndi/rmi://localhost:9999/server");
        JMXConnector connector = JMXConnectorFactory.connect(url);
        connection = connector.getMBeanServerConnection();
    }

    void deploy() throws Exception {
        connection.createMBean("wrox.ch12.jmx.Worker", 
            new ObjectName("wrox.ch12.jmx:type=Worker,number=1"));
        connection.createMBean("wrox.ch12.jmx.Worker", 
            new ObjectName("wrox.ch12.jmx:type=Worker,number=2"));
        connection.createMBean("wrox.ch12.jmx.Worker", 
            new ObjectName("wrox.ch12.jmx:type=Worker,number=3"));
    }

    void lookup() throws Exception {
        ObjectName on = new ObjectName("wrox.ch12.jmx:*");
        Set set = connection.queryNames(on, null);
        for (Iterator iter = set.iterator(); iter.hasNext();) {
            ObjectName bean = (ObjectName) iter.next();
            System.out.println("deployed..=" + bean.toString());
        }
    }

    void checkRunning() throws Exception {
        ObjectName on = new ObjectName("wrox.ch12.jmx:*");
        QueryExp exp = Query.eq(Query.attr("Running"), Query.value(true));
        Set set = connection.queryNames(on, exp);
        for (Iterator iter = set.iterator(); iter.hasNext();) {
            ObjectName bean = (ObjectName) iter.next();
            System.out.println("running.. MBean =" + bean.toString());
        }
    }

    void remove() throws Exception {
        ObjectName on = new ObjectName("wrox.ch12.jmx:*");
        Set set = connection.queryNames(on, null);
        for (Iterator iter = set.iterator(); iter.hasNext();) {
            ObjectName bean = (ObjectName) iter.next();
            System.out.println("removing..=" + bean.toString());
            connection.unregisterMBean(bean);
        }
    }

    public void addMonitor( ) throws Exception {
        connection.createMBean("javax.management.monitor.StringMonitor", new
            ObjectName("wrox.ch12.jmx:name=WorkMonitor")); 
    }

    public static void main(String[] args) throws Exception {
        RemoteClient rc = new RemoteClient();
        rc.remove();
        rc.deploy(); 
        rc.lookup(); 
        rc.checkRunning();
        rc.addMonitor();
    }
}

操作步骤如下:
1. 创建远程客户端实例,连接到远程代理。
2. 调用 deploy() 方法部署三个 Worker MBeans。
3. 调用 lookup() 方法查询部署在 wrox.ch12.jmx 域的所有MBeans。
4. 调用 checkRunning() 方法查询 Running 属性为 true 的MBeans。
5. 调用 remove() 方法移除部署在 wrox.ch12.jmx 域的所有MBeans。
6. 调用 addMonitor() 方法添加一个 StringMonitor MBean。

4.3 工作监视器(WorkMonitor)

工作监视器用于跟踪 WorkerMBean 属性的变化。通过管理控制台可以设置监视器的属性,当属性发生变化时,监视器会向控制台发送通知。操作步骤如下:
1. 使用 addObservedObject() 方法添加要监控的 WorkerMBean ObjectName ,例如 wrox.ch12.jmx:type=Worker,number=2
2. 通过 ObservedAttribute 设置要监控的属性,这里是 Status 属性。
3. 设置 StringToCompare 属性,指定要监控的值。

graph LR
    classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
    A(RemoteAgent):::process --> B(RemoteClient):::process
    B --> C(WorkerMBeans):::process
    B --> D(WorkMonitor):::process
    D --> E(监控属性变化):::process
    E --> F(发送通知):::process
5. Java消息服务(JMS)

虽然在前面的内容中没有详细介绍Java消息服务(JMS),但它是SOA中用于通过消息导向中间件(MOM)实现系统松散集成的重要技术。JMS提供了位置无关的信息处理方式,通过消息端点进行信息的传递。

在SOA中,JMS可以与JMX结合使用,使JMX组件实现消息驱动。例如,当MBean的状态发生变化时,可以通过JMS发送消息通知其他组件,从而实现系统的异步通信和松散耦合。

6. 总结

本文介绍了Java组件与外部组件通信的多种技术,包括套接字、RMI、CORBA和Web服务,并分析了它们的特点和适用场景。同时,详细阐述了面向服务的集成和面向服务的架构(SOA),以及在SOA中起重要作用的使能技术,如JMX和JMS。

通过具体的示例,展示了如何创建和管理标准MBean,以及如何使用JMX API进行远程管理和监控。这些技术和方法为构建分布式系统和实现系统集成提供了强大的支持,有助于开发者更好地应对企业级应用中的各种挑战。

在实际应用中,开发者应根据具体的需求和场景选择合适的技术,并结合使用不同的技术来实现系统的高效、稳定和可扩展。随着技术的不断发展,分布式计算和系统集成将变得更加容易和高效,为企业带来更多的价值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值