JMS 入门学习

原创 2018年04月17日 18:35:29

前言

新公司现在的项目中有使用 ActiveMQ,所以在闲余时间自己也学习一下,浏览过很多文档及博客内容,发现入门容易,深入了解涉及也蛮多的。本文旨在记录一下如何入门,即使入门可能也会有疏漏,所以当做“抛砖引玉”,烦请各位多多指点。

介绍

JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。Java消息服务是一个与具体平台无关的API,绝大多数MOM提供商都对JMS提供支持,类似于JDBC(Java Database Connectivity)。在实际应用中JMS+MQ服务器(即消息中间件)相结合来完成消息排队类型的应用程序开发。

MQ 服务器是什么?用 MQ 的说法,Message(消息)只是一个字节流(这个字节流可以是一个 XML 文档、一个序列化的 Java 对象、一个文本字符串或甚至是一条空消息),对消息的解释留给应用程序域来做,MQ 服务器不对消息施加任何语义和结构限制。消息存储在MQ服务器的消息队列中,MQ 服务器允许您使用JMS将消息加入到队列以及从队列中取走消息。

使用场景

消息队列中间件是分布式系统中重要的组件,主要解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构。关于详细介绍可参考这篇关于消息队列的使用

JMS 消息传送对象和模式

为了发送或接收消息,JMS 客户端必须先连接到 JMS 提供者(该提供者通常作为消息代理实现):此连接在客户端与代理之间打开一个通信通道。接下来,客户端必须设置一个用来创建、生成和使用消息的会话。可以将该会话视为定义客户端与代理之间的特定对话的消息流。客户端本身就是消息生成方和/或消息使用方。消息生成方 向代理所管理的目的地发送一条消息。消息使用方访问该目的地以使用此消息。该消息包括消息头、属性(可选)和主体。消息主体用来保存数据;消息头中包含代理路由和管理消息所需的信息;属性可以由客户端应用程序或提供者定义,以满足处理消息的需要。
连接、会话、目的地、消息、生成方和使用方是构成 JMS 应用程序的基本对象。

通过这些基本对象,客户端应用程序可以使用两种消息传送模式(或域)发送和接收消息。

消息传送域

JMS API 定义通信的两种消息传送域:点对点消息传送发布/订阅消息传送

  1. 点对点消息传送

    在点对点域中,消息生成方被称为发送者,而使用方被称为接收者。它们通过被称为队列的目的地来交换消息:发送者生成队列中的消息;而接收者则使用队列中的消息。

    图示为点对点域中最简单的消息传送操作。
    说明:MyQueueSender 向队列目的地 MyQueue1 发送 Msg1。然后, MyQueueReceiver 从 MyQueue1 获得该消息。

    特点
    多个接收者可以使用一个队列中的多条消息,但每条消息只能由一个接收者使用。

    发送者和接收者之间不存在时间上的相关性:客户端发送一条消息后,无论接收者是否正在运行,都能获取该消息。

    消息在队列中按发送的顺序排列,但使用消息的顺序取决于多种因素,例如消息失效日期、消息优先级以及使用消息时是否使用了选择器。

    优势:
    由于多个接收者可以使用同一队列中的消息,因此如果消息的接收顺序不重要,则可以对消息的使用进行负载平衡。

  2. 发布/订阅消息传送

    在发布/订阅域中,消息生成方被称为发布者,而消息使用方则被称为订阅者。它们通过称为主题的目的地来交换消息:发布者生成主题中的消息;订阅者则订阅主题并使用主题中的消息。

    描述

    图示为发布/订阅域中的简单消息传送操作。
    说明:MyTopicPublisher 向目的地 MyTopic 发布 Msg1。然后,MyTopicSubscriber1 和 MyTopicSubscriber2 均从 MyTopic 接收 Msg1 的副本。

    特点
    多个订阅者可使用一个主题中的消息。订阅者可检索发布到一个主题中的所有消息,除非它们使用选择器过滤掉消息或消息在使用之前已过期。

    订阅者可共享连接或使用不同连接,但它们均可访问同一主题。

    长期订阅者可能处于活动状态,也可能处于非活动状态。在它们处于非活动状态时,代理会为它们保留消息。

    可在运行时动态添加和删除发布者和订阅者,这样,即可根据需要缩放消息传送系统。

    消息按发送的顺序发布到主题,但使用消息的顺序取决于多种因素,例如消息失效日期、消息优先级以及使用消息时是否使用了选择器。

    发布者与订阅者之间存在时间上的相关性:订阅者只有先订阅主题,才能接收到发布者在订阅者创建订阅后发布的消息。

