• MQ消息队列(2)—— Java消息服务接口(JMS)


    一、理解JMS

      1、什么是JMS?

            JMSJava消息服务(Java Message Service)应用程序接口,API是一个消息服务的标准或者说是规范,允许应用程序组件基于JavaEE平台创建、发送、接收读取消息。它使分布式通信耦合度更低,消息服务更加可靠以及异步性。

      我们可以简单的理解两个应用程序之间需要进行通信,我们使用一个JMS服务,进行中间的转发,通过JMS 的使用,我们可以解除两个程序之间的耦合。

           JMS不是消息队列,更不是某种消息队列协议。JMS是Java消息服务接口,是一套规范的JAVA API 接口

      1)这套规范接口由SUN提出,并在2002年发布JMS规范的Version 1.1版本。

      2)JMS和消息中间件厂商无关,既然是一套接口规范,就代表这它需要各个厂商进行实现。

      3)大部分消息中间件产品都支持JMS 接口规范,eg: 可以使用JMS API来连接Stomp协议的产品(例如ActiveMQ)。

         就像您可以使用JDBC API来连接ORACLE或者MYSQL一样。

    2、JMS的消息模型

     JMS具有两种通信模式:点对点发布/订阅模式

    3、JMS中消息的产生和消费

     在JMS中,消息的产生和消息是异步的。对于消费来说,JMS的消息者可以通过两种方式来消费消息。 
    ○ 同步 :订阅者或接收者调用receive方法来接收消息,receive方法在能够接收到消息之前(或超时之前)将一直阻塞 
    ○ 异步 :订阅者或接收者可以注册为一个消息监听器。当消息到达之后,系统自动调用监听器的onMessage方法。

    4、对象模型

    (1) ConnectionFactory
    创建Connection对象的工厂,针对两种不同的jms消息模型,分别有QueueConnectionFactoryTopicConnectionFactory两种。可以通过JNDI来查找ConnectionFactory对象。

    (2) Destination
    Destination,即 消息生产者的 消息发送目标,或者说 消息消费者的 消息来源

    对于消息生产者来说,它的Destination是某个队列(Queue)或某个主题(Topic);

    对于消息消费者来说,它的Destination也是某个队列或主题(即消息来源)。

    所以,Destination实际上就是两种类型的对象:Queue、Topic。可以通过JNDI来查找Destination。

    (3) Connection
    Connection表示在客户端和JMS系统之间建立的链接(对TCP/IP socket的包装)。

    Connection可以产生一个或多个Session。

    跟ConnectionFactory一样,Connection也有两种类型:QueueConnectionTopicConnection

    (4) Session
    Session是我们操作消息的接口。可以通过session创建生产者消费者消息等。

    Session提供了事务的功能。

    当我们需要使用session发送/接收多个消息时,可以将这些发送/接收动作放到一个事务中。

    同样,也分QueueSessionTopicSession

    (5) 消息的生产者
    消息生产者由Session创建,并用于将消息发送到Destination。

    同样,消息生产者分两种类型:QueueSenderTopicPublisher

    可以调用消息生产者的方法(send或publish方法)发送消息。

    (6) 消息消费者
    消息消费者由Session创建,用于接收被发送到Destination的消息。

    两种类型:QueueReceiverTopicSubscriber

    可分别通过session的createReceiver(Queue)或createSubscriber(Topic)来创建。

    当然,也可以session的creatDurableSubscriber方法来创建持久化的订阅者。

    (7) MessageListener
    消息监听器。如果注册了消息监听器,一旦消息到达,将自动调用监听器的onMessage方法

    EJB中的MDB(Message-Driven Bean)就是一种MessageListener。

     5、消息的组成

     Message主要由三部分组成,分别是Header,PropertiesBody, 解释如下:

    1. Header: 消息头,所有类型的这部分格式都是一样的
    2. Properties: 属性,按类型可以分为 应用设置的属性 , 标准属性 和 消息中间件定义的属性
    3. Body: 消息正文,指我们具体需要消息传输的内容。

    消息头

    序号 属性名称 说明 设置者

    1

    JMSDestination

    消息发送的目的地,是一个Topic或Queue  send

    2

    JMSDeliveryMode

    消息的发送模式,分为NON_PERSISTENT和PERSISTENT,即 持久化的 和 非持久化的  send

    3

    JMSMessageID

    消息ID,需要以ID : 开头     send

    4

    JMSTimestamp 

     消息发送时的时间,也可以理解为 调用send()方法时的时间,而不是 该消息发送完成的时间  send

    5

    JMSCorrelationID

     关联的消息ID,这个通常用在需要回传消息的时候  client

    6

    JMSReplyTo

     消息回复的目的地,其值为一个Topic或Queue, 这个由发送者设置,但是接收者可以决定是否响应  client

    7

    JMSRedelivered 

     消息是否重复发送过,如果该消息之前发送过,那么这个属性的值需要被设置为true, 客户端可以根据这个属性的值来

    确认这个消息是否重复发送过,以避免重复处理。

     Provider

    8

    JMSType

     由消息发送者设置的个消息类型,代表消息的结构,有的消息中间件可能会用到这个,但这个并不是是批消息的种类,比如

    TextMessage之类的

     client

    9

    JMSExpiration 

     消息的过期时间,以毫秒为单位,根据定义,它应该是timeToLive的值再加上发送时的GMT时间,也就是说这个指的是过期

    时间,而不是有效期

    send 

    10

    JMSPriority

     消息的优先级,0-4为普通的优化级,而5-9为高优先级,通常情况下,高优化级的消息需要优先发送  send

    消息属性

           消息属性的主要作用是可以对头信息进行一个额外的补充,毕竟消息头信息:一是有限,二是很多不能由应用程序设定。

      通常,消息属性可以用在消息选择器的表达式里,结合起来实现对消息的过滤。

      消息属性的值只能是基本的类型,或者这些基本类型对应的包装类型。也就是说,不能将一个自定义的对象作为属性值。

      通常情况下,如果能够放在body里的内容,就不必放在消息属性里。

     消息体

           为了适应不同场景下的消息,提高消息存储的灵活性,JMS定义了几种具体类型的消息,不同的子类型的消息体也不一样。

      需要注意的是,Message接口并没有提供一个统一的getBody之类的方法。

    消息子接口定义如下:

    1)TextMessage: 最简单的消息接口,用于发送文本类的消息,设置/获取其body的方法定义如下setText()/getText().


    2)StreamMessage: 流式消息接口,里面定义了一系列的对基本类型的set/get方法,

               消息发送者可以通过这些方法写入基本类型的数据,

              消息接收者需要按发送者的写入顺序来读取相应的数据。


    3)MapMessage:把消息内容存储在Map里,本接口定义了一系列对基本类型的的set/get方法,

                                    与StreamMessage不同的是,每个值都对应了一个相应的key,

                                    所以消息接收者不必按顺序去读取数据。

    4)ObjectMessage: 将对象作为消息的接口,提供了一个set/get 对象的方法,需要注意的是只能设置一个对象,这个对象可以是一个Collection,但必须是序列化的
    5)BytesMessage: 以字节的形式来传递消息的接口,除了提供了对基本类型的set/get,还提供了按字节方式进行set/get。 

  • 相关阅读:
    从句分析
    artDialog ( v 6.0.2 ) content 参数引入页面 html 内容
    Java实现 LeetCode 13 罗马数字转整数
    Java实现 LeetCode 13 罗马数字转整数
    Java实现 LeetCode 13 罗马数字转整数
    Java实现 LeetCode 12 整数转罗马数字
    Java实现 LeetCode 12 整数转罗马数字
    Java实现 LeetCode 12 整数转罗马数字
    Java实现 LeetCode 11 盛最多水的容器
    Java实现 LeetCode 11 盛最多水的容器
  • 原文地址:https://www.cnblogs.com/651434092qq/p/11082126.html
Copyright © 2020-2023  润新知