JMS(java message service java消息服务)

  1. 什么是JMS(java消息服务)
    java消息服务是指两个应用程序之间进行异步通信的API,它为标准消息协议和消息服务提供了一组通用接口,包括创建、发送、读取消息等,用于支持java应用程序开发.在javaee中,当两个应用程序使用JMS进行通信时,它们之间并不是直接相连的,而是通过一个共同的消息收发服务组件关联起来以达到解耦/异步/削峰的效果.
    在这里插入图片描述
  2. JMS组成结构和特点
  • JMS provider: 实现JMS接口和规范的消息中间件,也就是MQ服务器
  • JMS producer: 消息生产者,创建和发送JMS消息的客户端应用
  • JMS consumer: 消息消费者,接收和处理JMS消息的客户端应用
  • JMS message
    • 消息头
      • JMSDestination: 消息发送目的地,主要指queue和topic
      • JMSDeliveryMode: 持久模式和非持久模式.
        持久化的消息应该被传送仅一次,如果JMSprovider出现故障,它会在服务器恢复之后再次传递.
        非持久化的消息最多被传送一次,如果服务器发生故障,该消息将永远丢失.
      • JMSExpiration: 设置消息在一定时间后过期,默认永不过期.如果send方法中的timeToLive设置为0,表示消息永不过期.
      • JMSPriority: 消息优先级
        从0-9十个级别,0-4为普通消息,5-9为加急消息.JMS不要求MQ严格按照这十个优先级发送消息,但必须保证加急消息先于普通消息到达,默认是4级
      • JMSMessageID: 唯一识别每个消息的标识,由MQ产生
    • 消息体
      • TextMessage: 一个普通的字符串消息,包含一个String
      • MapMessage: 一个map类型的消息,key为string类型,值为java的基本类型
      • BytesMessage: 二进制数组消息,包含一个byte[]
      • StreamMessage: java数据流消息,用标准流操作来顺序的填充和读取
      • ObjectMessage: 对象消息,包含一个可序列化的java对象
    • 消息属性: 本质键值对,用于识别/去重/重点标注等操作
      以属性名和属性值的形式制定,可以将属性作为消息头的扩展,属性指定一些消息头没有包括的附加信息,比如可以在属性里指定消息选择器.
      TestMessage message = session,createTextMessage();
      message.setText(text);
      message.setStringProperty("username", "z3");   /
      
  1. JMS可靠性(多节点集群、持久型、事务、签收)
  • 多节点集群

  • 持久性

    • 非持久化: 当服务器宕机,消息丢失
    messageProvider.setDeliveryMode(DeliveryMode.NON_PERSISTENT);
    
    • 持久化(队列的默认传送模式): 当服务器宕机,消息依然存在
    messageProvider.setDeliveryMode(DeliveryMode.PERSISTENT);
    
  • 事务(偏生产者)

    • 设置为false,只要执行send,就进入到队列中
    • 设置为true,先执行send再执行commit,消息才被真正的提交到队列中.对于消费端,如果不执行commit则消费会被重复消费.
    Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
    ...
    session.commit();
    session.close();
    
  • acknowledge(签收,偏消费者):

    • 自动签收(默认): Session.AUTO_ACKNOWLEDGE
    • 客户端手动签收: Session.CLIENT_ACKNOWLEDGE
      客户端调用acknowledge方法手动签收
    • 允许重复签收: Session.DUPS_OK_ACKNOWLEDGE(不常用)
    • 事务性签收: Session.SESSION_TRANSACTED(不常用)
      注: 对于消费者,如果同时设置了事务true和客户端手动签收,事务优先级更高.
      如果事务没有写session.commit(),不管有没有调用acknowledge方法手动签收,都会重复消费.
      如果事务写了session.commit(),不管有没有调用acknowledge方法手动签收,都不会重复消费.
      如果事务回滚,则消息会再次被传送.
      如果事务为false,消息何时被确认取决于创建会话的应答模式(acknowledge mode)
  1. JMS点对点(queue)总结
    点对点模型是基于队列的,生产者消息到队列,消费者从队列接收消息,队列的存在使得消息的异步传输成为可能.
  • 如果在session关闭时有部分消息已被接收但还没有被签收(acknowledge),那当消费者下次连接到相同队列时,这些消息还会被再次接收
  • 队列可以长久的保存消息直到消费者收到消息.消费者不需要因为担心消息会丢失而时刻和队列保持激活的连接状态,充分体现了异步传输的优势.
  1. JMS发布订阅总结
    JMS pub/sub模型定义了如何向一个内容节点发布和订阅消息,这些节点被称为topic.
    主题可以被认为是消息的传输中介,发布者发布消息到主题,订阅者从主题订阅消息.
    主题使得消息订阅者和消息发布者保持互相独立,不需要接触即可保证消息的传送.

  2. 消费者三大消费情况

  • 先生产,只启动1号消费者,则1号消费者消费所有消息
  • 先生产,先启动1号消费者,再启动2号消费者,则1号消费者消费所有消息
  • 先启动两个消费者,再生产消息,则一个消费者消费一半消息
  1. 点对点消息传递域的特点
  • 每个消息只能有一个消费者,类似1对1的关系
  • 消费者的生产者和消费者之间没有时间上的相关性.无论消费者在生产者发送消息的时候是否处于运行状态,消费者都可以提取消息
  • 消息被消费后队列中不会再存储,所以消费者不会消费到已经被消费掉的消息
  1. 发布订阅消息传递域的特点
  • 生产者将消息发布到topic中,每个消息可以有多个消费者,属于一对多关系
  • 生产者和消费者之间存在时间上的相关性,订阅某一个topic的消费者只能消费订阅后发布的消息
  • 生产者生产时,topic不保存消息,它是无状态的.也就是说如果无人订阅就去生产,那么就是废消息.所以一般先启动消费者再启动生产者
    注: JMS规范允许消费者创建持久订阅.发布订阅模式类似于微信公众号.
  1. JMS非持久订阅和持久订阅
  • 非持久订阅
    只有当客户端处于激活状态,也就是和MQ保持连接状态时才能接收到发送到某个topic的消息
    如果消费者处于离线状态,生产者发送的主题消息将会丢失作废,消费者永远消费不到.
    总结: 先要订阅才能接收到发布,只给订阅者发布消息.
  • 持久化订阅
    客户端首先向MQ注册一个自己的身份ID识别号,当这个客户端处于离线状态时,生产者会为这个ID保存所有发送到主题的消息.
    当客户端再次连接到MQ时会根据消费者ID得到所有当处于离线状态时发送到topic的消息.
    非持久化订阅状态下,不能恢复或重新派送一个未签收的消息.持久化订阅才能恢复或重新派送一个未签收的消息.
  • 假设所有的消息必须被接收,则用持久化订阅.当丢失消息能够被容忍,则使用非持久化订阅.
  1. JMS(Java Message Service java消息服务)开发步骤
  • 创建一个connection factory
  • 通过connection factory创建JMS connection
  • 启动JMS connection
  • 通过connection创建JMS session
  • 创建JMS destination
  • 创建JMS producer或者创建JMS message并设置destination
  • 创建JMS consumer或者注册一个JMS message listener
  • 发送或者接收JMS messages
  • 关闭所有的JMS资源(connection、session、producer、consumer等)

猜你喜欢

转载自blog.csdn.net/qq_26496077/article/details/112152243