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

消息追踪

使用场景

  • 削峰限流
  • 异步处理
  • 应用解耦
  • 日志处理
  • 消息通讯(聊天)
posted @ 2022-01-31 14:41  etherea|  阅读(122)  评论(0编辑  收藏  举报