(一)什么是JMS 
jms即Java消息服务(Java Message Service)应用程序接口是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。Java消息服务是一个与具体平台无关的API,绝大多数MOM提供商都对JMS提供支持。

(二)常见的JMS提供商有哪些?

  • IBM 的 MQSeries
  • BEA 的 Weblogic JMS service
  • Apache 的 ActiveMQ

本系列都采用ActiveMQ

(三)核心API 
JMS第一个版本是1998年制定的,最后一个版本是在2002年制定的JMS1.1。 
本文基于JMS1.1

  • JMS Provider 完全使用Java对JMS接口的一个实现,上面所说的三个就是
  • JMS Client 一个完全使用JMS编写的发送和接收消息的客户端(必然用Java实现)
  • Non-JMS Client 使用JMS提供商提供的本地客户端API编写收发消息,而不是JMS提供的API
  • JMS Producer 一个创建和发送JMS消息的客户端应用
  • JMS Consumer 一个接收并处理JMS消息的客户端应用
  • JMS Message JMS基础概念,JMS客户端发送和接收的消息
  • JMS Domains 两种类型的消息,分别为点对点(point-to-point)和发布/订阅(publish/subscribe)
  • Administered Object 对JMS对象进行配置

3.1 Provider

  1. package javax.jms;
  2. public interface MessageProducer {
  3. void setDisableMessageID(boolean value) throws JMSException;
  4. boolean getDisableMessageID() throws JMSException;
  5. void setDisableMessageTimestamp(boolean value) throws JMSException;
  6. boolean getDisableMessageTimestamp() throws JMSException;
  7. void setDeliveryMode(int deliveryMode) throws JMSException;
  8. int getDeliveryMode() throws JMSException;
  9. void setPriority(int defaultPriority) throws JMSException;
  10. int getPriority() throws JMSException;
  11. void setTimeToLive(long timeToLive) throws JMSException;
  12. long getTimeToLive() throws JMSException;
  13. Destination getDestination() throws JMSException;
  14. void close() throws JMSException;
  15. void send(Message message) throws JMSException;
  16. void send(Message message, int deliveryMode, int priority, long timeToLive)
  17. throws JMSException;
  18. void send(Destination destination, Message message) throws JMSException;
  19. void send(Destination destination, Message message, int deliveryMode,
  20. int priority, long timeToLive) throws JMSException;
  21. }

MessageProducer不仅提供了发送消息的方法,同时也提供了设置消息头部的方法(JMSDeliveryMode、JMSPriority、JMSExpiration、TimeToLive)

3.2 Consumer

  1. package javax.jms;
  2. public interface MessageConsumer {
  3. String getMessageSelector() throws JMSException;
  4. MessageListener getMessageListener() throws JMSException;
  5. void setMessageListener(MessageListener listener) throws JMSException;
  6. Message receive() throws JMSException;
  7. Message receive(long timeout) throws JMSException;
  8. Message receiveNoWait() throws JMSException;
  9. void close() throws JMSException;
  10. }

JMS客户端使用JMS MessageConsumer类来接收和处理消息。可以使用receive方法处理同步消息,也可以采用MessageListener的实现来处理异步消息。 
MessageConsumer没有设置目标(destination)的方法,在消费者被创建的时候(session.createConsumer())需要提供默认的目标。

3.3 Message 
JMS允许消息承载多种形式的信息,可以是文本形式,也可以是二进制的数据或者是在头部提供特殊的属性设置。
JMS由以下三部分组成。

  • header消息头
  • properties属性对
  • payload实际负载

3.3.1 Header 可以通过API设置

  • JMSDestination 消息投递目标
  • JMSDeliveryMode 可以设置消息投递模式(persistent/non-persistent)。建议使用持久化方式,以获得更佳的可靠性。
  • JMSExpiration 消息过期的时间。可以使用MessageProducer.setTimeToLive()设置默认的过期时间,也可以使用MessageProducer.send()方法设置个别消息的过期时间。0表示消息永不过期。
  • JMSMessageID 一个能够唯一标识一条消息的字符串,这个字符串被JMS提供者签发,不建议应用依赖这个ID编程。
  • JMSPriority 0到9,9为最高。JMS提供商只是尽量地将优先级高的消息先投递。不建议应用依赖这个次序编程。
  • JMSTimestamp 这个头选项标志了消息提供者向JMS提供者发送消息的时间。MessageProducer.setDisableMessageTimestamp()可取消。

