ActiveMQ使用

JMS:Java消息服务(即Java Message Service),Java平台上有关面向MOM的技术规范。目的是通过提供标准的产生、发送、接收和处理消息的API简化企业应用的开发,类似JDBC和数据库通信方式的抽象。

ActiveMQ:ActiveME是基于JMS的开源的消息中间件。提供标准的、面向消息的、能够跨多种语言和系统的应用集成消息中间件。

消息:服务之间进行传送的数据单位。可以很简单,比如字符串;也可以是对象等。

JMS中的相关角色

Broker:消息服务器,作为server提供消息核心服务。

Provider/MessageProvider:消息生产者是由会话创建的一个对象,用于把消息发送到一个目的地。

Consumer/MessageConsumer:消息消费者是由会话创建的一个对象,它用于接收发送到目的地的消息。

同步消费:调用消费者的receive方法从目的地中显式提取消息。receive方法可以一直阻塞到消息到达。

异步消费:为消费者注册一个消息监听器,以定义在消息到达时所采取的动作。

PTP:Point To Point,点对点通信消息模型。

​ 生产者将消息发送到queue中,消费者从queue中获取并消费消息。消息被消费之后,queue不能在有存储,所以消费者不会消费到已经被消费的消息。Queue支持多个消费者,但对于一个消息,只会有一个消费者。如果消费者不存在,消息将一致保存,直到被消费。

在这里插入图片描述

Pub/Sub:Publish/Subscribe,发布订阅消息模型

在这里插入图片描述

​ 生产者将消息发布的topic,同时有多个消费者订阅来消费该消息。不同于PTP的方式,发不到topic的消息会被所有的订阅者消费。默认情况下,当生产者发布消息当时候,只有在线的订阅者会消费到消息,不在线的订阅者将不会消费到该消息。

Queue:队列,目标类型之一,和PTP结合

Topic:主题,目标类型之一,和Pub/Sub结合

Queue/Topic都是 Destination 的子接口.

ConnectionFactory:连接工厂是客户用来创建连接的对象,例如ActiveMQ提供的ActiveMQConnectionFactory。

Connnection:JMS Connection封装了客户与JMS提供者之间的一个虚拟的连接。

Destination:消息目的地,由Session创建。是客户用来指定它生产的消息的目标和它消费的消息的来源的对象。

Session:JMS Session是生产和消费消息的一个单线程上下文(在这个上下文中,一组发送和接收被组合到了一个原子操作中)。会话用于创建消息生产者(producer)、消息消费者(consumer)和消息(message)等。

消息中间件的场景

异步通信:消息队列提供了异步处理机制,允许用户把一个消息放入队列,但并不立即处理它。想向队列中放入多少消息就放多少,然后在需要的时候再去处理它们。

缓冲:消息队列通过一个缓冲层来帮助任务最高效率的执行,该缓冲有助于控制和优化数据流经过系统的速度。以调节系统响应时间。

解耦:降低服务间的强依赖程度,针对异构系统进行适配。通过消息系统在处理过程中间插入了一个隐含的、基于数据的接口层,当应用发生变化时,可独立的扩展或者修改。

冗余:消息队列把数据进行持久化直到它们已经被完全处理,通过这一方式规避了数据丢失风险。

扩展性:消息队列解耦了处理过程,可以在不修改代码的情况下进行分布式扩容。

可恢复性:消息队列降低了进程间的耦合度,所以即使一个处理消息的进程挂掉,加入队列中的消息仍然可以在系统恢复后被处理。

过载保护:访问量剧增的情况下,消息队列能够使关键组件顶住突发的访问压力,而不会因为突发的超负荷的请求而完全崩溃。

HelloActiveMQ

Producer
public class MyProducer {
  public static void main(String[] args) {
    Connection connection = null;
    ActiveMQConnectionFactory connectionFactory = null;
    try {
      //1.获取连接工厂,这里默认不设定用户密码,为了安全可以在activemq.xml中配置指定的用户、密码才能访问ActiveMQ。
      connectionFactory = new ActiveMQConnectionFactory(
        ActiveMQConnectionFactory.DEFAULT_USER,
        ActiveMQConnectionFactory.DEFAULT_PASSWORD,
        "tcp://localhost:61616"//tcp协议,ActiveMQ支持多种协议,开启了不通的端口
      );
      //2.获取一个ActiveMQ的连接
      connection = connectionFactory.createConnection();
      //3.获取session
      Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);//false,表示事务不开启
      //4.找目的地,获取destination,消费端,也会从这个目的地取消息。要么是queue,要么是topic
      Queue queue = session.createQueue("myQueue");
      //5.消息创建者
      MessageProducer producer = session.createProducer(queue);
      //6.创建消息
      for (int i = 0; i < 10; i++) {
        TextMessage textMessage = session.createTextMessage("hi :" + i);
        //7.向目的地写入消息
        producer.send(textMessage);
      }
    } catch (JMSException e) {
      e.printStackTrace();
    } finally {
      //8.关闭连接
      try {
        connection.close();
      } catch (JMSException e) {
        e.printStackTrace();
      }
    }
  }
}