消息消费

在JMS中,消息的产生和消费都是异步的。对于消费来说,JMS的消息者可以通过两种方式来消费消息。

  1. 同步
    订阅者或接收者通过receive方法来接收消息,receive方法在接收到消息之前(或超时之前)将一直阻塞;

  2. 异步
    订阅者或接收者可以注册为一个消息监听器。当消息到达之后,系统自动调用监听器的onMessage方法。

创建JMS应用程序

这里是用的ActiveMQ配合使用,过程其实和创建 JDBC 有点类似,下表为发送和接收消息所需的步骤

生成消息 使用消息
管理员创建连接工厂受管理对象 相同
客户端创建连接并设置特定于此连接的任何属性 相同
客户端创建会话并设置用于决定消息传送可靠性的属性 相同
客户端创建消息生成方 客户端创建消息使用方
客户端创建消息 客户端建立连接
客户端发送消息 客户端接收消息
  1. 创建 连接工厂对象 (ConnectionFactory) 及 连接对象 Connecttion

    连接工厂封装了本地与MQ服务器之间的虚拟连接,并且可以配置从它派生的所有连接的行为,可以使用它来创建一个连接对象。

    public static final String BROKER_URL = "tcp://localhost:61616";
    // 创建连接工厂
    ConnectionFactory factory = new ActiveMQConnectionFactory(ActiveMQConnection.DEFAULT_USER, ActiveMQConnection.DEFAULT_PASSWORD, BROKER_URL);
    // 通过工厂创建一个连接
    connection = factory.createConnection();
    // 启动连接
    connection.start();
  2. 创建会话对象

    会话对象主要用于创建消息、消息生成方和消息使用方。创建会话时,通过多个确认选项或通过事务来配置可靠传送。

    // 创建一个session会话
    // 参数一:是否开启事务 true开启 ,false不开启事务,如果开启记得手动提交  
    // 参数二:签收模式,一般使用的有自动签收和客户端自己确认签收 
    session = connection.createSession(Boolean.TRUE, Session.AUTO_ACKNOWLEDGE);
  3. 消息生产者

    通过会话会生成一个消息生产者,指定了发布消息类别:queue 或 topic
    可以设定消息的特性,是否持久化,到期时间,优先级等。

    // 创建名为 myQueue 队列
    Destination destination = session.createQueue(“myQueue”);
    // 创建名为 myTopic 主题
    //Destination destination = session.createTopic(“myTopic”);
    // 创建消息制作者
    MessageProducer producer = session.createProducer(destination);
    // 设置持久化模式
    producer.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
    //创建消息
    for (int i = 0; i < 6; i++) {
        String message = "发送消息第" + (i + 1) + "条";
        TextMessage text = session.createTextMessage(message);
        producer.send(text);
    }
  4. 消息消费者

    通过会话会生成一个消息消费者,指定了接收的消息类别:queue 或 topic
    可以设定消息的特性,是否持久化,到期时间,优先级等。

    // 创建名为 myQueue 队列
    Destination destination = session.createQueue(“myQueue”);
    // 创建名为 myTopic 主题
    //Destination destination = session.createTopic(“myTopic”);
    // 创建消息制作者
    MessageConsumer consumer = session.createConsumer(destination);
  5. 获取消息

    消息使用方可以支持同步或异步消息使用。

    • 同步

      表示使用方明确要求传送消息并使用该消息。

      根据请求消息时使用的方法,同步使用方可选择等待(无限期)消息到达,等待指定的时间或者在不存在可供使用的消息时立即返回。

      while (true) {
          // 接收数据的时间(等待) 10s
          Message message = consumer.receive(1000 * 10);
          TextMessage text = (TextMessage) message;
          if (text != null) {
              System.out.println("接收:" + text.getText());
          } else {
              break;
          }
      }
    • 异步

      表示自动将消息传送给为使用方注册的消息侦听器对象 (MessageListener)。当会话线程调用消息侦听器对象的 onMessage() 方法时,客户端将使用该消息。

      consumer.setMessageListener(new MessageListener() {
          public void onMessage(Message message) {
              try {
                  String text = ((TextMessage) message).getText();
                  System.out.println(text);
              } catch (JMSException e) {
                  e.printStackTrace();
              }
          }
      });

