个人博客网:https://wushaopei.github.io/    (你想要这里多有)

1、可用性保证

引入消息队列之后该如何保证其高可用性?

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

2、异步投递Async Sends

2.1  异步投递的定义

对于一个Slow Consumer,使用同步发送消息可能出现Producer堵塞的情况,慢消费者适合使用异步发送

如图介绍:

2.2 什么是异步投递

ActiveMQ支持同步,异步两种发送的模式将消息发送到broker,模式的选择对发送延时有巨大的影响。producer能达到怎么样的产出率(产出率=发送数据总量/时间)主要受发送延时的影响,使用异步发送可以显著提高发送的性能。
        ActiveMQ默认使用异步发送的模式:除非明确指定使用同步发送的方式或者在未使用事务的前提下发送持久化的消息,这两种情况都是同步发送的。
        如果你没有使用事务且发送的是持久化的消息,每一次发送都是同步发送的且会阻塞producer知道broker返回一个确认,表示消息已经被安全的持久化到磁盘。确认机制提供了消息安全的保障,但同时会阻塞客户端带来了很大的延时。
很多高性能的应用,允许在失败的情况下有少量的数据丢失。如果你的应用满足这个特点,你可以使用异步发送来提高生产率,即使发送的是持久化的消息。
 
异步发送

  • 它可以最大化producer端的发送效率。我们通常在发送消息量比较密集的情况下使用异步发送,它可以很大的提升Producer性能;不过这也带来了额外的问题,
  • 就是需要消耗更多的Client端内存同时也会导致broker端性能消耗增加;
  • 此外它不能有效的确保消息的发送成功。在userAsyncSend=true的情况下客户端需要容忍消息丢失的可能。

2.3 官网配置参考(投递开启)

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

    //  开启异步投递

    activeMQConnectionFactory.setUseAsyncSend(true);    

2.4 面试题: 异步消息如何确定发送成功?

异步发送丢失消息的场景是:生产者设置userAsyncSend=true,使用producer.send(msg)持续发送消息。

  • 如果消息不阻塞,生产者会认为所有send的消息均被成功发送至MQ。
  • 如果MQ突然宕机,此时生产者端内存中尚未被发送至MQ的消息都会丢失。
  • 所以,正确的异步发送方法是需要接收回调的。

同步发送和异步发送的区别就在此,

  • 同步大宋等send不阻塞了就表示一定发送成功了,
  • 异步发送需要客户端回执并由客户端再判断一次是否发送成功

具体实现的代码案例:

JmsProduce_AsyncSend   在代码中接收回调的函数 :

package com.demo;

import org.apache.activemq.ActiveMQConnectionFactory;
import org.apache.activemq.ActiveMQMessageProducer;
import org.apache.activemq.AsyncCallback; import javax.jms.*;
import java.util.UUID; public class Producer {
private static final String ACTIVEMQ_URL = "tcp://192.168.10.130:61616";
private static final String ACTIVEMQ_QUEUE_NAME = "Queue-异步投递回调"; public static void main(String[] args) throws JMSException {
ActiveMQConnectionFactory activeMQConnectionFactory = new ActiveMQConnectionFactory();
activeMQConnectionFactory.setBrokerURL(ACTIVEMQ_URL);
//开启异步投递
activeMQConnectionFactory.setUseAsyncSend(true);
Connection connection = activeMQConnectionFactory.createConnection();
connection.start(); Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Queue queue = session.createQueue(ACTIVEMQ_QUEUE_NAME);
//向上转型到ActiveMQMessageProducer
ActiveMQMessageProducer activeMQMessageProducer = (ActiveMQMessageProducer) session.createProducer(queue); for (int i = 0; i < 3; i++) {
TextMessage textMessage = session.createTextMessage("message-" + i);
textMessage.setJMSMessageID(UUID.randomUUID().toString() + "----orderAtguigu");
String textMessageId = textMessage.getJMSMessageID();
//使用ActiveMQMessageProducer的发送消息,可以创建回调
activeMQMessageProducer.send(textMessage, new AsyncCallback() {
@Override
public void onSuccess() {
System.out.println(textMessageId + "发送成功");
} @Override
public void onException(JMSException exception) {
System.out.println(textMessageId + "发送失败");
}
});
}
activeMQMessageProducer.close();
session.close();
connection.close();
}
}

3、延时投递和定时投递

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

3.2 代码编写

  • 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); }

4、 Activemq的消息重试机制

(1)由消息丢失或延时而引发的问题——常见面试题

具体哪些情况会引发消息重发

  1. Client用了transactions且再session中调用了rollback
  2. Client用了transactions且再调用commit之前关闭或者没有commit
  3. Client再CLIENT_ACKNOWLEDGE的传递模式下,session中调用了recover

请说说消息重发时间间隔和重发次数

  • 间隔:1
    次数:6
     每秒发6次

有毒消息Poison ACK

  • 一个消息被redelivedred超过默认的最大重发次数(默认6次)时,消费的回个MQ发一个“poison ack”表示这个消息有毒,告诉broker不要再发了。这个时候broker会把这个消息放到DLQ(私信队列)。

重试机制的注意事项:

  1. 最多六次还没发出就会
  2. 加入DLQ (死信队列)

官网链接地址: http://activemq.apache.org/redelivery-policy

(2)简单案例说明:

(3)重发整合Spring 的配置

(4)重试机制的属性说明:

5、死信队列

(1)概念: Activemq中引入了“死信队列”(Dead Letter Queue) 的概念。即一条消息再被重发了多次后(默认为重发6次redeliveryCounter==6),将会被Activemq移入“死信队列”,开发人员可以在这个Queue中查看处理出错的消息,进行人工干预。