3.3.2 Properties 附加的头部信息。JMS提供使用Java原始模型设置属性的方法包括boolean、byte、short、int、long、float、double和String Object

  1. a value written as the row type can be read as the column type.
  2. |----------------------------------------------------------
  3. |        | boolean byte short int long float double String
  4. |----------------------------------------------------------
  5. |boolean |    X                                       X
  6. |byte    |          X     X    X   X                  X
  7. |short   |                X    X   X                  X
  8. |int     |                     X   X                  X
  9. |long    |                         X                  X
  10. |float   |                               X     X      X
  11. |double  |                                     X      X
  12. |String  |    X     X     X    X   X     X     X      X
  13. |----------------------------------------------------------

3.3.3 Payload 消息体。JMS一共定义了5种。

  • Stream 流
  • Map 名值对 key为String,value为序列化对
  • Text 文本
  • Object 可序列化对象
  • Bytes 二进制序列

3.3.4 消息选择器 
很多情况下,JMS客户端订阅了一个目标(Destination)的消息,但是客户端可能仅想消费其中一部分,此时需要对消息进行过滤。可以使用消息的头部或者属性字段对消息进行过滤。JMS客户端工具包提供的选择器(selectors),会通知JMS 提供商(Provider),消费者只想接收包含了特定属性字段的消息。消息选择器通过对消息头中的属性进行过滤,允许JMS客户端指定哪些消息是其关注的消息。选择器使用SQL92表达式的子集定义。消息选择器使用布尔逻辑,通过对消息的头部属性和属性字段为评判目标进行简单布尔计算。不满足表达式的消息将不被投递到客户端。消息选择器不能对消息的实际负载进行过滤,只能对消息头部的属性和属性字段进行过滤。

3.3.5 JMS Domains 
JMS有两种类型的消息,分别是发布/订阅式和点对点式。 
3.3.5.1 Queue 
点对点式的消息传输中目标(Destination)将被认为是一个队列,消息可以同步的或者异步的被发送和接收。队列中的每条消息将仅会投递给一个消费者,并且仅投递一次(once-and-only-once 语义)。这很像发送email一样。消费者可以使用MessageConsumer.receive()同步接收队列中的消息,也可以实现MessageListener的MessageConsumer.setMessageListener()方法异步接收消息。队列将会存储所有投递来的消息,直到消息被投递出去或者消息已经过期。订阅消息可以通过MessageConsumer.receive()同步的从主题(topic)处接收消息,也可以通过实现MessageListener的setMessageListener方法异步接收订阅主题。多个消费者可以注册同一个消息队列接收消息,但是一条PTP消息仅会发给一个消费者。上图中需要注意,一个PTP消息的发送者发送的消息仅会被一个消费者接收,并不是所有注册到这个队列的消费者都会接收到同一消息。JMS提供者保证消息有且仅有一次被投递到注册的消费者。JMS提供商会在众多消费者之间做到一种负载平衡。 
3.3.5.2 Topic 
发布/订阅使用远程的主题(topic)目的地。发布者将消息发布给远程的主题,订阅者注册接收相应主题的消息。所有的发向主题的消息都会被以一种推的方式(push model)投递给所有的接收者。订阅消息可以通过MessageConsumer.receive()同步的从主题(topic)处接收消息,也可以通过实现MessageListener的setMessageListener方法异步接收订阅主题。如果不显示指明保持(durability)消息,主题消息将不会被保持。可以使用具有生命期(durable)的订阅。使用具有生命期的订阅时,如果有订阅者在消息发布时没有与JMS提供者连接,JMS将会为这种订阅者存储消息,当订阅者再次连接到JMS提供者时,这个订阅者将会收到失去连接期间的所有没过期的消息。生命期订阅允许发送消息时,接收者的非连接状态。 
3.3.5.3 生命期消息(Message Durability) 
生命期消息仅适用于发布/订阅消息域,当客户连接到主题时,他们可以决定是使用有生命期的(durable)还是无生命期的(non-durable)订阅。

  • Durable Subscription 当接收有生命期主题订阅的消费者在消息发布时处于不可用状态,JMS提供者将会对订阅的主题进行存储,当消费者状态可用时,会接收到之前订阅的消息。
  • Non-Durable Subscription 在消费者不可用期间发布的所有消息,都将丢失。

