rabbitmq

rabbitmq, activemq, kafka比较

  • 性能比kafka>rabbitmq>activemq
  • 速度比activemq>rabbitmq>kafka
  • kafka主要用于大数据 activemq可靠性不高,有时会出现问题,消息会丢失,维护越来越少
    rabbitmq支持多种协议,所以是重量级,适合企业应用。可靠性很高,管理页面非常好 综合选择的话选rabbitmq
    rabbitmq缺点不利于二次开发或维护,erlang语言开发,难度较高,不易修改源码
    redis提供消息订阅服务,可以当作mq使用,但是目前案例较少,不方便扩展

消息队列的常见使用场景 :

  1. 解耦:不使用mq时 耦合严重,系统B,C,D都要从A调接口,A需要改代码,需要考虑延时,断掉等问题,
    使用mq以后,A系统只需产生一条数据,放在Mq里,各个系统就可以在mq调用。
  2. 异步:没有用mq太耗时,用mq采用异步的方式,异步化可以大幅度提升高延迟接口的性能。
  3. 削峰:在高峰期 不用mq 用户几百万条数据通过系统到mysql mysql承受的数据在2000条/秒左右,会直接挂掉。
    用mq,在高峰期数据放在mq里,mq每秒只放出2000条到数据库。

存在的问题

  • mq可能会挂掉,导致系统要考虑的问题变多,复杂性变高,
  • 一致性问题,有人给系统A发送个请求,系统ABC都成功D失败了,而导致整个请求 给用户返回的是成功,结果后台 逻辑没有完全执行。
  • 系统A喝MQ协调出现问题,导致系统B内部插入两条一模一样的数据
    解决方式:
  • 高可用:rabbitmq镜像集群模式,你创建的queue,无论元数据还是queue里的消息都会存在于多个实例上,然后每次你写消息到queue的时候,都会自动把消息到多个实例的queue里进行消息同步。
    好处在于,你任何一个机器宕机了,没事儿,别的机器都可以用 坏处 1性能开销大,导致网络带宽压力和消耗很重,2没有扩展性
  • 数据重复:
    (1)根据主键查到重复的数据,就修改
    (2)redis,每次都是set,天然幂等性
    (3)设置唯一键
  • 丢失数据:
    1,生产者弄丢了数据
    (1)使用事务 缺点: 吞吐量会下来,因为太耗性能
    (2)开启confirm模式,在生产者那里设置开启confirm模式之后,你每次写的消息 都会分配一个唯一的id,然后如果写入了rabbitmq中,rabbitmq会给你回传一个ack消息,告诉你说这个消息ok了。如果rabbitmq没能处理这个消息,会回调你一个nack接口,告诉你这个消息接收失败,你可以重试
    2 rabbitmq弄丢了数据
    就是rabbitmq自己弄丢了数据,这个你必须开启rabbitmq的持久化,就是消息写入之后会持久化到磁盘 设置持久化有两个步骤,第一个是创建queue的时候将其设置为持久化的 第二个是发送消息的时候将消息的deliveryMode设置为2,就是将消息设置为持久化的,必须要同时设置 这两个持久化才行,rabbitmq哪怕是挂了,再次重启,也会从磁盘上重启恢复queue,恢复这个queue里的数据。
    3 消费端弄丢了数据
    这个时候得用rabbitmq提供的ack机制,简单来说,就是你关闭rabbitmq自动ack,可以通过一个api来调用就行,然后每次你自己代码里确保处理完的时候,再程序里ack一把。这样的话,如果你还没处理完,就没有ack,那rabbitmq就认为你还没处理完,这个时候rabbitmq会把这个消费分配给别的consumer去处理,消息是不会丢的。
    如何保证消息的顺序性?
    rabbitmq:拆分多个queue,每个queue一个consumer,就是多一些queue而已,确实是麻烦点;
    或者就一个queue但是对应一个consumer,然后这个consumer内部用内存队列做排队,然后分发给底层不同的worker来处理
    大量消息在mq里积压了几个小时了还没解决
    1)先修复consumer的问题,确保其恢复消费速度,然后将现有cnosumer都停掉
    2)新建一个topic,partition是原来的10倍,临时建立好原先10倍或者20倍的queue数量
    3)然后写一个临时的分发数据的consumer程序,这个程序部署上去消费积压的数据,消费之后不做耗时的处理,直接均匀轮询写入临时建立好的10倍数量的queue
    4)接着临时征用10倍的机器来部署consumer,每一批consumer消费一个临时queue的数据
    5)这种做法相当于是临时将queue资源和consumer资源扩大10倍,以正常的10倍速度来消费数据
    6)等快速消费完积压数据之后,得恢复原先部署架构,重新用原先的consumer机器来消费消息
    消息队列满了以后该怎么处理
    如果消息在queue中积压超过一定的时间就会被rabbitmq给清理掉,这个数据就没了
    这就不是说数据会大量积压在mq里,而是大量的数据会直接搞丢。
    我们可以采取一个方案,就是批量重导,将丢失的那批数据,写个临时程序,一点一点的查出来,然后重新灌入mq里面去,假设1万个订单积压在mq里面,没有处理,其中1000个订单都丢了,你只能手动写程序把那1000个订单给查出来,手动发到mq里去再补一次
    有几百万消息持续积压几小时,说说怎么解决?
    临时写程序,接入数据来消费,消费一个丢弃一个,快速消费掉所有的消息,用第二个方案补数据

你可能感兴趣的:(java)