RabbitMQ学习和知识点简单归纳

541 阅读5分钟

RabbitMQ

rabbitmq服务默认端口 5672 web管理页面15672 支持持久化 消息不会丢失
AMQP协议

在tcp/ip、http的基础上产生的一种高级消息队列协议,http的请求头和响应头过于复杂,大部分都是短链接,所以产生一个通道保持一个长连接,提高性能,所以mq产生自己的协议

角色
  • none:无法访问web页面
  • managment:只能看到自己的相关信息无法看别人的,无法创建修改自己的queue、exchange等
  • policymaker:和management一样能看自己的相关信息,还能创建修改自己的queue、exchange等
  • monitoring:能看所有人的相关信息
  • adminstrator:能看所有人的并且能修改新增删除,就是拥有所有的操作功能
核心概念
  • serve:就是我们的rabbitMQ服务器
  • connction:连接,tcp/ip 进行网络连接
  • channel:连接建立后,创建通道,进行消息的读写
  • message:通道中传递的消息
  • virtual host:虚拟主机,“/”,“/hello”,类似于mysql中一个个数据库,一个虚拟主机中可以有多个交换机、队列
  • exchange:交换机(路由),接收通道传递过来的消息
  • bindings:交换机和消息队列之间建立连接,可以保护多个routing key
  • routing key:路由规则,可以用它来确定如何路由一个特定消息,主要用于寻找队列
  • queue:消息队列,保存消息的载体
消息分发策略的机制

支持发布订阅、轮询分发、公平分发、重发、消息拉取

假如mq中有100条消息,有三个消费者,不同的分发机制有不同分发方式,如下

  • 发布订阅:每个消费者都会获取100条消息
  • 轮询分发:每个消费者各获取33条,留下一条分给其中一个消费者
  • 公平分发:那个消费者消费的快那个就多发一些,能者多劳,必须要手动的应答
  • 重发:假如一条消息被某个消费者消费后,并没有给mq回复确认消费信息,那么该消息不会删除并向另两个的其中一个发送消息
  • 消息拉取:rpc的形式,被动拉取的一种机制,基本不会用
6种工作模式 对路由的设定
  • simple简单队列模式 默认队列 拥有一个默认交换机

屏幕截图 2021-03-14 020655.png

生产者
package com.lly.mq.first;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class Customer {
    public static void main(String[] args) throws IOException, TimeoutException {
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("127.0.0.1");
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");
        connectionFactory.setVirtualHost("/");
        Connection connection = connectionFactory.newConnection("生产者");
        //创建队列
        Channel channel = connection.createChannel();
        //声明队列  五个参数分别为 1.队列名称  2.是否持久化(false:非持久化)  3.排他性  4.队列是否自动删除(消息被消费完时)  5.携带附属参数
        channel.queueDeclare("hello",false,false,false,null);
        //发送消息   四个参数  1.交换机名称(没有指定,使用默认的) 2.队列名称
        channel.basicPublish("","hello",null,"Hello RabbitMQ!".getBytes());
        System.out.println("消息发送成功!");
        channel.close();
        connection.close();
    }
}

消费者
package com.lly.mq.first;

import com.rabbitmq.client.*;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class Producter {
    public static void main(String[] args) throws IOException, TimeoutException {
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("127.0.0.1");
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");
        connectionFactory.setVirtualHost("/");
        Connection connection = connectionFactory.newConnection("消费者");
        //创建队列
        Channel channel = connection.createChannel();
        channel.queueDeclare("hello",false,false,false,null);
        channel.basicConsume("hello", true, new DeliverCallback() {
            @Override
            public void handle(String s, Delivery delivery) throws IOException {
                System.out.println("接收到消息是:" + new String(delivery.getBody(), "UTF-8"));
            }
        }, new CancelCallback() {
            @Override
            public void handle(String s) throws IOException {
                System.out.println("接收到消息失败" );
            }
        });
        System.in.read();
        channel.close();
        connection.close();
    }
}

  • work工作队列模式 拥有一个默认交换机

屏幕截图 2021-03-14 050209.png

  • fanout发布订阅模式

屏幕截图 2021-03-14 035305.png 将多个队列和交换机绑定,当交换机接收到一条消息后,会分别分发到多个已绑定的队列中,每个队列都接受到这条消息。比如注册时,需要发短信、发邮件、添加数据库,可以使用这个这种模式进行一个异步的操作 例:如下是对fanout的模拟 1.创建消息队列fanout1、fanout2,各自有一条数据

3.png 2.创建一个fanout路由,名称fanout-exchange,并分别为两个队列绑定,注意并没有绑定routing key。

1.png

3.发送一个内容为message的消息,可见fanout1、fanout2数据由1变为2了

2.png

4.png

  • Direct路由模式

屏幕截图 2021-03-14 040734.png

将多个队列和交换机绑定,并将绑定设置一个routing key,当交换机接收到一条向指定routing key消息后,拥有相关绑定routing key的队列将收到一条消息,是一种精准的匹配,具体示例参考topics主题模式配图,Direct模式下routing key不带由#和*

  • topics主题模式

屏幕截图 2021-03-14 040253.png

topics和Direct基本相同,topics是一种模糊匹配 例:如下是对topic的模拟

1.首先创建4个队列 queue1 queue2 queue3 queue4,如下图:

1.png

2.创建一个topic路由,名称topic-exchange,并分别为四个队列绑定routing key,#和*表示模糊匹配,#表示0个或多个,*表示有且只有一个

2.png

3.当向routing key为xxx.com.xxx发送消息时,只有queue1收到了消息,可见queue1消息由2变为了3

8.png

3.png

4.当向routing key为com.user.xxx发送消息时 ,queue1和queue4会收到消息,queue1消息由3变为4,queue4消息由0变为1

4.png

5.png

5.当向routing key为xxx.course.xxx.xxx发送消息时,可见提示没有相对应的路由,queue2消息还是为1不变

6.png

总结:simple、work模式可以理解为就是fanout模式,simple和work是使用默认的路由,而fanout需要我们自己创建。而direct和topics也很相似,direct是一种对routing key的精准匹配,而topics是一种模糊匹配。