(2)死信队列的使用:处理失败的消息

(3)死信队列的配置介绍

  • SharedDeadLetterStrategy

  • IndividualDeadLetterStrategy

  • 配置案例

a. 自动删除过期消息

b. 存放非持久消息到死队列中

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

6、 如何保证消息不被重复消费,幂等性的问题

如果消息是做数据库的插入操作,给这个消息一个唯一的主键,那么就算出现重复消费的情况,就会导致主键冲突,避免数据库出现脏数据 。

如果不是,可以用redis 等的第三方服务,给消息一个全局 id ,只要消费过的消息,将 id ,message 以 K-V 形式写入 redis ,那消费者开始消费前,先去 redis 中查询有没消费的记录即可。

ActiveMQ 笔记(八)高级特性和大厂常考重点的更多相关文章

  1. Python:笔记(4)——高级特性

    Python:笔记(4)——高级特性 切片 取一个list或tuple的部分元素是非常常见的操作.Python提供了切片操作符,来完成部分元素的选取 除了上例简单的下标范围取元素外,Python还支持 ...

  2. 分布式-信息方式-ActiveMQ的Destination高级特性1

    ActiveMQ的Destination高级特性 Destination高级特性----->Composite Destinations 组合队列Composite Destinations : ...

  3. python3精简笔记(三)——高级特性

    Python中 1行代码能实现的功能,决不写5行代码.请始终牢记,代码越少,开发效率越高. 切片 取一个list或tuple的部分元素是非常常见的操作.Python提供了切片(Slice)操作符 L ...

  4. ActiveMQ的Destination高级特性

    1.    Composite Destinations  组合目的地 组合队列Composite Destinations : 允许用一个虚拟的destination代表多个destinations ...

  5. python学习笔记(三)高级特性

    一.切片 list.tuple常常截取某一段元素,截取某一段元素的操作很常用 ,所以python提供了切片功能. L=['a','b','c','d','e','f'] #取索引0,到索引3的元素,不 ...

  6. Python学习笔记4 高级特性_20170618

    # 切片(获取list / tuple / 字符串 中指定的元素) l = list(range(10)) l[0:3] l[:3] # 0可以省略 l[:] # 全部 l[3:] # 最后的可以省略 ...

  7. 分布式-信息方式-ActiveMQ的Destination高级特性3

    虚拟destination用来创建逻辑destination,客户端可以通过它来生产和消费消息,它会把消息映射到物理destination. ActiveMQ支持2种方式: 1:虚拟主题(Virtua ...

  8. 分布式-信息方式-ActiveMQ的Destination高级特性2

    使用filtered destinations,在xml配置如下: <destinationInterceptors> <virtualDestinationInterceptor& ...

  9. html5学习笔记3——高级特性

    一:Web存储 数据以 键/值 对存在, web网页的数据只允许该网页访问使用. web存储有两种: localStorage - 没有时间限制的数据存储,存于浏览器缓存 sessionStorage ...

随机推荐

  1. SpringCloudStream学习(四)TTL(存活时间)Dead Letter Exchanges(死信交换机)

    TTL(Time-To-Live and Expiration): RabbitMQ既能对队列设置TTL也能对消息设置TTL,消息TTL可以应用于单个队列.一组队列或应用于逐个消息. 如何给消息设置T ...

  2. SSM的医院管理系统录像

    视频观看地址:http://mp.toutiao.com/preview_article/?pgc_id=6806135073323090444

  3. Linux内核驱动学习(五)KThread学习总结

    文章目录 简介 例程 运行结果 参考 简介 使用内核线程需要包含头文件#include <linux/kthread.h>,下面整理了一下常用的api接口,如下表格所示: 函数 功能 st ...

  4. CodeForces - 1209D Cow and Snacks 并查集

    CodeForces - 1209D 题意 现在n种点心,每种点心只有一份,有k位客人,每位客人有两种想要吃的点心,你可以安排他们进场的顺序,每位客人会吃掉所有他想要吃的,并且还没被吃掉的点心.如果客 ...

  5. Web_python_template_injection

    0x01 pthon模板注入 判断是否为模板注入 paload http://124.126.19.106:34164/{{1+1}} //如果里面的值被执行了,那么存在模板注入 //调用os模块的p ...

  6. webpack 中,module,chunk 和 bundle 的区别是什么?

    前两天为了优化公司的代码打包项目,恶补了很多 webpack4 的知识.要是放在几年前让我学习 webpack 我肯定是拒绝的,之前看过 webpack 的旧文档,比我们内部项目的文档还要简陋. 但是 ...

  7. 「雕爷学编程」Arduino动手做(29)——DS1302时钟模块

    37款传感器与模块的提法,在网络上广泛流传,其实Arduino能够兼容的传感器模块肯定是不止37种的.鉴于本人手头积累了一些传感器和模块,依照实践出真知(一定要动手做)的理念,以学习和交流为目的,这里 ...

  8. 《C程序设计语言》 练习3-5

    问题描述 练习 3-5 编写函数 itob(n, s, b),将整数n转换为以b为底的数,并将转换结果以字符的形式保存到字符串s中.例如,itob(n, s, 16)把整数n格式化成十六进制整数保存在 ...

  9. 判断数组的方法/判断JS数据类型的四种方法

    参考文: 以下 3 个判断数组的方法,请分别介绍它们之间的区别和优劣Object.prototype.toString.call() . instanceof 以及 Array.isArray() h ...

  10. Vue的双向绑定原理

    Vue的构造函数分析 vm就是MVVM中的View Model var vm = new Vue({ el: '#app', data: { message: 'Hello Vue!' } }) /* ...