JMS初步研究与其他消息服务集成技术的对比

来源:互联网 发布:域名注册公司有哪些 编辑:程序博客网 时间:2024/05/16 03:48

JMS in practice

Author : (丁宏亮)David

                Email :  hongliang.dinghl@alibaba-inc.com

Outline

§   什么是消息服务

§   为什么使用消息服务

§   什么是JMS(Java Message Service)

§   JMS的通信方式

§   JMS应用程序开发步骤

§   JMS应用程序开发实践

§   其他的JMS特性

§   SpringJMS的集成,JMSMDB的关系

§   JMSTask,RMI,CORBA,WEB SERVICE的区别

什么是消息服务

1. 消息服务是支持松耦合分布式通信的对等通信机制。

2. 消息服务支持软件组件或应用程序之间松耦合分布式通信。

3.支持的数据可以是文本,数值,若是Java应用程序之间的通信,数据

  可以包含对象。

4.组件或应用程序之间不一定同时运行

为什么使用消息服务

1.松散耦合但高内聚

2.避免直接通信

3.保证消息传递

4.异步通信

5.一对多,多对多,多对一通信

什么是JMS

JMS(Java 消息服务)是一组标准的API,能够用于访问多种消息服务器。它试图提供一套标准,统一的接口,这套接口适用于多种不同供应商的消息服务器,在这个意义上 ,它和JDBC以及JNDI是相似的。那些消息服务器一般都有自己的本机接口,用本机接口可以直接访问消息服务器。但是,使用本机接口的代码不仅可移植性差,而且每当您希望使用另一个消息服务时,都要学习新的API。而使用JMS,你可以使用一样的API访问IBMMQSeries消息服务和 JBossMQ消息服务。准许开发者避免使用各供应商特定的API,这当然是JMS的一大 优点。

 

 

 

 

 

 

 

1.什么是JMS中的消息

  • 消息这个术语在计算机系统中含义非常广泛,它被用来描述不同的操作系统概念,它被用来描述邮件和传真。而在这里,它指的是用于企业应用间的异步通讯。
  • 这里所说的“消息”是指被企业应用而不是人所消费的异步的请求、报告以及事件。消息中包含了重要的用来系统间进行协作的信息。消息中包含了精确的数据格式以描述特定的业务活动,通过应用系统之间的消息交互,使得企业业务过程能够保持一致。

2.JMS中的消息的基本结构

  • 2.1 消息头
  • 2.2 消息属性
  • 2.3 消息体

 

 

2.1 消息头

 消息头包含标准的,必不可少的消息信息,比如每个消息都有个ID,一个优先级,一个时间戳,一个目标。这些信息大部分都在消息发送到目标之前自动设定。消息头可以通过get set方法存取.形式如:setJMSHeaderName,getJMSHeaderName

2.2  消息属性

   消息属性是标准的,特定于供应商或特定于应用程序的可选的消息信息,主要作用是帮助消息过滤,消息属性在接收的客户机里是只读的。

2.3 消息体

   消息体是实际的消息内容。JMS支持多种格式的消息体。比如:TextMessage,MapMessage,BytesMessage,StreamMessage,ObjectMessage

3.JMS由那些应用部分组成

  • JMS客户端 :用来发送和接收消息的Java语言程序。
  • JMS客户端:这些客户端是用消息系统的本地客户端API编写的,而不是JMS。如果应用先于JMS出来之前,那么它可能会既包括JMS客户端,也包括非JMS客户端。
  • Messages(消息):每个应用定义了用于在客户端之间进行通讯的消息。
  • JMS Provider JMS提供者):实现了JMS规范的消息系统,该系统还提供必须的用于管理和控制全方位的功能。
  • Administered Objects(被管理的对象):是预先配置的JMS对象,由系统管理员为使用JMS的客户端创建。

4.如何实现JMS客户端程序的跨平台性?

  •     由于有很多JMS 消息系统,它们的底层实现技术各不相同,比如Sun MQ, IBM MQ,BEA MQ,Apache ActiveMQ,那么如何使得JMS客户端针对这些消息系统编程时能够隔离这些产品的变化而具有跨平台特性呢?那就是通过定义被管理的对象来实现。被管理的对象是由管理员通过使用JMS系统提供者的管理工具创建和定制,然后被JMS客户端使用。JMS客户端通过接口来调用这些被管理的对象,从而具备跨平台特性。

主要有两个被管理的对象:

  • ConnectionFactory 这是客户端用来创建同JMS提供者之间的连接的对象。
  •  Destination :这个对象是客户端用来指明消息被发送的目的地以及客户端接收消息的来源。被管理的对象一般被管理员放在JNDI名字空间中,通常在JMS客户端应用的文档中说明它所需要的JMS被管理对象,以及应以何种JNDI名字来提供这些JMS被管理对象。

