`
guilin20
  • 浏览: 10284 次
  • 性别: Icon_minigender_1
  • 来自: 上海
最近访客 更多访客>>
社区版块
存档分类
最新评论

实战JMS (转)

    博客分类:
  • java
阅读更多
近日开发一个Message Driven Bean实现的异步计算功能,整理之后希望可以和各位正在做MDB或者JMS开发的朋友分享一下。

这是一个MIS系统的一部分,用于计算最后的收费金额,由于计算过程及其复杂,要求实现不影响用户接口响应,就是要实现异步计算,同时可以处理多个计算请求,计算结束后通知发出计算命令的客户端。功能十分简单,只要一个MDB就可以实现了,但是要通知客户端计算结束使得系统变得有趣多了。

JMS API
在进行系统设计之前我们先回头熟悉一下JMS的一些概念。JMS源于企业应用对于消息中间件的需求,使应用程序可以通过消息进行异步处理而互不影响。JMS应用程序有四个组成部分:JMS服务提供者、消息管理对象、消息的生产者消费者和消息本身。

l         JMS服务提供者实现消息队列和通知,同时实现消息管理的API。JMS已经是J2EE API的一部分,J2EE服务器都提供JMS服务。

l         消息管理对象提供对消息进行操作的API。JMS API中有两个消息管理对象:ConnectionFactory和Destination,根据消息的消费方式的不同ConnectionFactory可以分为QueueConnectionFactory和TopicConnectionFactory,Destination可以分为Queue和Topic。用这两个管理对象可以建立到消息服务的会话。

l         消息的生产者和消费者。它们可以毫不相干,只需要消息的消费者知道如何使用消息即可。根据消息消费者数目的不同,消息的消费者分为两类:subscriber 和receiver,同样消息发送者也分为两类:Publisher和Sender。

l         消息。JMS API规定了五种消息:Message、MapMessage、TextMessage、ByteMessage、StreamMessage和ObjectMessage

消费形式的不同造成JMS有两组平行的API,这就是JMS的PTP(point to point)模型和PUB/SUB(publisher和subscriber、出版和订阅)模型。PTP的消息应用中一个消息只有一个消费者,消费后该消息即不再有效。而PUB/SUB应用中一个消息可以有多个订阅者,而且每个订阅者不一定非要处理该消息。

下面是JMS应用的基本模型:


(该图引自sun的在线文档 JMS Tutorial)

根据该模型列出JMS中几个最长用的API:

l         QueueConnectionFactory和TopicConnectionFactory 连接工厂用来生成QueueConnection和TopicConnection的实例

l         QueueConnection和TopicConnection连接对象用来建立到JMS的连接并生成会话实例

l         QueueSession和TopicSession会话对象用来创建消息、消息的生产者和消息的消费者(解释一下消息的生产者:它并不代表生成消息实例的对象而是指将消息发送到JMS的对象)

l         QueueSender、TopiCPUblisher和QueueReciever、TopicSubscriber。消息的生产者和消费者,QueueSender的send方法和TopicPublisher的publish方法发送消息到Destination。QueueReciever和TopicSubscriber直接使用父接口MessageConsumer中定义的方法receive、recieveNoWait等方法来接收消息,setMessageListener方法来设置消息监听器。QueueReciever的getQueue方法得到Queue的引用,TopicSubscriber的getTopic方法得到Topic的引用。

l         MessageListener,消息监听器。改接口只有一个方法onMessage(),改方法只有一个Message类型的参数,通过MessageConsumer(QueueReciever和TopicSubscriber共同的父接口)的setMessageListener方法注册后,系统在收到消息后调用改方法。

l         Queue和Topic,消息Destination。主要的作用就是存储消息。

设计
系统过于简单就不设计了,这里简单交代一下软件的运行环境和执行流程,这个MIS系统是B/S模式的,Web Browser在完成添加执行任务(保存到数据库)的工作后要发一个消息给计算程序,这个计算过程就实现成MDB,计算结束后将完成的消息发给生成任务的Web Browser,各位不要以为我真的能这样做,主动式的把消息发送给Web Browser笔者还没有这份功力,这里采用了一个取巧的方法:在Web页中使用一个Applet,该Applet本身也是一个一直运行的线程,并且每隔一段时间访问接收消息的Servlet,如果有收到消息则提示用户。这个Servlet就是一个MessageConsumer了,而MDB就是MessageProducer了。而在产生执行任务的时候,保存执行任务的JSP/servlet则是MessageProducer,而运行MDB的EJB Container则成了MessageCunsumer,MDB则成为一个消息监听器。由于有两种消息笔者偷懒就使用了两个Destination(跟上面图不谋而合,哈哈),一个用来存放执任务的消息,一个用于存放任务完成的消息。具体实现当然有消息内容的设计和实现,不过对于系统结构并不影响,这里就不废话了。

开发工具是JBuilder和WebLogic。

动手实现
1.         发送和接收消息。需要使用JMS API手动编码实现发送和接收消息的有三个地方:发送消息的Servlet、接收消息的Servlet和发送计算完成消息的MessageDrivenBean。对于发送和接收消息都需要的QueueConnectionFactory、QueueConnection、Queue和QueueSession等对象则利用Servlet和MDB的生命周期方法获得和释放,在Servlet的init方法和MDB的ejbCreate方法中获得资源并创建需要的对象,在Servlet的destroy和MDB的ejbRemove方法中释放资源。

获得资源:

public void init() throws ServletException {
    try{
      InputStream in = this.getClass().getClass().getClassLoader().
          getResourceAsStream("jndi.properties");
      Properties p = new Properties();
      p.load(in);
      ctx = new InitialContext(p);
    }catch(Exception ex){
      ex.printStackTrace();
    }
    try{
      connectionFactory = (QueueConnectionFactory) ctx.lookup(
          connectionFactoryName);
      queue = (Queue) ctx.lookup(queueName);
      connection = (Javax.jms.QueueConnection) ( (QueueConnectionFactory)
                                                connectionFactory).
          createQueueConnection();
      queueSession = ( (javax.jms.QueueConnection) connection).
          createQueueSession(false, Session.AUTO_ACKNOWLEDGE);
         queueSender = queueSession.createSender(queue);
    }catch(Exception ex){
      ex.printStackTrace();
    }


  }

发送消息:

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       String taskid = request.getParameter("taskid");
    try{
      String completedmsg = "任务" + taskid + "执行完成";
      ObjectMessage om = queueSession.createObjectMessage(new CalculateCompleted(userid, taskid, completedmsg));
      queueSender.send(om);
    }catch(Exception ex){
      ex.printStackTrace();
    }

  }

接收消息。这里对消息在Servlet中作了转存,messages是一个Hashtable对象。

public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
       boolean rflag = true;
    try {
      messageConsumer = (QueueReceiver) queueSession.createReceiver(queue);
      connection.start();
      while (rflag) {
        Message m = messageConsumer.receiveNoWait();
        if (m != null) {
          if (m instanceof ObjectMessage) {
            ObjectMessage message = (ObjectMessage) m;
            MessageBody mb = (MessageBody)message.getObject();
            ArrayList a = (ArrayList)messages.get(mb.getUserID());
            if(a == null){
              a = new ArrayList();
              a.add(mb);
              messages.put(mb.getUserID(), a);
            }else{
              a.add(mb);
            }
          }
          else {
            rflag = false;
          }
        }
        else {
          rflag = false;
        }
      }
      connection.stop();
    }
    catch (JMSException e) {
      e.printStackTrace();
    }

  }

释放资源:

public void destroy() {
    try{
      if(connection != null)connection.close();
    }catch(Exception ex){
      ex.printStackTrace();
    }

  }

MDB的jebCreate方法和上面init方法的内容一样,ejbRemove和上面destroy方法的内容相同。MDB的计算过程实现在onMessage()方法中,计算完成后发送一条消息,发送消息的过程上面已有,不再赘述。

2.         WebLogic的JMS服务配置。这里使用最简单的JMS配置,除了名字和JNDI名其余的均使用缺省值。

a)         启动WebLogic,打开web console

b)        展开左侧的JMS节点,新建一个JMS Server。名字随意。


c)        为刚建立的JMS Server建立两个Queue。JNDI名分别为::jms/calculate和jms/completed。


d)        建立一个ConnectionFacotry。JNDI名:jms/conn_factory

3.         配置MDB。这里除了要指定MDB监听的Queue外,因为MDB需要向另外的Queue发送计算成功的消息,还需要把上面WebLogic中配置的jms/conn_factory作为资源添加到MDB的resource-ref中,把jms/completed作为环境资源添加到MDB的resource-env-resource中。

4.         部署执行。用JBuilder建立一个EAR然后部署,非常简单。如果各位想要测试只需要建立一个简单的客户端应用程序,然后将MDB的onMessage方法简单实现为消息转发就可以了。

总结
笔者初学JMS,只能说说JMS最基本的应用。JMS是一组很强大的API,不仅可以在一个应用程序中实现异步通信,也常被用来在不同的应用程序间传递数据,同时JMS也支持分布式事务,达到了企业应用的要求,笔者相信随着学习和应用的不断深入,将会发现JMS更强大的功能。
分享到:
评论

相关推荐

    JMS 实战 示例

    Java消息服务(Java Message Service,简称JMS)是Java平台中用于企业级应用间异步通信的标准接口。它允许应用程序创建、发送、接收和读取消息。在分布式系统中,JMS扮演着至关重要的角色,它能够实现组件间的解耦,...

    JMS教程

    七、实战示例 使用JMS API创建一个简单的点对点消息发送和接收程序,包括连接设置、会话创建、消息生产和消费等步骤。 八、JMS与微服务 在微服务架构中,JMS常用于服务间通信,实现解耦和异步处理。 总结,JMS是...

    Java网络编程--基于Spring的JMS编程

    文件"基于Spring的JMS编程-1"可能包含了关于如何在Spring环境中配置和使用JMS的详细步骤,包括XML配置、代码示例以及可能的实战项目案例。进一步学习这些内容,你将能够熟练掌握Spring框架下的JMS编程技巧,从而在...

    基于Java通讯开发jms源代码 (jms通讯开发源码)

    基于Java通讯开发jms源代码 (jms通讯开发源码) java,net,socket,通讯开发,jms /* * @(#)Message.java 1.60 02/04/09 * * Copyright 1997-2002 Sun Microsystems, Inc. All Rights Reserved. * * SUN ...

    JMS规范培训教程 中文版

    PDF文档中可能包含了以下章节:JMS简介、消息模型、消息格式、消息代理的配置与管理、JMS API详解、案例研究和实战演练等内容。通过学习这份教程,读者不仅可以了解JMS规范的理论,还能通过实例学习如何在实际项目中...

    JMS ACTIVEMQ 教程文档

    6. **实战案例** - **构建微服务通信**:使用JMS和ActiveMQ实现在微服务架构中的解耦通信。 - **事件驱动架构**:在事件驱动架构中,如何利用JMS和ActiveMQ实现事件的生产和消费。 这个教程将覆盖以上所有内容,...

    Spring JMS 消息处理-基于JNDI

    7. **实战示例**:最后,博主会提供一个实际的示例,展示如何在一个简单的Spring应用中集成JMS,包括创建JNDI资源、配置Spring容器以及测试发送和接收消息。 通过学习这篇博客,开发者可以了解到如何利用Spring JMS...

    实战EJB 实战EJB 实战EJB

    ### 实战EJB知识点解析 #### 一、企业JavaBeans (EJB) 技术概览 **什么是企业JavaBeans技术?** 企业JavaBeans (EJB) 是Java平台上的服务器端组件模型,专为构建可扩展、可靠且跨平台的企业级应用程序而设计。...

    基于JSONP+ngBind+ngRepea技术实战美玩网(BootStrap+AngularJS+JMS+Highcharts).rar

    分享课程——基于JSONP+ngBind+ngRepea技术实战美玩网(BootStrap+AngularJS+JMS+Highcharts);本教程主要从基础出发到项目的整体框架整合,整个大纲内容涉及面较为广泛,涉及到数据库技术,javaEE技术点,web框架...

    activeMq 实战

    ### ActiveMQ 实战 #### JMS 基本构件概览 **ActiveMQ** 是一个高性能、功能丰富的开源消息中间件,它实现了 **Java Message Service (JMS)** 规范。JMS 规范定义了一组接口,这些接口提供了一个标准的方式来进行...

    ActiveMQ 实战

    ActiveMQ实战手册以介绍JMS和ActiveMQ的操作及配置为主,JMS(Java Message Service)是Java平台中对于面向消息中间件(MOM)的一种标准的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。...

    经典Java EE企业应用实战:基于WebLogic/JBoss的JSF+EJB 3+JPA整合开发-利用JMS实现企业消息处理

    本实战教程将深入探讨如何在WebLogic和JBoss这两种流行的Java EE应用服务器上整合这些技术,并利用JMS(Java Message Service)实现企业级的消息处理。 JSF是一种用户界面框架,它简化了创建基于组件的Web应用程序...

    java开发实战经典

    12. **Java EE相关**:虽然不是Java SE的主要内容,但可能会涉及Servlet、JSP、EJB、JMS、JNDI等Java企业级应用技术。 13. **设计模式**:介绍常见的设计模式,如单例模式、工厂模式、装饰者模式、代理模式、观察者...

    Camel in action(camel实战)

    #### 四、Apache Camel 实战教程内容概述 - **核心概念** - 第一章介绍了 Camel 的基本概念,包括如何发送和接收消息,以及如何构建简单的路由逻辑。 - **路由与数据转换** - 第二章深入探讨了 Camel 中的路由...

    ActiveMQDemo实战.pdf

    综上所述,《ActiveMQDemo实战.pdf》涉及的知识点涵盖了消息队列的基本概念、ActiveMQ的基本使用、JMS API的编程模式、消息的生产与消费流程、以及消息服务的配置和安全性考虑。对于IT行业的专业人员来说,这些知识...

    JMS API中英文

    ### 实战案例 假设我们需要开发一个简单的股票交易系统,该系统需要实时更新股票价格并通知所有订阅者。在这种情况下,我们可以采用JMS的发布/订阅模式。首先,我们需要创建一个主题作为消息的目的地,然后通过消息...

    ActiveMQ实战资料

    **ActiveMQ实战资料详解** Apache ActiveMQ是Apache软件基金会开发的一款开源消息中间件,它是Java消息服务(Java Message Service,简称JMS)的一个实现。在分布式系统中,ActiveMQ扮演着至关重要的角色,它允许...

    深入掌握 JMS(java message service)

    通过以上理论知识的学习和实战案例的实践,我们可以更加深入地理解JMS的核心概念和技术细节。JMS作为一种成熟的消息中间件技术,在现代企业级应用中扮演着至关重要的角色。掌握了JMS的基本原理和使用方法后,开发者...

    Java EE核心框架实战

    《Java EE核心框架实战》是一本深度探讨Java企业级应用开发的实践指南,旨在帮助开发者掌握Java EE(以前称为J2EE)的核心技术,并能够运用这些技术构建高效、可扩展的分布式应用程序。这本书以实际案例为引导,通过...

Global site tag (gtag.js) - Google Analytics