ActiveMQ面试专讲--高级特性

一、引入消息队列后,如何保证其高可用性

持久化、事务、签收、 以及带复制的 Leavel DB + zookeeper 主从集群搭建

二、异步投递(Async send)

对于一个慢消费者,使用同步有可能造成堵塞,消息消费较慢时适合用异步发送消息

activemq 支持同步异步 发送的消息,默认异步。当你主动设定同步发送的方式和 未使用事务的情况下发持久化消息,这时是同步的。

如果没有使用事务,且发送的是持久化消息,每次发送都会阻塞一个生产者直到 broker 发回一个确认,这样做保证了消息的安全送达,但是会阻塞客户端,造成很大延时 。

在高性能要求下,可以使用异步提高producer 的性能。但会消耗较多的client 端内存,也不能完全保证消息发送成功。在useAsyncSend = true 情况下容忍消息丢失

根据官网描述,设置消息异步有三种方式:

url 后面加参数

开启ActivemqFactury 的Async 为true

将connection 设Async 为true

但这样设置为异步发送会有一个问题:允许消息丢失,那如何做到消息投递快并且消息不会被丢失呢?

异步发送消息丢失的情况场景是: UseAsyncSend 为 true 使用 producer(send)持续发送消息,消息不会阻塞,生产者会认为所有的 send 消息均会被发送到 MQ ,如果MQ 突然宕机,此时生产者端尚未同步到 MQ 的消息均会丢失 。

故 正确的异步发送方法需要接收回调

同步发送和异步发送的区别就在于 :

同步发送send 不阻塞就代表消息发送成功

异步发送需要接收回执并又客户端在判断一次是否发送

在代码中接收回调的方法 :

activeMQConnectionFactory.setUseAsyncSend(true);
    ……  
    
 for (int i = 1; i < 4 ; i++) {
         textMessage = session.createTextMessage("msg--" + i);
        //设置一个唯一id标识此消息
      textMessage.setJMSMessageID(UUID.randomUUID().toString()+"--  orderr");
     String msgid = textMessage.getJMSMessageID();
            messageProducer.send(textMessage, new AsyncCallback() {
                @Override
                public void onSuccess() {
                    // 发送成功怎么样
                    System.out.println(msgid+"has been successful send ");
                }

                @Override
                public void onException(JMSException e) {
                    // 发送失败怎么样
                    System.out.println(msgid+" has been failure send ");
                }
            });
}    

三、延迟投递和定时投递

① 在配置文件中设置定时器开关 为 true

②代码编写

Java 代码中封装的辅助消息类型 ScheduleMessage

可以设置的 常用参数 如下:

long delay = 3 * 1000 ;
long perid = 4 * 1000 ;
int repeat = 7 ;
for (int i = 1; i < 4 ; i++) {
    TextMessage textMessage = session.createTextMessage("delay msg--" + i);
    // 消息每过 3 秒投递,每 4 秒重复投递一次 ,一共重复投递 7 次
    textMessage.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_DELAY,delay);
    textMessage.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_PERIOD,perid);
    textMessage.setLongProperty(ScheduledMessage.AMQ_SCHEDULED_REPEAT,repeat);

    messageProducer.send(textMessage);
}

四、消息重试机制

最多六次还没发出就会

加入DLQ (死信队列)

五、死信队列

可以修改消息进入死信队列的重发次数条件为3次 // 三次的意思是不计算本来发送的第一次

RedeliveryPolicy  redeliveryPolicy = new RedeliveryPolicy();
redeliveryPolicy.setMaximumRedeliveries(3);
activeMQConnectionFactory.setRedeliveryPolicy(redeliveryPolicy);

在spring 中使用 死信机制

在业务逻辑中,如果一个订单系统没有问题,则使用正常的业务队列,当出现问题,则加入死信队列 ,此时可以选择人工干预还是机器处理 。

死信队列默认是全部共享的,但是也可以设置独立的死信队列

独立的死信队列配置

六、如何保证消息不会被重复消费,也就是幂等性问题。

七、ActiveMQ中的观察者模式

观察者模式 、 发布订阅者设计模式 :

观察者模式 : 对象间的一对多的依赖关系

何谓观察者模式?观察者模式定义了对象之间的一对多依赖关系,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并且自动更新。

在这里,发生改变的对象称之为观察目标,而被通知的对象称之为观察者。一个观察目标可以对应多个观察者,而且这些观察者之间没有相互联系,所以么可以根据需要增加和删除观察者,使得系统更易于扩展。

发布订阅者 : 是观察者模式的一个概念的变种,

发布/订阅者模式与观察者模式主要有以下几个不同点:

  1. 在观察者模式中,主体维护观察者列表,因此主体知道当状态发生变化时如何通知观察者。然而,在发布者/订阅者中,发布者和订阅者不需要相互了解。它们只需在中间层消息代理(或消息队列)的帮助下进行通信。
  2. 在发布者/订阅者模式中,组件与观察者模式完全分离。在观察者模式中,主题和观察者松散耦合。
  3. 观察者模式主要是以同步方式实现的,即当发生某些事件时,主题调用其所有观察者的适当方法。发布服务器/订阅服务器模式主要以异步方式实现(使用消息队列)。
  4. 发布者/订阅者模式更像是一种跨应用程序 模式。发布服务器和订阅服务器可以驻留在两个不同的应用程序中。它们中的每一个都通过消息代理或消息队列进行通信。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值