消息队列
⚫ activeMq的几种通信方式?
1、发布订阅模式
2、点对点
⚫ 丢消息怎么办?如何解决消息丢失?
持久化
不推荐使用消息事务,会验证降低性能
生产者确认(publisher confirm):生产者发送消息后,等待mq的ACK,如果没有收到或者收到失败信息,则重试。如果收到成功消息则业务结束
⚫ 点对点消息消费者出异常怎么办?
⚫ 持久化消息非常慢。
⚫ 消息的不均匀消费。
⚫ 如何避免消息堆积?
-通过同一个队列多消费者监听,实现消息的争抢,加快消息消费速度。
⚫ 如何避免消息重复消费?
保证接口幂等即可,那么如何保证接口幂等呢?
- 某些接口天生幂等,例如查询请求
- 某些接口天生不幂等,比如新增,还有某些接口的修改功能
- 能根据具体的业务或状态来确定的,在消费端通过业务判断是否执行过
⚫ 能说一下消息队列吗然后为什么要用他
mq的话总共有4种在第一个项目中用到的是ActivMQ因为第一个项目比较传统用到的技术也比较老了但是都是经过时间的考验了非常稳定,然后他的特点支持的协议和编程语言都很广泛
对JMS消息服务无缝贴合的支持和javaEE的规范都是非常支持的能很好的实现集群化
** ⚫ ActiveMQ服务器宕机怎么办?**
这得从ActiveMQ的储存机制说起。在通常的情况下,非持久化消息是存储在内存中的,持久化消息是存储在文件中的,它们的最大限制在配置文件的
那如果文件增大到达了配置中的最大限制的时候会发生什么?我做了以下实验:
设置2G左右的持久化文件限制,大量生产持久化消息直到文件达到最大限制,此时生产者阻塞,但消费者可正常连接并消费消息,等消息消费掉一部分,文件删除又腾出空间之后,生产者又可继续发送消息,服务自动恢复正常。
设置2G左右的临时文件限制,大量生产非持久化消息并写入临时文件,在达到最大限制时,生产者阻塞,消费者可正常连接但不能消费消息,或者原本慢速消费的消费者,消费突然停止。整个系统可连接,但是无法提供服务,就这样挂了。
具体原因不详,解决方案:尽量不要用非持久化消息,非要用的话,将临时文件限制尽可能的调大。
⚫ 死信队列
如果你想在消息处理失败后,不被服务器删除,还能被其他消费者处理或重试,可以关闭AUTO_ACKNOWLEDGE,将ack交由程序自己处理。那如果使用了AUTO_ACKNOWLEDGE,消息是什么时候被确认的,还有没有阻止消息确认的方法?有!
消费消息有2种方法,一种是调用consumer.receive()方法,该方法将阻塞直到获得并返回一条消息。这种情况下,消息返回给方法调用者之后就自动被确认了。另一种方法是采用listener回调函数,在有消息到达时,会调用listener接口的onMessage方法。在这种情况下,在onMessage方法执行完毕后,消息才会被确认,此时只要在方法中抛出异常,该消息就不会被确认。那么问题来了,如果一条消息不能被处理,会被退回服务器重新分配,如果只有一个消费者,该消息又会重新被获取,重新抛异常。就算有多个消费者,往往在一个服务器上不能处理的消息,在另外的服务器上依然不能被处理。难道就这么退回--获取--报错死循环了吗?
⚫ 如何保证消息中间件的高可用?
⚫ 消息队列积压了大量的消息,你该怎么处理?
⚫ 如何保证消费者消费消息是有顺序的?
⚫ 大量的消息被消费,能否oom异常?
可控制每个消息队列中数据的大小,不容许出现无限填充数据,避免该队列过大,导致过度消耗系统资源问题,可以控制队列内存的大小。
⚫ activemq发消息的方式有哪些?
⚫ activeMQ如果数据提交不成功怎么办?
答:该问题比较模糊,具体activemq的问题如下:
1、消费者接收消息不成功,怎么办?
对于activemq来说,如果消息生产者没有把消息发送到mq中的broker里面,则消息不会重新发送。
如果消息生产者已经把消息发送到mq中的broker里面,但是消息的消费者没有应答(可能没有接收到,也可能是接收到之后,处理业务逻辑时出现异常)。此时activemq会默认最多重发6次消息,如果依然没有接收到消息,那么该消息会进入DLQ(Dead Letter Queue死信队列)。
2、消息接收成功,但是处理出现异常,或者没有应答怎么办?
在程序中捕获异常,将消息重新放入MQ,由其它消费方再次处理。
ActiveMQ 如果数据提交不成功怎么办?
Activemq 有两种通信方式,点到点形式和发布订阅模式。如果是点到点模式的话,如果消息发送不成功此
消息默认会保存到 activemq 服务端知道有消费者将其消费,所以此时消息是不会丢失的。
如果是发布订阅模式的通信方式,默认情况下只通知一次,如果接收不到此消息就没有了。这种场景只适
用于对消息送达率要求不高的情况。如果要求消息必须送达不可以丢失的话,需要配置持久订阅。每个订
阅端定义一个 id,在订阅是向 activemq 注册。发布消息和接收消息时需要配置发送模式为持久化。此时如
果客户端接收不到消息,消息会持久化到服务端,直到客户端正常接收后为止。
⚫ 如何解决消息重复的问题
⚫ 如何解决消息丢失问题?
https://www.cnblogs.com/756623607-zhang/p/10507267.html
⚫ 给我讲一下 ActiveMQ 这个技术
(What ActiveMQ 是什么?)
先说 jms 规范
讲这个 ActiveMQ,需要先聊到 java 中有一个 JMS 规范,就是 java 消息服务规范,这套规
范包含点对点,订阅两种方式来收发消息,简单来说的话,就是 JMS 制定了这样一个规范,
里边的 API 与具体的平台无关。
ActiveMQ 是支持 JMS 规范的一个开源技术,它支持好多通讯协议,像我们最常用的 TCP 和
UDP,它都支持,activeMQ 支持多种通讯协议 TCP/UDP 等。对于 TCP 协议,我们知道 TCP 有
一个三次握手,所谓的三次握手可以这样来理解,比如 A 和 B 建立连接时,首先 A 向 B 发出
一个同步请求,然后 B 回复一个同步请求应答,最后 A 回复一个确认信息。
ActiveMQ 消息如何发送接收
就拿 ActiveMQ 中所支持的 TCP 协议来说,ActiveMQ 初始化时,通过类根据配置打开 TCP 侦
听端口,客户通过该端口发起建立链接的动作。 生产者发送一个消息,进入到消息队列中,
然后消费者可以从队列中取出消息
在 ActiveMQ 中分为生产者和消费者,生产者发送消息,消费者接受消息,里边有一个比较
重要的机制叫做消息中转器,它是 activeMQ 的核心,消息会先经过中转器,然后再分发给
消费者
发送消息方式
对于 ActiveMQ 发送消息的方式,是分为两种的,其实它也是符合 JMS 规范的,就是点对点
和订阅消息类型,对于点对点,每个消息只能有一个消费者,这种方式是基于队列的,如果
消息不被消费,就会一直阻塞在队列中,只有当消费者消费之后消息才会消失。
对于订阅方式,它是基于主题 topic 的,可以有多个消费者,类似于广播,只要你订阅了,
就能够收到这个消息,如果发的时候还没启动消费者,那这个消息就会被错过。
心跳机制
还有这个 ActiveMQ 还有一个心跳的机制,这种机制可以判断收发双方链路是否通畅,它内
部使用的机制是双向心跳,也就是 ActiveMQ 的生产者和消费者都进行相互心跳。心跳这里
会产生两个线程,一个是“ReadCheck”“WriteCheck”,它们都是 timer 类型,每隔一段
时间都会被调用一次.
其实这个 ActiveMQ 的信息还是挺多的,比如它发送消息能实现即时发送,还能实现定时,延
时发送.
28、ActiveMQ 原理
ActiveMQ 收发消息的原理和具体流程大约是这样的:
发送方:
创建一个连接消息中转服务器的连接工厂。
根据这个工厂获取到一个具体的 connection
启动连接,创建 session 回话
设置发送消息的类型,可以指定 topic 也可以指定点对点
将消息发送出去
消费方:
也是创建一个连接消息中转服务器的连接工厂
根据这个工厂获取到一个具体的 connection
启动连接,创建 session 会话
定义消息消费者,准备接收消息
设置一个消息接收的监听者,当有消息回调接收到的时候,回调到 onMessage 方法中
(Why 为什么使用 ActiveMQ)
我们做的项目由于是分布式项目,各个模块之间都是相互独立的,就会有这样的需求,比如
模块之间的通信问题,或者高并发,就会用到消息队列,消息队列的话,常用的有
RabbitMQ,ActiveMQ,阿里的 RocketMQ,rabbitmq 支持的协议比较多,是一种重量级的消息框
架,阿里的 rocketmq 没有用过,我们常用的是 activeMQ,属于轻量级的。
(How ActiveMQ 怎么用)
使用场景
对于 ActiveMQ 在我们开发中,主要应用到这么几个场景,比如,我们的项目现在都是分布
式的,咱们不可能在一个模块中实现所有的功能,就拿商品管理模块来说,当对商品做添加,
修改,删除操作时,其他模块也有可能有相关连的变化,比如前台模块中的搜索,商品信息
变了,索引库中内容也应该有相应的变化,这个时候呢,我们就需要用到一个通信机制,那
ActiveMQ 这种类型的框架我们就恰好需要的,可以在商品操作时,发送一个消息说我商品
信息改变了,当然需要指明哪一个商品发生了变化,发送对应的商品 id 就行,在前台模块
中,我们配置一个消息接收端,当接收到消息时,对索引库做下修改就行。
当然,除了商品添加同步更新索引库,像商品详情模块,在商品审核通过以后,想消息队列中
发送了一个商品 id 到消息队列中,pageService 工程中有一个监听类,可以生成相应的静态
页面,,还有订单模块也有用到过,当执行生成订单,进行银行扣款,扣款成功,减库存啊,
这种类型的操作,都可以通过 ActiveMQ 发生消息来实行同步操作。
具体操作
以上呢,是介绍一下 ActiveMQ,对于 ActiveMQ 的使用,我们是这样来做的
,拷贝一个 ActiveMQ 压缩包放到在 Linux 服务器上,解压,用./activemq 启动 activemq,这
个就是我刚才所说的消息中转服务器,我们还可以访问一个管理界面,能够查看收发消息的
状态。
在 maven 项目,我们需要在 pom 文件中配置 activemq 的 jar 包信息
在发送端的 springmvc 的配置文件中配置 mq 的连接工厂,指定消息服务器的 ip 端口,配置
Spring 提供的 JMS 模板类工具类(jmsTemplate),配置发送消息的类型。在需要进行发送的
代码逻辑中,直接使用 spring 提供的模板类 jmsTemplate.send 就可以了,至于发送的内容,
可以自己指定。是文本类型,还是消息对象消息,按需求指定就可以。
同样的,在 Springmvc 配置工厂,服务 ip 端口,还需要额外指定一个监听器,这个监听器
就是自己定义的一个类,实现 MessageListener ,当收到消息时,就会触发里边的一个回
调方法,把消息取出来,执行相应逻辑就可以。
⚫ RabbitMQ的应用场景以及基本原理介绍
https://cloud.tencent.com/developer/article/1079026
⚫ RabbitMQ的缺点
1、系统可用性降低
2、系统复杂性提高
3、一致性问题
⚫ Kafka、ActiveMq、RabbitMq、RocketMq各有什么优缺点?
⚫ MQ有哪些常见问题?如何解决这些问题?
1、消息的顺序问题
2、消息的重复问题
⚫ RabbitMQ的工作模式
1、simple模式
2、work工作模式
3、publish/subscribe发布订阅
4、routing路由模式
5、topic主题模式
⚫ `如何保证RabbitMQ消息的顺序性
⚫ 消息如何分发?
⚫ 消息如何路由?
⚫ 如何保证消息不被重复消费?或者说,如何保证消息消费时的幂等性
⚫ 如何保证RabbitMq消息的可靠传输?
⚫ 为什么不应该对所有的message都适用持久化机制?
⚫ 如何保证高可用的?RabbitMQ的集群
⚫ 如何解决消息队列的延时以及过期失效问题?消息队列满了以后应该怎么处理?有几百万消息持续积压几个小时,说说怎么解决?
⚫ rabbitmq设置过期时间,部分消息丢失,如何解决?
采用批量重导方法:将丢失的那批数据查询导入到mq里面。
⚫ 如何保证消息正确的发送至RabbitMQ?
Rabbitmq使用发送方确认模式,确保消息正确的发送到RabbitMq。
发送方确认模式:将信道设置为confirm模式(发送方确认模式)则所有在信道发布的消息都会指派一个唯一的ID,一旦消息被投递到目的队列后,或者消息被写入磁盘后(可持久化的消息),信道会发送一个确认给生产者(包含消息唯一ID)。如果RabbitMQ发生内部错误从而导致消息丢失,会发送一条nack(not acknowledged,未确认)消息。
⚫ 如何确保消息接受方消费了消息?
接收方消息确认机制:消费者接受每一个消息都必须进行确认(消息接受和消息确认是两个不同操作)只有消费者确认了消息,RabbitMQ才能安全的把消息从队列中删除。
这里没有用到超时机制,RabbitMq仅通过Comsumer的连接中断确认是否需要重新发送消息。也就是说,只要连接不中断,RabbitMq给了Consumer足够长的时间来处理消息。
⚫ 如何避免消息重复投递或者重复消费
在消息生产时,MQ内部针对每条生产者发送的消息生成inner-msg-id,作为去重和幂等的依据)(消息投递失败并重传),避免重复的消息进入队列;在消息消费时,要求消息体中必须要有一个bizid(对于同一业务全局唯一)作为去重和幂等的依据,避免同一消息被重复消费。
⚫ RabbitMq如何保证数据一致性
1、生产者确认机制:消息持久化后异步回调通知生产者,确保消息已经发出去;
2、消息持久化:设置消息持久化;
3、消息确认机制:消息者成功消费消息之后,手动确认,保证消息已经消费。