消息中间件之ActiveMQ(3)消息类型和死信队列

消息类型

JMS消息由以下三部分组成的:
消息头
每个消息头字段都有相应的getter和setter方法。
消息属性
如果需要除消息头字段以外的值,那么可以使用消息属性。
消息体
JMS定义的消息类型有TextMessage、MapMessage、BytesMessage、StreamMessage和
ObjectMessage。
TextMessage
文本消息
MapMessage
k/v
BytesMessage
字节流
StreamMessage
java原始的数据流
ObjectMessage
序列化的java对象
我们就以ObjectMessage和BytesMessage为例写个小案例
首先创建一个实现序列化的实体类,因为通过ActiveMQ传输对象时是通过序列化传输,反序列化接收的,所以实体类一定要实现序列化

public class Girl implements Serializable {
    String name;//姓名
    int age;//年龄
    double price;//彩礼价格

    public Girl(String name, int age, double price) {
        this.name = name;
        this.age = age;
        this.price = price;
    }

    @Override
    public String toString() {
        return "Girl{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", price=" + price +
                '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }
}

消息发送者Sender.java

/**
 * 消息发送者
 */
public class Sender {
    public static void main(String[] args) throws JMSException {
        //创建连接
        ActiveMQConnectionFactory mqConnectionFactory = new ActiveMQConnectionFactory(
                "admin",
                "123",
                "tcp://localhost:61616");
        Connection connection = mqConnectionFactory.createConnection();
        Session session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
        Queue queue = session.createQueue("queue");
        MessageProducer producer = session.createProducer(queue);
        Girl girl = new Girl("小丽",25,200.00);
        ObjectMessage objectMessage = session.createObjectMessage(girl);
        //发送字节流,图片,文件等相对来说比较小的
        BytesMessage bytesMessage = session.createBytesMessage();
        bytesMessage.writeUTF("发送字节流");

        producer.send(objectMessage);
        producer.send(bytesMessage);

        session.close();
        System.out.println("关闭连接");
    }

}

消息接收者Receiver.java,在接收者里面定义了一个监听器来处理消息

public class Receiver {
    public static void main(String[] args) throws JMSException {
        ActiveMQConnectionFactory mqConnectionFactory = new ActiveMQConnectionFactory(
                "admin",
                "123",
                "tcp://localhost:61616"
        );
        //设置信任持久化类型
        ArrayList<String> list = new ArrayList<String>();
        list.add(Girl.class.getPackage().getName());
        mqConnectionFactory.setTrustedPackages(list);
        Connection connection = mqConnectionFactory.createConnection();
        connection.start();
        Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
        Queue queue = session.createQueue("queue");
        MessageConsumer consumer = session.createConsumer(queue);
        consumer.setMessageListener(new MyListener());
    }

}

监听器MyListener.java

public class MyListener implements MessageListener {
    public void onMessage(Message message) {
        if(message instanceof ObjectMessage){
            ObjectMessage objectMessage = (ObjectMessage) message;
            try {
                Girl girl = (Girl) objectMessage.getObject();
                System.out.println(girl.toString());
            } catch (JMSException e) {
                e.printStackTrace();
            }
        }else if(message instanceof BytesMessage){
            BytesMessage bytesMessage = (BytesMessage) message;
            try {
                System.out.println(bytesMessage.readUTF());
            } catch (JMSException e) {
                e.printStackTrace();
            }
        }
    }
}

运行发送者,接收者就可以看到接收者已经接收到了girl对象和字节流
在这里插入图片描述

死信队列

死信队列是用来保存处理失败或者过期的消息的队列,默认的死信队列是ActiveMQ.DLQ,如果没有特别指定,死信都会被发送到这个队列。默认的持久化消息过去,会被送到DLQ,非持久消息不会送到DLQ,我们可以通过配置文件(activemq.xml)来修改死信队列的配置

1、不使用默认的死信队列
<broker...>
  <destinationPolicy>
    <policyMap>
      <policyEntries>
        <!— 设置所有队列,使用 '>' ,否则用队列名称 -->
        <policyEntry queue=">">
          <deadLetterStrategy>
            <!--
                    queuePrefix:设置死信队列前缀
                    useQueueForQueueMessages: 设置使用队列保存死信,还可以设置useQueueForTopicMessages,使用Topic来保存死信
            -->
            <individualDeadLetterStrategy   queuePrefix="DLQ." useQueueForQueueMessages="true" />
          </deadLetterStrategy>
        </policyEntry>
      </policyEntries>
    </policyMap>
  </destinationPolicy>
  ...
</broker>
2、非持久化消息保存到死信队列
 	  <policyEntry queue=">">
         <deadLetterStrategy>
           <sharedDeadLetterStrategy processNonPersistent="true" />
         </deadLetterStrategy>
       </policyEntry>
3、过期消息不保存到死信队列
	  <policyEntry queue=">">
         <deadLetterStrategy>
           <sharedDeadLetterStrategy processExpired="false" />
         </deadLetterStrategy>
       </policyEntry>
4、持久消息不保存到死信队列

丢弃所有死信

<beans>
  <broker ...>
    <plugins>
      <discardingDLQBrokerPlugin dropAll="true" dropTemporaryTopics="true" dropTemporaryQueues="true" />
    </plugins>
  </broker>
</beans>

丢弃指定目的死信

<beans>
  <broker ...>
    <plugins>
      <discardingDLQBrokerPlugin dropOnly="MY.EXAMPLE.TOPIC.[0-9]{3} MY.EXAMPLE.QUEUE.[0-9]{3}" reportInterval="3000" />
    </plugins>
  </broker>
</beans>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值