RabbitMq 学习记录 持续更新~~~~

 
    RabbitMq学习:
        
        1.概念:rabbitMq是基于amqp的高级协议,运行速度和socket一致。
        
        2.核心组件:
              broker:服务器(server)
              exchange:
                   1.direct:直接匹配
                   2.topic:模糊匹配
                        #:关键字后面多词模糊匹配
                        *: 关键字后面只匹配一个词
                        通常是消费者这边使用通配符的匹配生产者
                   3.fanout:不需要处理路由件,不走任何的路由key,会将消息发送到指定交换机的指定queue上。
                            性能最好,因为不走路由
                   
              channel:通道,所有操作都在通道完成
              message: 由两部分组成:properties(消息设置)、body(具体内容)
              queue:
              routingkey:
              virtual host:虚拟地址,用于逻辑隔离,最上层的消息路由。同一个virtual host中不能够有相同名字的exchange或者queue
                             
        3.提供者和消费者
            提供者:只关心exchange和routingKey
            消费者:只关心queue和routingKey以及exchange0
            
            如果消息提供者没有指定exchange的话,就会默认使用AMQP DEFAULT exchange 根据routingKey去完全匹配一个queue,
            如果能够匹配就将消息路由出去,否则删除message。
            
            
        4.消息可靠性投递方案
           
            1.消息入库机制,在发送消息之前,将消息入库并这只状态为发送中。消息正常发送到rabbit server并返回confirm,将数据库消息发送状态为完成。设置分布式任务等待server的confirm返回值,如果在规定的时间没有返回值则重新retry 发送消息。在规定的次数内完成发送并收到server的confirm返回值,将数据库状态设置为完成。如在规定的次数未完成,则将数据库消息发送状态设置为失败。后期全部发送完毕之后统一处理(日志信息显示失败原因!rpc调用会出现网络原因)
            
            2.延迟发送:消息提供者首先入库消息的部分信息,同时起连个发送服务,一个立即发送,一个延时发送(具体延时时间看具体情况)新建一个callback listener监听消费者端发送回来的confirm messge以及提供者延时发送的消息,如果能够监听到,则将这条信息入库。如果不能够监听到则提示提供者重新发送信息。当延时发送的消息被监听到,回去数据库中查询是否要这条消息的消费记录,如果有则不运行这条延时发送的消息,如果在规定的时间中依然没有这条消息的消费记录,则消费延时消息。
              
        5.如何避免消息的重复消费?
           
            使用消息提供者端的comfirm listener来监听消息返回值。
            
            返回值为ack or noack
        
        6.如何判断消息提供者提供的消息是否被消费?
        
            使用return listener来监听消息是否被消费。
            
        7.自定义consumer extends DedfaultConsumer就能够实现消费了。
        
        8.消费端的限流处理方式:
        
            为什么要进行消费端限流?
                巨量的消息推送过来,单个客户端无法同时处理这些海量的数据,可能会导致客户端宕机,故需要进行消费端限流配置。RabbitMq提供了一种qos功能,在非自动确认消息的前提下,如果一定数目的消息未被确认前,不进行消费新的消息

            原生api:defaultConsumer.basicqos(int perfetchSize,int perfetchCount,bollean gloal)
            
            perfetchSize: 0 表示不指定上限,其他的数字表示指定上限。
            
            perfetchCount:表示客户端(消费者端)能够同时接收的最大消息数量
            
            gloal: true 便是针对整个channel,faalse针对的是 consumer
        
        注意事项:要想使用qos进行限流,必须将ack设置为手动ack
        
        Demo:
        
           /**
         *  声明一个exchange
         */
        channel.exchangeDeclare(exchangeName,exchangeType,true);
        /**
         *  声明一个队列
         */
        channel.queueDeclare(queueName,true,false,false,null);
        channel.queueBind(queueName,exchangeName,routingKey);
        /**   指定提供者的数量    指定同时过来多少条,其余的要等到这些ack后再过来  

                 是否全局化true针对channel false consumer
         *    int prefetchSize, int prefetchCount,  boolean global
         */
        channel.basicQos(0,3,false);
        DefaultConsumer consumer = new MyConsumer(channel);
        /**
         * String queue, boolean autoAck, Consumer callback
         */
        channel.basicConsume(queueName,false,consumer);

        
        
        9.ack和手动ack
            
            ack是消费者是否成功消费消息的标识,其中关键配置参数为:Boolean autoAck true = 自动ack false=手动ack
            
            provider可以用 confirm listener来监听消息是否被消费,同时给出相关处理。
            
            手动ack需要在自定义的消费者中,直接根据某个条件来判断其是否ack。
              basicAck() 为成功消费消息!
              basicNack() 手动消费失败!
              
        10.死信队列 dlx dead letter exchange
        
            什么情况下消息会进入死信队列?
            
             1.消息没有被成功消费,同时在手动nack处理时参数requeue被设置为false,这时候消息会进入死信队列。
             2.消息时间过期,TTL过期,超过设置的最大消息存活时间。
             3.超过设置qos中的最大队列数:perftchSize
             
            死信队列的声明:在消费端声明,和其他的交换机声明方式一致。死信队列数据存放在队列里面。
            
            
        11.自定义adpter中必须实现一个默认方法名:handleMessage
        
        
        12.springboot 注解接收消息:
        
            @RabbitHandler
            @RabbitListener(指定queue、指定exchange、指定routingkey)
            
            onmessage(@Payload  目标属性 @Headers  需要的属性内容)
            
            从properties里面读取数据只需要使用${springboot.rabbitMq.exchange.name} 表达式形式处理就ok了
            
            
        13.集群的恢复。
        
            1.正常的A、B(b为master)关闭停机。
                先启动A,30s后启动B。或者先启动B再启动A即可。
                
            2.A B同时停机(机房掉电等原因)。
                只需要在30s内启动A B两个节点即可。
                
            3.A(备用节点)挂了,B(主节点)没有挂。
                启动B(主节点),然后再主节点上执行rabbitmqctl forget_cluster-node-A 解除A节点和本集群的关系,然后再新启动一个节点作为从(备)节点加入到该集群即可
            
            4.A(备用节点)没挂,B(主)节点挂掉了。
                先启动A节点,然后再A节点上启动命令:rabbitmqctl forget_cluster-node-B_offline 就可以在主节点不在线的情况下解除主节点和该集群的绑定,然后再将A作为主节点,最后新启动一个新的节点作为从节点加入该集群即可。
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
            
        
        
            
        

原创文章 18 获赞 3 访问量 1630

猜你喜欢

转载自blog.csdn.net/qq_39941165/article/details/104740839
今日推荐