消息内容类型

在消息体中,JMS API定义了五种类型的消息格式,让我们可以以不同的形式发送和接受消息,并提供了对已有消息格式的兼容。不同的消息类型如下:

类型 描述
TextMessage 表示一个文本对象
ObjectMessage 表示一个序列化 Java 对象的消息
BytesMessage 表示字节数据
StreamMessage 表示java原始值数据流
MapMessage 表示键值对

特定于域的 API 及统一域 API

JMS API 定义可用于实现 点对点域 或 发布/订阅域 的接口和类。表的第 2 列和第 3 列中显示的特定于域的 API。JMS API 还定义另外一个统一域,用于通过编程实现常规的消息传送客户端。这类客户端的行为由目的地类型决定,客户端向目的地中生成消息并使用目的地中的消息。如果该目的地是一个队列,则消息传送行为将为点对点模式;如果该目的地是一个主题,则消息传送行为将为发布/订阅模式。

基本类型(统一域) 点对点域 发布/订阅域
Destination(队列或主题) Queue Topic
ConnectionFactory QueueConnectionFactory TopicConnectionFactory
Connection QueueConnection TopicConnection
Session QueueSession TopicSession
MessageProducer QueueSender TopicPublisher
MessageConsumer QueueReceiver TopicSubscriber
参考资料
  1. https://docs.oracle.com/cd/E19148-01/820-0533/aerbg/index.html
  2. https://docs.oracle.com/javaee/7/tutorial/partmessaging.htm#GFIRP3
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/YY_WG/article/details/79978786

pmp项目管理学习入门技巧

-
  • 1970年01月01日 08:00

JMS学习(一)入门及activemq简单实例

1. JMS基本认识jms即Java消息服务(Java Message Service)应用程序接口是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送...
  • fun913510024
  • fun913510024
  • 2015-04-26 03:13:50
  • 740

JMS入门教程

转载:http://www.cnblogs.com/jjj250/archive/2012/08/08/2628552.html
  • zhangzikui
  • zhangzikui
  • 2014-05-01 11:43:27
  • 5706

【JMX学习】1、jmx入门

项目的web端和后端分开部署,用到JMX,使web端跟后端通信,当后端启动时加载一些文件,当web端修改时就会通知后端去更新,下面大概的学习下JMX,首先了解下JMX,然后做了一些小例子 一、j...
  • hy1945hy
  • hy1945hy
  • 2013-03-28 13:28:42
  • 1500

深入浅出JMS(三)--ActiveMQ简单的HelloWorld实例

JMS其实并没有想象的那么高大上,看完这篇博文之后,你就知道什么叫简单。。...
  • jiuqiyuliang
  • jiuqiyuliang
  • 2015-09-26 13:37:47
  • 97371

JMS学习一(JMS介绍)

一、JMS是什么个鬼 二、为什么要学习,使用JMS 三、JMS有什么优势 四、JMS消息传送模型 五、接收消息 六、JMS编程接口 七、JMS消息结构 ...
  • QH_JAVA
  • QH_JAVA
  • 2017-02-16 09:38:29
  • 10508

JMS&MQ,从入门到精通(一)

JMS JMS即Java消息服务(Java Message Service)应用程序接口,是一个Java平台中关于面向消息中间件(MOM)的API,用于在两个应用程序之间,或分布式系统中发送消息,...
  • u013410747
  • u013410747
  • 2017-04-26 17:53:45
  • 625

jms入门

下载ActiveMQ 官方网站:http://activemq.apache.org/  ActiveMQ默认启动时,启动了内置的jetty服务器,提供一个用于监控ActiveMQ的admi...
  • hellomvn
  • hellomvn
  • 2016-06-02 15:30:04
  • 234

JMS入门及简单例子

基本概念JMS(Java Message Service)即java消息服务。它提供了标准的生产、发送和接收信息的借口,简化了企业开发的流程。它提供了两种方式的消息通信模型:点对点的模型、发布/点阅模...
  • weixin_35342186
  • weixin_35342186
  • 2017-01-14 18:52:37
  • 190

JMS入门Demo

  • 2015年07月27日 11:45
  • 8.56MB
  • 下载
收藏助手
不良信息举报
您举报文章:JMS 入门学习
举报原因:
原因补充:

(最多只允许输入30个字)