下图是被管理对象的关系:

 

 

 

 

JMS的通信方式

  • 传统的消息服务一般支持点对点通信和发布/订阅通信两种通信模式中的一种。JMS API对两种模式都支持。
  •  1.点对点通信
  •  2.发布/订阅通信

1.点对点通信

 

 

 

2.发布/订阅通信

 

 

JMS应用程序开发步骤

  • 1.点对点JMS应用程序开发步骤
  • 1.1 使用特定于服务器的机制发布目标(队列)。在JBOSS,这是通过jbossmq-destinations-service.xml文件完成的。本质上,JNDI条目是为目标而注册的。
  • 1.2 定义产生消息的客户机
  • 1.3 定义接收消息的客户端
  • 1.4 启动消息服务器
  • 1.5 编译并启动客户端      

点对点JMS应用程序模型

 

 

 

 

  • 2.发布/订阅JMS应用程序开发步骤
  • 1.1 使用特定于服务器的机制发布目标(主题)
  • 1.2 定义发布消息的客户机
  • 1.3 定义订阅主题的客户端
  • 1.4 启动消息服务器
  • 1.5 编译并启动客户端

发布/订阅JMS应用程序模型

 

 

 

 

JMS API 编程模型

 

 

 

JMS api 类图关系

 

 

JMS应用程序开发实践

 

其他的JMS特性

  • 1.指定消息的持久性
  • 2.设置消息优先级
  • 3.定义消息持续的时间
  • 4.持久订阅
  • 5.主题消息选择器
  • 6.客户端验证
  • 7.事务

SpringJMS的集成

1.提供JMS抽象API,简化了访问目标(队列或主题)和向指定目标发布消息时JMS的使用。

2.开发人员不需要关心JMS不同版本(例如JMS 1.0.2JMS 1.1)之间的差异。

3.开发人员不必专门处理JMS异常,因为Spring为所有JMS异常提供了一个未经检查的异常,并在JMS代码中重新抛出。

JMSMDB的关系

由于消息驱动Bean架构在Java消息服务(JMS)技术之上。

实现接口:MssageDrivenBeanMessageListener.

 

 

 