注意:消息持久化(persistence)和生命期消息(Message Durability)概念不同。持久化是一个独立任何域的概念。主要用于JMS提供者崩溃时消息的恢复。可以通过JMSDeliveryMode属性设置消息的持久化和非持久化属性。

3.4 管理员对象 
JMS规范定义了两种管理员对象:ConnectionFactory和Destination。

  • ConnectionFactory:SPI的顶级工厂,根据JMS提供商的不同,这个对象得到方式会有不同。
  • Destination Destination:对象封装了提供者相关的消息发送和接收的地址。尽管Destination是Session创建的,但是它们的生命期与创建Session的连接相匹配(就是说Session终结了,连接没有终结,Destination仍然有效)。

(四) Native JMS的使用 
4.1 步骤(以发送为例)

  • 获得JMS连接工厂(connection Factory)
  • 使用JMS工厂创建JMS连接
  • 启动JMS连接
  • 使用JMS连接创建JMS 会话(Session)
  • 获得一个JMS的目的地
  • 创建JMS 发送者(Producer)并指明发送目标
  • 发送JMS消息
  • 关闭JMS资源(connection、Session、producer、Consumer)

4.2 代码(忽略异常处理代码)

  1. import javax.jms.Connection;
  2. import javax.jms.ConnectionFactory;
  3. import javax.jms.Destination;
  4. import javax.jms.JMSException;
  5. import javax.jms.MessageProducer;
  6. import javax.jms.Session;
  7. import javax.jms.TextMessage;
  8. import org.apache.activemq.ActiveMQConnectionFactory;
  9. import org.apache.activemq.command.ActiveMQQueue;
  10. import org.apache.activemq.command.ActiveMQTextMessage;
  11. public class Main {
  12. public static void main(String[] args) throws JMSException {
  13. // 1
  14. ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616");
  15. // 2
  16. Connection connection = connectionFactory.createConnection();
  17. // 3
  18. connection.start();
  19. // 4
  20. Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
  21. // 5
  22. Destination destination = new ActiveMQQueue("queue");
  23. // 6
  24. MessageProducer messageProducer = session.createProducer(destination);
  25. // 7
  26. TextMessage textMessage = new ActiveMQTextMessage();
  27. textMessage.setText("some text");
  28. messageProducer.send(textMessage);
  29. // 8
  30. messageProducer.close();
  31. session.close();
  32. connection.stop();
  33. connection.close();
  34. System.out.println("done!");
  35. }
  36. }
 