在这里插入图片描述

Messages Enqueued:表示生产了多少条消息

Messages Dequeued:表示消费了多少条消息

Number Of Consumers:表示在该队列上还有多少消费者在等待接受消息

Number Of Pending Messages:表示还有多少条消息没有被消费,实际上是表示消息的积压程度

Consumer
public class MyConsumer {
  public static void main(String[] args) {
    Connection connection = null;
    ActiveMQConnectionFactory connectionFactory = null;
    try {
      //1.获取连接工厂
      connectionFactory = new ActiveMQConnectionFactory(
        ActiveMQConnectionFactory.DEFAULT_USER,
        ActiveMQConnectionFactory.DEFAULT_PASSWORD,
        "tcp://localhost:61616"
      );
      //2.获取一个ActiveMQ的连接
      connection = connectionFactory.createConnection();
      connection.start();
      //3.获取session
      Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
      //4.找目的地,消费端,从这个目的地取消息
      Destination queue = session.createQueue("myQueue");
      //5.消费者
      MessageConsumer consumer = session.createConsumer(queue);
      for (int i = 0; i < 10; i++) {
        TextMessage textMessage = (TextMessage) consumer.receive();
        System.out.println("Receive:" + textMessage.getText());
      }
    } catch (JMSException e) {
      e.printStackTrace();
    } finally {
      try {
        connection.close();
      } catch (JMSException e) {
        e.printStackTrace();
      }
    }
  }
}

在这里插入图片描述

消息可靠性机制

​ 消息是否被成功消费,需要有一种确认机制,就是消息确认机制。**ACK(Acknowledgement)**即确认字符,在数据通信中,接收站发给发送站的一种传输类控制字符。表示发来的数据已确认接收无误。

ACK_MODE

​ JMS规定Client可以使用的ACK_MODE有四种:

  • AUTO_ACKNOWLEDGE = 1:自动确认。当客户成功的从receive方法返回的时候,或者从MessageListener.onMessage方法成功返回的时候,会话自动确认客户收到的消息。
  • CLIENT_ACKNOWLEDGE = 2:客户端手动确认。客户通过消息的acknowledge方法确认消息。(在这种模式中,确认是在会话层上进行:确认一个被消费的消息将自动确认所有已被会话消费的消息。)
  • DUPS_OK_ACKNOWLEDGE = 3:自动批量确认.该选择只是会话迟钝的确认消息的提交。可能会导致一些重复的消息。
  • SESSION_TRANSACTED = 0:事务提交并确认。所有的事务性会话,不管如何设置ack模式,都是按照以下原则:同一事务内部,在执行commit之前接收到的消息,都是没有ack的,放在pendingAck里面。在进行session.commit的时候会把pendingAck里面的消息全部一次确认,视为手动批量确认。事务会话要求效率高,因此都是批量进行ack的,没有别的方式。
ACK_TYPE

​ ACK_MODE确定了用何种方式进行消息确认。ACK_TYPE表示确认指令的类型。不同的ACK_TYPE将传递着消息的状态,broker可以根据不同的ACK_TYPE对消息进行不同的操作。JMS API中并没有定义ACT_TYPE,因为它通常是一种内部机制,并不会面向开发者。

DELIVERED_ACK_TYPE = 0 消息"已接收",但尚未处理结束
STANDARD_ACK_TYPE = 2 “标准"类型,通常表示为消息"处理成功”,broker端可以删除消息了
POSION_ACK_TYPE = 1 消息"错误",通常表示"抛弃"此消息,比如消息重发多次后,都无法正确处理时,消息将会被删除或者DLQ(死信队列)
REDELIVERED_ACK_TYPE = 3 消息需"重发",比如consumer处理消息时抛出了异常,broker稍后会重新发送此消息
INDIVIDUAL_ACK_TYPE = 4 表示只确认"单条消息",无论在任何ACK_MODE下
UNMATCHED_ACK_TYPE = 5 BROKER间转发消息时,接收端"拒绝"消息

消息优先级

​ 消息优先级只是一个理论上的概念,并不能绝对保证优先级高的消息一定被消费者优先消费!也就是说ActiveMQ并不能保证消费的顺序性!

默认(JMSPriority == 4)
高(JMSPriority> 4 && <= 9)
低(JMSPriority> 0 && <4)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值