zoukankan      html  css  js  c++  java
  • RabbitMQ总结

    消息队列
        三个业务场景:解耦、异步、削峰
        带来问题
            系统可用性降低:外部依赖越多,越容易挂掉。
            系统复杂性提高:重复消费,消息丢失,消息传递的顺序性
            一致性问题:
    
    一、如何保证消息的可靠性传输(如何处理消息丢失的问题)
    从三个方面分析:
        1)生产者发送时弄丢了数据
        解决方法1:生产者发送数据之前开启rabbitmq事务(channel.txtSelect),然后发送消息。
                   如果消息没有成功被rabbitmq接收到,生产者收到异常报错,回滚事物(channel.txRollback)。重发消息。
                   如果消息成功接收,提交事务(channel.txCommit)
            缺点:事物机制,吞吐量会下来,因为太耗性能。
        
        解决方法2:生产者开启confirm模式,每次写消息,会分配一个guid。
                   如果rabbitmq接收失败,会返回一个nack,重新发送。
                   如果rabbitmq接收成功,会返回一个ack。
            事物机制是同步的,会阻塞。
            confirm机制是异步的,消息rabbitmq接收了之后会异步回调你一个接口通知你这个消息接收到。
            一般在生产者这块避免数据丢失,都是用confirm机制的。    
            
        2)rabbitmq弄丢了数据
        解决方法:开启rabbitmq的持久化,消息写入之后会持久化到磁盘。
                  两步:①创建queue时,durable设置为True
                        ②发送消息时,deliveryMode设置为2
        
        3)消费端弄丢了数据  
        解决方法:ack机制,取消消费端的自动应答,变为手动应答,每次代码处理完成之后,程序里ack。
                  channel.basicConsume(QUEUE_NAME, false, consumer)//第二个参数false,表示手动应答。
                  channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false)//返回确认状态
                  
    
    二、如何保证消息不被重复消费(保证消息消费时的幂等性)    
        解决办法:每个消息弄一个编号id,consumer消费了数据之后,每隔一段时间,会把自己消费过的消息的id提交一下。
                但是这样还会有一个问题,重启,进程kill,consumer没来的及提交id,还是会重复消费?
                这个从业务上解决比较好:
                栗子:
                    消费一条往数据库插入一条,消费第二次的时候,判断是不是消费过了,直接扔到。
        
        幂等性:就一个数据,或者一个请求,给你重复来多次,确保对应的数据是不会改变的,不能出错
                栗子:数据库的话,先根据逐渐查下,如果有了,更新或者丢弃都行。
                      redis,直接弄一个set,天然幂等性。
        
    三、如何保证消息的顺序性    
        解决办法1:用单线程消费,保证顺序性。
        解决办法2:对消息进行编号,消费者处理时根据编号判断顺序。 
        rabbitmq:拆分多个queue,每个queue一个consumer,就是多一些queue而已,确实是麻烦点;
        或者就一个queue但是对应一个consumer,然后这个consumer内部用内存队列做排队,然后分发给底层不同的worker来处理。
    
    四、消息队列的延时以及过期失效问题?消息队列满了以后该怎么处理?有几百万消息持续积压几小时,说说怎么解决?
        1.队列满了,可能是消费端问题,多建几个临时消费者。
        2.过期时间(TTL),消息丢掉之后,从新导入,可以在高峰期过后操作。
        假设1万个订单积压在mq里面,没有处理,其中1000个订单都丢了,你只能手动写程序把那1000个订单给查出来,手动发到mq里去再补一次
    
    五、消息队列,该如何进行架构设计
        可伸缩性:增加吞吐量和容量,参考kafka设计。
        持久化:
        高可用性:

    参考文章:https://blog.csdn.net/HiBoyljw/article/details/85123099

    为rabbitmq添加远程访问用户

    [root@localhost sbin]# ./rabbitmqctl  list_users     #用户列表
    Listing users ...
    [root@localhost sbin]# ./rabbitmqctl add_user admin admin 
    Creating user "admin" ...
    [root@localhost sbin]#./rabbitmqctl set_user_tags admin administrator 
    Setting tags for user "admin" to [administrator] ...
    [root@localhost sbin]#./rabbitmqctl set_permissions -p "/" admin ".*" ".*" ".*" 
    Setting permissions for user "admin" in vhost "/" ...
    [root@localhost sbin]# ./rabbitmqctl list_users 
    Listing users ...
    admin    [administrator]
    [root@localhost sbin]#
  • 相关阅读:
    老男孩python学习_day004知识点
    老男孩python学习_day003作业
    老男孩python学习_day003知识点
    老男孩python学习_day002知识点
    老男孩python学习_day001知识点
    老男孩python学习_day002作业
    老男孩python学习_day001作业
    Struts2+Spring4+Hibernate4整合超详细教程
    解决 Ubuntu15.04 登陆界面无限循环 的问题
    jsp之间url传值出现中文乱码
  • 原文地址:https://www.cnblogs.com/sdadx/p/8718111.html
Copyright © 2011-2022 走看看