ActiveMQ学习笔记(一) JMS概要的更多相关文章

  1. ActiveMQ学习笔记(二) JMS与Spring

    上文可见,JMS Native API使用起来不是特别方便.好在Spring提供了很好的JMS支持. (一)配置ConnectionFactory 如果使用连接池的话,不要忘记activemq-poo ...

  2. ActiveMQ学习笔记(5)——使用Spring JMS收发消息

      摘要 ActiveMQ学习笔记(四)http://my.oschina.net/xiaoxishan/blog/380446 中记录了如何使用原生的方式从ActiveMQ中收发消息.可以看出,每次 ...

  3. ActiveMQ学习笔记(4)----JMS的API结构和开发步骤

    1. JMS的API结构 其实上图中的五个API在第一节中我们都已经使用到了.本节将会讲非持久化和持久化topic的使用. 2. JMS的基本开发步骤 1. 创建一个JMS工厂,  Connectio ...

  4. ActiveMQ学习笔记1

    1.接口 JMS 公共 点对点域 发布/订阅域 ConnectionFactory QueueConnectionFactory TopicConnectionFactory Connection Q ...

  5. ActiveMQ学习笔记(18)----Message高级特性(二)

    1. Blob Message 有些时候,我们需要传递Blob(Binary Large Objects)消息,在5.14之前,(5.12和5.13需要在jetty.xml中手动开启)可以按照如下的方 ...

  6. ActiveMQ学习笔记(14)----Destination高级特性(二)

    1. Visual Destinations 1.1 概述 虚拟Destination用来创建逻辑Destinations,客户端可以通过它来产生和消费消息,它会把消息映射到物理Destination ...

  7. ActiveMQ学习笔记(12)----ActiveMQ的集群

    1. Queue consumer cluster ActiveMQ支持Consumer对消息的高可靠性的负载均衡消费,如果一个Consumer死掉,该消息会转发到其他的Consumer消费的Queu ...

  8. ActiveMQ学习笔记(6)----ActiveMQ整合Spring开发

    1. 添加依赖 spring 提供了对JMS的支持,需要添加Spring支持jms的包和Spring的核心包,如下: <dependency> <groupId>org.apa ...

  9. ActiveMQ学习笔记(1)----初识ActiveMQ

    1. 什么是ActiveMQ? ActiveMQ是Apache推出的,一款开源的,完全支持JMS1.1和j2ee1.4规范的JMS Provider实现的消息中间件(Message Oriented ...

随机推荐

  1. 大流量IIS负载均衡NLB解决方案

    说白了就是  用多台WEB服务器   同时处理大量的http请求! 机器越多力量越大呵呵!!! 在现行的许多网络应用中,有时一台服务器往往不能满足客户端的要求,此时只能通过增加服务器来解决问题. 那么 ...

  2. 学习:java设计模式—工厂模式

    一.工厂模式主要是为创建对象提供过渡接口,以便将创建对象的具体过程屏蔽隔离起来,达到提高灵活性的目的. 工厂模式在<Java与模式>中分为三类: 1)简单工厂模式(Simple Facto ...

  3. unsigned 和 signed

    http://www.cnblogs.com/stonehat/archive/2011/10/14/2212141.html http://m.blog.csdn.net/blog/u0100862 ...

  4. cimge 这次能够图片大小尺寸

    CImage imSrc,imDest;imSrc.Load(……);//读入原始图片imDest.Create(……)//创建新大小的图片imSrc.StretchBlt(imDest.GetDC( ...

  5. zoj 2770 Burn the Linked Camp (差分约束系统)

    // 差分约束系统// 火烧连营 // n个点 m条边 每天边约束i到j这些军营的人数 n个兵营都有容量// Si表示前i个军营的总数 那么 1.Si-S(i-1)<=C[i] 这里 建边(i- ...

  6. validator的验证

    通常喜欢这么写验证 <form method="post" data-ajax="false" action="/Shppping/PlaceO ...

  7. centos软件环境

    1,保持能链接外网和yum的可用性. 注意:yum配置项中最好:keepcache=1 2,yum install gcc, gcc-c++, make, cmake, 3, ntfs-3g wget ...

  8. TabWidget/TabHost的两种使用方法

    1.概念 盛放Tab的容器就是TabHost.TabHost的实现有两种方式: 第一种继承TabActivity,从TabActivity中用getTabHost()方法获取TabHost.各个Tab ...

  9. Easy steps to create a System Tray Application with C# z

    Hiding the C# application to the system tray is quiet straight forward. With a few line of codes in ...

  10. Apache OFBiz 学习笔记 之 服务引擎 一

    概述     服务定义为一段独立的逻辑顺序,当多个服务组合一起时可完成不同类型的业务需求     服务有很多类型,WorkFlow.Rules.Java.SOAP.BeanShell等.java类型的 ...