* ?为什么需要使用消息队列 ?
* ◆ 消息队列就是一种中间件,提供不同平台,不同语言的应用程序之间,提供可靠的,持久的异步通讯机制
* -通常提供队列和主题、发布、订阅两种机制,当需要使用消息的时候,可以取出消息供自己使用。
* ◆ 使用消息队列,主要为了通过'异步处理'来提高系统性能和削峰、降低系统耦合性。
* ◆ 目前使用较多的消息队列有 ActiveMQ RabbitMQ、Kafka、RocketMQ 等.
*
*
* ?说一下,系统中使用MQ解决来什么问题呢?(消息队列的作用)
* ‣ 1-异步处理减少响应时间;
* -使用消息队列,可以对业务进行异步处理达到减少响应时间的目的。
* ‣ 2-减低系统耦合性;
* ◆ 消息队列使,利用发布-订阅模式工作,消息发送者发布消息,一个或多个消息接受者订阅消息。
* ◆ 消息发送者和消息接受者之间没有直接耦合,达到解耦的目的。
* ◆ 对新增业务,只要对该类消息感兴趣,即可订阅该消息,对原有系统和业务没有任何影响,从而实现网站业务的可扩展设计。
*‣ 3-削峰
* ◆ 通过异步处理,将短时间高并发产生的事务消息存储在消息队列中,从而削平高峰的并发事务。
* ◆ 在电商一些秒杀,促销活动中,使用消息队列可以有效促销活动刚开始大量订单涌入对系统的冲击。
*
* ?使用消息队列带来的问题?
* ▸ 1-降低系统可用性
* ▵在加入MQ之前,业务逻辑是顺序执行的,加入MQ业务可以异步执行,但是需要考虑打动MQ的消息丢失和MQ挂掉等情况。
* ‣ 2-提高系统的复杂性
* ▵加入MQ之后,你需要保证消息没有被重复消费,处理消息丢失的情况,保证消息传递的顺序性等问题。
* ‣ 3-存在一致性的问题
* ▵消息队列可以实现异步,消息队列带来的异步确实可以提高系统响应速度。但是,万一消息的真正消息者并没有正在消费消息怎么办;
* --这样反而影响类正常的业务逻辑了。
*
* ?JMS-规范和AMQP-规范 ?
* ✧ -描述一个JMS和AMQP的是什么?
* ▵ JMS(Java Message Service):Java消息服务
* -JMS 的客户端之间可以通过JMS服务进行异步的消息传输。
* -JMS 的API是一个消息服务的规范,允许应用程序组件 基于JavaEE平台创建、发送、接收和读取消息.
*
* ▵ AMQP(Advanced Message Queuing Protocol):高级消息队列协议
* -是一个提供统一消息服务的应用层标准,是应用层协议的一个开发标准;
* -为面向消息的中间件设计,兼容JMS。
* -基于此协议的客户端与中间件可传递消息,不受客户端/中间件不同产品,不同开发语言等限制。
*
* JMS消息与消息客户端,传输的类型有那些,使用的什么类型的消息?
* 1、StreamMessage : Java原始值的数据流
* 2、MapMessage : 名-值对
* 3、TextMessage : 字符串对象
* 4、ObjectMessage : 序列化的Java对象
* 5、BytesMessage : 字节的数据流
*
* ?使用的什么消息发送模式??
* JMS的消息模式有
* ◆ 点对点的消息模式(Point to Point Messaging)
* ➢ 消息发送队列目的地(Queue),这个队列只有一个人可以接受到它对应的属于自己的消息。
* ➢ 在消息未过期之前,消费者(接受者)可以任意时间接受;
* ➢ 消费者在接受后,必须反馈信息,表示信息被接受,否则JMS不认为消息被接受。
* ◆ 发布订阅模式(Publish-subscribe Mode)
* ➢ 每个消息都可以有多个订阅者;
* ➢ 订阅者必须保持活动状态等待发布者发布的消息;
*
* JMS-属于Java API,传承格式P2P和PUB/SUB,消息格式5种。
*
* ?ActiveMQ是如何高可用的?
* -由于系统中使用了,MQ 增加了系统的复杂性,为了保证高可用性,
* --ActiveMQ提供了master-slave 和 broker-cluster,两种部署方式来保证其高可用性需求的。
*
* ? 如果服务器意外宕机,怎么做到的重启后恢复消息队列的呢?
* 1、可以采用持久机制实现;
* 2、在发送者将消息发送出去后,消息中心首先将消息存储到本地文件,内存数据库或者远程数据等,
* --然后试图将消息发送给接收者,发送成功则将消息从存储中删除,失败则继续尝试。
* 3、消息中心,启动以后首先要检查指定的存储位置,如果未发送成功的消息,则需要把消息发送出去。
* 4、持久化机制有JDBC、AMQ、KahaDB和LevelDB。
*
* ? 消息持久化机制虽然解决了单机宕机的问题,但是系统稳定性肯定是不宕机为好,如何实现的呢?
* 1、可以使用ActiveMQ的master-slave的架构方式,它和Redis Sentinel主从高可用的方式很像;
* 2、需要借助Zookeeper(集群)注册所有的ActiveMQ Broker;
* 3、只有其中一个Broker可以提供服务,被视为 Master,其它的 Broker处于待机状态,被视为Slave;
* 4、如果Master因故障而不能提供服务,Zookeeper会从Slave中推举一个Broker充当Master.
* 5、Slave连接Master并同步它们的存储状态,Slave 不接受客户端连接。
*
* 不好的地方,解决问题方式-(Broker-Cluster)
* ? Master-Slave的方式虽然能解决多服务,热备的高可用问题,但是可以解决负载均衡和分布式的问题吗?
* 1、Master-Slave的方式无法解决负载均衡和分布式的问题,需要使用Broker-Cluster的方式,解决负载均衡的问题。
* 2、Broker-Cluster部署方式中,各个Broker通过网络互相连接,并共享queue.
*
* ?项目中使用ActiveMQ是使用同步消息还是异步消息?
* ➢ 客户端消费消息的风格有同步和异步两种;
* ➢ 在同一个消费者中只能使用一种风格;
* ➢ 同步是在消费者端调用 receive()方法
* ➢ 异步是使用MessageListener的方式,一般项目中使用异步的方式会多一些。
*
* ?消费者接收到消息后,如何确认的?
* ◆ Auto_ACKNOWLEDGE = 1 自动确认
* ◆ Client_ACKNOWLEDGE = 2 客户端手动确认
* -客户端手动确定需要,在代码中使用ACKNOWLEDGE 方式进行确认。
* ◆ Dups_OK_ACKNOWLEDGE = 3 自动批量确定
* ◆ Session_TRANSACTED = 0 事务提交并确定 session.commit();
* --如果session是事务类型,则消息确定机制必须是这个;
* --如果session是非事务的,则不可以是这个消息确定机制;
* ◆ INDIVIDUAL_ACKNOWLEDGE = 4 单条消息确认 ;
*
* ? 描述以下使用MQ的过程中遇到过什么问题,如果解决的?
* -不均匀消费问题 很常见问题.
* ◆ 有时在发送一些消息之后,开启2个消费者去处理消息,会发现一个消费者处理了所有的消息,另一个消费者根本没收到消息;
* ◆ 原因在于ActiveMQ的prefetch机制,当消费者去获取消息时,不会一条一条去获取,而是一次性获取一批,默认是1000条;
* ➢ 这些预获取的消息,在还没确定消费之前,不会再分配给其他消费者,此时这些恶消息的状态应该算作,"已分配未消费";
* ➢ 如果消息最后被消费,则会在服务器端被删除,如果消费者崩溃,则这些消息会被重新分配给新的消费者。
* -解决方案:将prefetch设置为1,或小点数值,每次处理1次消息,处理完再去取,这样也慢不了多少。
*
* ?消息的重复消费的原因什么?如何解决的?
* ◆ 造成消息重复的根本原因是网络不可达;
* ◆ 保证重复消息对业务逻辑不造成影响;
* ‣ 方案一,保证每条消息都有唯一编号且保证消息处理成功只能保证幂等性,不管来多少条重复消息,
* --最后处理的结果都一样,消费端实现,不属于消息系统要实现的功能,业务代码自定义编写。
* ‣ 方案二,利用一张日志表来记录已经处理成功的消息的ID,如果新到的消息ID,已经在日志表中,
* --那么就不再处理这条消息,消息系统实现,也可以业务端实现。
* ◆ MQ不保证消息不重复,如果业务需要保证严格的不重复消息,需要自己在业务去重。
MQ 消息队列/JMS-规范和AMQP-规范/ActiveMQ是如何高可用
最新推荐文章于 2021-06-22 13:48:41 发布