• RabbitMQ入门


    RabbitMQ

    介绍

    MQ全称为Message Queue,即消息队列。“消息队列”是在消息的传输过程中保存消息的容器。它是典型的:生产者、消费者模型。生产者不断向消息队列中生产消息,消费者不断的从队列中获取消息。因为消息的生产和消费都 是异步的,而且只关心消息的发送和接收,没有业务逻辑的侵入,这样就实现了生产者和消费者的解耦。

    优势

    1. 应用解耦

    在多个系统中加了一层,实现解耦

    1. 异步提速

    将消息写入消息队列,消息队列统一给各个系统发送消息,实现异步提速

    1. 削峰填谷

      MQ可以存储很多请求信息(相比于系统服务器),系统可以再去慢慢从MQ中拉取请求并消费 .

      也就是说,将要处理的数据存储起来让系统在其可承受范围内来处理,提高了系统的稳定性

    劣势

    1. 系统可用性降低

    引入的依赖越多,可用性越差,一旦MQ宕机,会对业务造成影响,如何保证MQ高可用

    1. 系统复杂度提高

    异步调用,如何保证消息没有被重复消费?怎么处理消息丢失?保证消息传递顺序

    1. 一致性问题

    需要保证各系统间数据处理的一致性

    与同类产品相比

    吞吐量略低于RocketMQ和Kafka,性能极好,消息延迟低,社区活跃,管理界面丰富.

    rb1

    一个连接的channel对应一个交换机,交换机与队列绑定并通信,

    安装&配置

    三个包

    erlang语言包

    erlang内存管理

    rabbitmq安装包

    erlang-22.0.7-1.el7.x86_64.rpm
    socat-1.7.3.2-2.el7.x86_64.rpm
    rabbitmq-server-3.7.18-1.el7.noarch.rpm
    

    3个命令

    rpm -ivh xxx1.rpm

    rpm -ivh xxx2.rpm

    ......

    配置

    安装完成后,默认会使用 /etc/rabbitmq/下的rabbitmq.config(需要自己上传)

    cd /usr/share/doc/rabbitmq-server-3.7.18/

    find / -name rabbitmq.config.example

    • 安装vim

    yum install -y vim

    • 配置文件
    注意:默认安装完成后配置文件模板在:/usr/share/doc/rabbitmq-server-3.7.18/rabbitmq.config.examp1e目录中,需要将配置文件复制到/etc/rabbitmq/目录中,
    并修改名称为rabbitmq.config
    
    cp /usr/share/doc/rabbitmq-server-3.7.18/rabbitmq.config.example /etc/rabbitmq/rabbitmq.config  #把原配置文件copy过去
    
    ls /etc/rabbitmq/rabbitmq.config #查看配置文件位置
    
    vim /etc/rabbitmq/rabbitmq.config #修改成自己的配置文件
    
    • 打开web管理界面

    修改用户配置权限(来宾账户) 添加了才能使用web管理界面

    找到 %%{loopback_users, []}, 删除%%注释 改成 {loopback_users, []}

    • 执行如下命令,启动rabbitmq中的插件管理

      rabbitmq-plugins enable rabbitmq_management
      

    查看服务状态

    systemctl status rabbitmq-server
    

    **启停RabbitMQ的服务 **

    systemctl start rabbitmq-server    #  启动
    
    systemctl restart rabbitmq-server  # 重启
    
    systemctl stop rabbitmq-server     # 关闭
    

    出现:

    [root@RabbitMQServer myFile]# systemctl status rabbitmq-server
    ● rabbitmq-server.service - RabbitMQ broker
       Loaded: loaded (/usr/lib/systemd/system/rabbitmq-server.service; disabled; vendor preset: disabled)
       Active: inactive (dead)
    [root@RabbitMQServer myFile]# systemctl start rabbitmq-server
    [root@RabbitMQServer myFile]# systemctl status rabbitmq-server
    ● rabbitmq-server.service - RabbitMQ broker
       Loaded: loaded (/usr/lib/systemd/system/rabbitmq-server.service; disabled; vendor preset: disabled)
       Active: active (running) since 一 2022-01-03 20:15:16 CST; 1min 40s ago
     Main PID: 1500 (beam.smp)
       Status: "Initialized"
       CGroup: /system.slice/rabbitmq-server.service
               ├─1500 /usr/lib64/erlang/erts-10.4.4/bin/beam.smp -W w -A 64 -MBas ageffcbf -MHas ageffcbf -MBlmbcs 51...
               ├─1718 /usr/lib64/erlang/erts-10.4.4/bin/epmd -daemon
               ├─1862 erl_child_setup 32768
               ├─1885 inet_gethost 4
               └─1886 inet_gethost 4
    
    

    关闭防火墙服务

    systemctl status firewalld #查看
    
    systemctl disable firewalld #禁用
    	Removed symlink /etc/systemd/system/multi-user.target.wants/firewalld.service.
    	Removed symlink /etc/systemd/system/dbus-org.fedoraproject.FirewallD1.service.
    
    systemctl stop firewalld #关闭
    

    help命令

    rabbitmqctl help

    进入管理界面

    http://192.168.5.102:15672/

    输入2个guest登录

    工作模式

    rb2

    rb3

    简单直连

    rb4

    工作队列

    其实就是直连队列,有多个消费者竞争消息

    rb1

    • 1个消息只能发给1个消费者,采用轮询方式平均发送

    • 消费者处理完才会处理下条消息

    流程

    生产端:

    1、声明队列

    2、创建连接

    3、创建通道

    4、通道声明队列

    5、制定消息

    6、发送消息,使用默认交换机

    消费端:

    1、声明队列

    2、创建连接

    3、创建通道

    4、通道声明队列

    5、重写消息消费方法

    6、执行消息方法

    //给名字为spring_queue的队列发消息
    rabbitTemplate.convertAndSend("","spring_queue","hello eazyZhiLian");
    

    Pub/Sub订阅模式

    rb1

    模式说明

    P:生产者,发送消息给交换机

    C: 消费者,消息接收者,一直等待消息到来

    Quene: 消息队列,接收消息,缓存消息, 该模式中每个消费者监听自己的队列

    Exchange: 交换机(X),一方面,接受生产者发送的消息,另一方面,知道如何处理消息,例如递给某个特别的队列、递给所有队列、或是将消息丢弃。如何操作取决于Exchange的类型。

    常用类型有以下3种:

    Fanout:广播,将消息交给所有绑定到交换机上的队列

    当交换机为广播模式时,routingKey不需要

    Direct: 定向,交给符合指定routing key的队列

    Topic: 通配符,把消息交给符合routing pattern(路由模式)的队列 更加灵活 *代表一个单词,#号代表多个

    Fanout

    广播模式 绑定交换机的队列都收到消息

    Direct

    路由模式

    rb1

    • 队列与交换机的绑定,需要指定一个RoutingKey
    • 消息的发送放在向Exchagne发送消息时,也必须指定消息的RoutingKey
    • Exchange 不在把消息交给每一个绑定的队列,而是根据RoutingKey判断,只有队列的RoutingKey与消息的RoutingKey一致,才会收到消息。

    Topic

    通配符模式

    路由key中 #号代表多个单词 *号代表一个单词

    springboot整合

    1. 导入依赖

    2. yml配置mq信息

    3. 生产端声明队列和交换机,绑定关系,通过rabbitTemplate发送消息

    4. 消费端@RabbitListener(queues = "xxx")监听队列

      @Component
      public class RabbitMqListener {
          @RabbitListener(queues = "boot_queue")
          public void ListenerQueue(Message msg){
              System.out.println("取出消息: "+new String(msg.getBody()));
          }
      }
      

    高级特性

    消息可靠性投递确认Confirm

    消息发送方希望杜绝任何消息丢失或者投递失败的场景.rabbitmq有2中方式控制消息的投递可靠性模式

    整个消息的投递路径为

    producer-->rabbitmq broker --> exchange --> queue --> consumer

    • 消息从producer 到exchange会返回一个confirmCallback(无论投递成功与否 到了exchange,ack为true)
    • exchange到queue失投递败 则会返回执行returnCallback

    编码

    在发送消息前定义回调函数 (实现匿名内部类的方法), 消息发送后会执行这个方法

    消息发送是否成功会返回给boolean ack ,失败原因返回给cause correlationData是相关配置信息

    rb1

    消息可靠性投递回退Return

    发消息给Exchange,路由到Queue失败 才执行ReturnCallBack

    1. 默认是丢弃消息

    2. spring:
        rabbitmq:
          publisher-confirms: true #开启回退模式
      
    		@Autowired
        	private RabbitTemplate rabbitTemplate;
    {
            rabbitTemplate.setReturnCallback(new RabbitTemplate.ReturnCallback() {
                @Override
                public void returnedMessage(Message message, int i, String s, String s1, String s2) {
                    System.out.println(message+"投递到queue失败");
                }
            });
            rabbitTemplate.convertAndSend(RabbitMQConfig.Exchange_NAME, "boot.haha", "你好 boot mq");
    }
    
    1. 开启回退模式

    2. 设置ReturnCallBack

    3. 设置Exchange处理消息的模式

      1. 如果消息没有路由到Queue,则丢弃(默认)
      2. 如果消息没有路由到Queue,则返回给消息发送方ReturnCallBack

    Consumer Ack

    消费者收到消息的确认方式

    三种方式<rabbit:listener-container acknowledge="xxx"

    • 自动确认 acknowledge="none"
    • 手动确认 acknowledge="manual"
    • 根据异常情况确认 acknowledge="auto"

    其中自动确认是指,当消息一旦被Consumer接收到,则自动确认收到,并将相应message从RabbitMQ的消息缓存中移除。但是在实际业务处理中,很可能消息接收到,业务处理出现异常,那么该消息就会丢失。如果设置了手动确认方式,则需要在业务处理成功后,调用channel.basicAckO, 手动签收,如果出现异常,则
    调用channel.basicNack方法,设置requeue可让其自动重新发送消息。

    编码

    监听器实现ChannelAwareMessageListener

    重写onMessage方法

    如果消息处理成功,则调用channel的basicAck()签收

    处理失败,则调用channel的basicNack()拒收,braoker重新发送consumer

    消息可靠性总结

    1. 持久化
      1. exchange要持久化
      2. queue要持久化
      3. message要持久化
    2. 生产方确认Confirm
    3. 消费方确认Ack
    4. Broker高可用

    消费端限流

    1. 确保ack机制为手动确认 acknowledge="manual"
    2. rabbit:listener-container配置属性 prefetch="100"

    表示消费者每次从mq拉去100条消息,消费完毕(手动签收后)才继续拉去下100条

    TTL

    介绍

    • Time to Live 存活时间

    • 消息到达存活时间后,还未被消费,会自动清除

    • 可以对消息设置,也可以对整个队列设置过期时间

    编码

    2种方式

    第一种 对队列设置 1000 ms的TTL

    rb9

    第二种 对消息设置

    rb10

    如果都设置了,则优先按照短时间的TTL处理

    消息过期,只在队列顶端被判断过期(移除)

    死信队列

    当消息成为Dead message后 可以被重新发送到另一个交换机,这个交换机就是死信交换机

    消息成为死信的情况

    1. 队列消息长度达到限制
    2. 消费者拒绝接受消息 basicNack() 并且requeue=false不把消息重新放入原队列
    3. 原队列存在消息过期设置,消息超时未被消费

    声明2个正常队列和交换机 (其中一个作为死信队列) 并绑定

    正常队列如何绑定死信交换机?

    声明原队列时带上参数 x-dead-letter-exchange = exchange_dlx(交换机名)

    ​ x-dead-letter-routing-key = dlx.xxx(发送的路由key)

    延迟队列

    消息进入队列后不会立即消费 只有到达指定时间后,才会被消费

    利用TTL和死信队列实现,消费者监听死信队列

    日志和监控

    默认日志存放路径: /var/log/rabbitmq/rabbit@xxx.log

    消息追踪

    使用场景

    • 削峰限流
    • 异步处理
    • 应用解耦
    • 日志处理
    • 消息通讯(聊天)
  • 相关阅读:
    poj2352树状数组
    hdu1166树状数组
    poj2785双向搜索
    poj2566尺取变形
    poj2100还是尺取
    poj3061尺取法
    poj3320尺取法
    hdu3829最大独立集
    poj2594最小顶点覆盖+传递闭包
    经典换根dp——hdu2196
  • 原文地址:https://www.cnblogs.com/yc9064/p/15858277.html
Copyright © 2020-2023  润新知