消息队列

发布时间 2023-03-29 18:00:12作者: java摩卡,一滴不撒

1.组件:

  • 工作流程:生产者发送消息根据路由键到消息代理中的某个交换机,交换机根据规则转发到队列,通过信道传送给消费者。
  • 死信队列:专门处理那些过期,被拒,队列满了处理不了的消息;
  • 信道:建立在TCP上的虚拟链接,TCP由多线程共享,TCP内存在超多信道,一个信道对应一个线程使用。

 

2.消息队列:

  • 理解:消息队列是模块间进行通信的一个中间件。是异步处理消息的,即客户端发送消息后就无需等待服务端操作,而是直接返回,消息到达服务端并处理完成后再次返回结果。
  • 优点:通过异步处理减少系统响应时间;降低模块之间的耦合;大流量时进行削峰限流;
  • 缺点:考虑mq消息的各种问题导致系统复杂性提高;消息丢失或失败造成数据不一致性的情况;

3.JMS和AMQP:

  • JMS是一个api规范,不能跨语言跨平台,可以是多种消息类型,只支持点对点模型和发布订阅模型;
  • AMQP是一个协议,能跨语言跨平台,只能是二进制的消息类型,根据交换机分为五种不同的模式;

4.如何保证消息不会丢失:

  • 发送方:开启confirm机制,维护一个信息表,收到回传的ACK后更新消息状态;为了防止任务过期失效,可以开启定时任务,对于过期未处理任务重新发送。
  • MQ自身:将消息和队列都设置成持久化,将数据写到磁盘中,写完之后再给发送方发送ACK。
  • 接收方:开启手动ACK,任务处理完后手动返回ACK,避免消息未处理完就返回。
  • 高并发:过期的消息,丢弃后,晚上编写程序进行批量重导后再执行。

5.如何保证消息按顺序抵达消费者:

  • 原因:消息抵达不同的消费者+消费者多线程处理消息,无法保证消息按照顺序被执行完毕。
  • 解决:实现多个队列,使得队列和消费者一对一,关键值哈希将有顺序要求的消息按照顺序发到同一个消费者进行处理。

6.如何保证高可用性:

  • 正常情况:采用镜像集群模式,每个节点都有所有queue实例的镜像,消息来了,全部节点都会自动同步。
  • 高并发消息挤压:停掉原有的customer,创建10倍的队列,用新机器创建10倍的customer,写程序将消息挤压的队列数据轮询到新队列里,将队列与customer绑定后处理,相当于十倍速度处理消息。恢复customer

7.如何保证消息不被重复消费:

  • 原因:MQ有消息重传确认的功能,如果消息完成了但是ACK中途丢失了就会导致消息重传。
  • 解决:生产者发送消息之前先生成一个全局唯一的id,将这个id放在消息内,消费者每次先从消息内获得这个id去redis中比对,没有才消费,并放入redis中,设置一个过期时间。