JMSTask,RMI,CORBA,WEB SERVICE的区别

  • 1.Task 任务调度完成消息集成 ,使用集中消息数据库。
  • 2.CORBA需要许多分布式组件的支持。
  • 3.RMI 需要编写存根类。
  • 4.WEB Service 门槛太高,需要UDDI,SOAP,WSDL的支持。
  • 官方参考http://java.sun.com/javaee/5/docs/tutorial/doc/bncdq.html

   代码示例:

   消息发送端:

   

  1. package com.alisoft.demo;
  2. import java.util.Properties;
  3. import javax.jms.JMSException;
  4. import javax.jms.Queue;
  5. import javax.jms.QueueConnection;
  6. import javax.jms.QueueConnectionFactory;
  7. import javax.jms.QueueSender;
  8. import javax.jms.QueueSession;
  9. import javax.jms.Session;
  10. import javax.jms.TextMessage;
  11. import javax.naming.Context;
  12. import javax.naming.InitialContext;
  13. import javax.naming.NamingException;
  14. public class QueueWrite {
  15. private QueueConnection qc=null;
  16. private Context context=null;
  17. public static void main(String args[]){
  18.     QueueWrite queueWrite=new QueueWrite();
  19.     queueWrite.init();
  20.     queueWrite.sendMessage();
  21.     
  22. }
  23. public void init(){
  24.     try {
  25.         System.out.println("...init context begin...");
  26.         Properties env=new Properties();
  27.         env.put(Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory");
  28.         env.put(Context.PROVIDER_URL,"jnp://127.0.0.1:1099");
  29.         env.put(Context.URL_PKG_PREFIXES, "org.jboss.naming");
  30.         context=new InitialContext(env);
  31.         QueueConnectionFactory qcf=(QueueConnectionFactory)context.lookup("ConnectionFactory");
  32.         qc=qcf.createQueueConnection();
  33.         System.out.println("...init context end...");
  34.     } catch (NamingException e) {
  35.         e.printStackTrace();
  36.     } catch (JMSException e) {
  37.         e.printStackTrace();
  38.     }
  39. }
  40. public void sendMessage(){
  41.     try {
  42.         QueueSession qs=qc.createQueueSession(false,Session.AUTO_ACKNOWLEDGE);
  43.         Queue q=(Queue)context.lookup("queue/B");
  44.         QueueSender sender=qs.createSender(q);
  45.         TextMessage message=qs.createTextMessage();
  46.         for(int i=0;i<100;i++){
  47.             message.setText("www.alisoft.com--->"+i);
  48.             sender.send(q,message);
  49.         }   
  50.         qc.close();
  51.     } catch (JMSException e) {
  52.         e.printStackTrace();
  53.     } catch (NamingException e) {
  54.         e.printStackTrace();
  55.     }
  56. }
  57. }

     消息接收端:

 

  

  1. package com.alisoft.demo;
  2. import java.util.Properties;
  3. import javax.jms.JMSException;
  4. import javax.jms.Message;
  5. import javax.jms.Queue;
  6. import javax.jms.QueueConnection;
  7. import javax.jms.QueueConnectionFactory;
  8. import javax.jms.QueueReceiver;
  9. import javax.jms.QueueSession;
  10. import javax.jms.Session;
  11. import javax.jms.TextMessage;
  12. import javax.naming.Context;
  13. import javax.naming.InitialContext;
  14. import javax.naming.NamingException;
  15. public class QueueRead {
  16.     private QueueConnection qc=null;
  17.     private Context context=null;
  18. public static void main(String args[]){
  19.     QueueRead queueRead=new QueueRead();
  20.     queueRead.initContext();
  21.     queueRead.ReceiveMessage();
  22. }
  23. public void initContext(){
  24.     try {
  25.         System.out.println("...init context begin...");
  26.         Properties env=new Properties();
  27.         env.put(Context.INITIAL_CONTEXT_FACTORY,"org.jnp.interfaces.NamingContextFactory");
  28.         env.put(Context.PROVIDER_URL,"jnp://127.0.0.1:1099");
  29.         env.put(Context.URL_PKG_PREFIXES, "org.jboss.naming");
  30.         context=new InitialContext(env);
  31.         QueueConnectionFactory qcf=(QueueConnectionFactory)context.lookup("ConnectionFactory");
  32.         qc=qcf.createQueueConnection();
  33.         System.out.println("...init context end...");
  34.     } catch (NamingException e) {
  35.         e.printStackTrace();
  36.     } catch (JMSException e) {
  37.         e.printStackTrace();
  38.     }
  39. }
  40. public String ReceiveMessage(){
  41.     StringBuffer sb=new StringBuffer();
  42.     TextMessage text=null;
  43.     try {
  44.         QueueSession qs=qc.createQueueSession(false,Session.AUTO_ACKNOWLEDGE);
  45.         Queue q=(Queue)context.lookup("queue/B");
  46.         QueueReceiver qr=qs.createReceiver(q);
  47.         qc.start();
  48.         
  49.             Message m=qr.receive(1);
  50.             while(m!=null){
  51.             
  52.                 if (m instanceof TextMessage){
  53.                      text=(TextMessage)m;
  54.                     System.out.println("message:"+text.getText());
  55.                 }
  56.             sb.append(text.getText()+"/r/n");
  57.             m=qr.receive(1);
  58.         }
  59.         
  60.     } catch (JMSException e) {
  61.         e.printStackTrace();
  62.     } catch (NamingException e) {
  63.         e.printStackTrace();
  64.     }
  65.     System.out.println(sb.toString());
  66.     return sb.toString();
  67. }
  68. }

 

 

 

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 断奶时乳房有肿块怎么办 孩子断奶后乳房变小怎么办 断奶了月经不来怎么办 钥匙在门上拔不出来怎么办 钥匙拔不下来了怎么办 养了几天鱼死了怎么办 乌龟的眼睛肿了怎么办 手被鱼刺扎了怎么办 被鱼刺扎手肿了怎么办 手被桂鱼扎了怎么办 三岁宝宝卡鱼刺怎么办 一岁宝宝卡鱼刺怎么办 鱼刺卡在胸口了怎么办 婴儿被鱼刺卡了怎么办 幼儿被鱼刺卡到怎么办 鱼刺被吞下去了怎么办 喉咙卡到鱼刺下不去怎么办 被小鱼刺卡了怎么办 晚上被鱼刺卡到怎么办 一个小鱼刺卡了怎么办 卡了一个小鱼刺怎么办 鱼刺卡在气管里怎么办 刺蛾幼虫 蛰了怎么办 被杨树辣子蛰了怎么办 蜇了老子蜇了怎么办 被刺蛾幼虫蛰了怎么办 孕妇被蚊虫叮咬发痒怎么办 白掌叶子尖发黄怎么办 白掌叶子卷了怎么办 白掌叶子全软了怎么办? 发财树有黄斑了怎么办 幸福树叶子蔫了怎么办 幸福树枝条塌了怎么办? 幸福树叶子嫣了怎么办 毒蚊子叮咬肿硬怎么办 被蚊子咬了很痒怎么办 蚊子咬了脚肿了怎么办 小孩被蚊子咬了怎么办 小狗老喜欢咬人怎么办 狗狗喜欢咬手怎么办 成年猫喜欢咬人怎么办