RabbitMQ

RabbitMQ总结:

1、RabbitMQ的 http访问端口:15672 项目访问端口:5672
2、AMQ协议:
	生产者、消费者、虚拟主机、交换机、队列
	过程:
		生产者与消费者都要绑定同一个虚拟主机账户
		生产者生产消息,通过channel 将消息放到绑定的交换机或者quene队列中
		消费者通过通道绑定与生产者相同的交换机或者队列,==实现监听==,一旦有消息进入,会从交换机或者队列中取出消息消费
3、RabbitMQ参数:
	队列相关:队列持久化,通道独占队列,是否自动删除
	消息相关:消息自动确认,消息的消费条数
4、RabbitMQ的五种消息模式
	直连模式
	工作模式:能者多劳:关闭消息自动确认,消息每次消费条数设置为1
	广播模式:所有消费者同时拿到消息消费
	路由模式:与消息中的路由信息相同的消费者才能拿到消息
	订阅模式:引入通配符,消息的路由信息符合消费者通配符规则的消费者消费消息
5、RabbitMQ的应用场景:
	异步处理:登陆发送手机验证码、邮箱验证等
	解耦:订单系统、库存系统之间
	流量削峰:秒杀=设置消息存储上限,超过消息上限的消息都回丢失,存储的消息即为秒杀成功的用户
6、RabbitMQ集群
	普通集群:(主从关系)
		主节点提供服务,从节点只是备份作用
		主节点宕机之后,集群不可用
		主节点宕机时的队列会同步到从节点
		如果主节点队列中的消息持久化了,那么主节点恢复之后,会与从节点同步队列,并将持久化的消息放入队列中
	镜像集群:
		可以将集群中的多个节点设置为镜像
		设置为镜像的节点可以提供消息服务
		未设置镜像的节点还是备份节点

MQ消息队列

MQ产品:
activeMQ:信息吞吐量小,老牌消息队列,中小企业使用
Kafka:只追求性能,对于事物和数据的一致性几乎没有
RocketMQ:开源版本也是不支持事务,付费版支持
RabbitMQ:对数据的一致性、稳定性、和可靠性都是最好的

RabbitMQ

安装RabbitMQ

安装:
1、rabbitMQ是基于erLang语言开发的,首先安装erLang依赖包

rpm -ivh erlang-22.0.7-1.el7.x86_64.rpm

2、安装erLang内存管理的依赖

rpm -ivh socat-1.7.3.2-2.el7.x86_64.rpm 

3、安装rabbitMQ

rpm -ivh rabbitmq-server-3.7.18-1.el7.noarch.rpm 

4、配置rabbitMQ的配置文件
在etc/rabbitmq/下应该有一个rabbitmq.config的配置文件

find / -name rabbitmq.config.example

找到这个文件,将这个文件复制到etc/rabbitmq/下,命名为rabbitmq.config
修改这个文件
:set nu 显示行号
修改第61行,将注释去掉,并且去掉后面的逗号
在这里插入图片描述
允许来并用户在网络上访问
5、启动rabbitmq中的插件管理

rabbitmq-plugins enable rabbitmq_management

6、启动rabbitmq

rabbitmq-plugins enable rabbitmq_management
ystemctl start rabbitmq-server

注:如果你的主机名是数字,那么启动会报错,将主机名修改成英文主机名即可
临时修改主机名

hostname newHostname  

7、访问web管理页面

如果访问不到需要关闭linux的防火墙

如果提示:User can only log in via localhost
解决方案:

找到这个文件rabbit.app
C:\Program Files\RabbitMQ Server\rabbitmq_server-3.7.13\ebin\rabbit.app
 
将第39行:{loopback_users, [<<”guest”>>]},
改为:{loopback_users, []},
然后重启服务
原因:rabbitmq从3.3.0开始禁止使用guest/guest权限通过除localhost外的访问

默认端口15672
在这里插入图片描述
在这里插入图片描述
RabbitMQ管理命令行

#1、服务启动相关
systemctl start|restart|stop|status rabbitmq-server
#2、管理命令行 用来在不使用web管理页面情况下操作RabbitMQ
rabbitmqctl help
#3、插件管理命令行
rabbitmq-plugins enable|list|disable
rabbitmq-plugins enable rabbitmq-management   启动web管理页面插件
rabbitmq-plugins list 插件列表

AMQ协议在这里插入图片描述
1、生产者通过通道将消息放到虚拟主机中Virtual Host,虚拟主机将相当于一个数据库,每一个生产者都要有一个自己的虚拟主机,这样多个应用之间可以做到互不影响。
2、访问虚拟主机,需要将用户与虚拟主机绑定,默认的来宾账户guest可以访问所有的虚拟主机
3、消息可以放到交换机中,根据不同的规则,分配到不同的队列中;有的模式不需要使用交换机

RabbitMQ的应用

1、新建项目
在这里插入图片描述

2、导入依赖

		<dependency>
            <groupId>com.rabbitmq</groupId>
            <artifactId>amqp-client</artifactId>
            <version>5.7.2</version>
        </dependency>
第一种模式:直连模式

在这里插入图片描述
生产者

public class Provider {
    //生产消息
    @Test
    public void testSendMessage() throws IOException, TimeoutException {
        //创建mq的连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        //设置连接rabbitmq主机
        connectionFactory.setHost("192.168.168.132");
        //设置端口号
        connectionFactory.setPort(5672);
        //设置连接哪个虚拟主机
        connectionFactory.setVirtualHost("/ems");
        //设置访问虚拟主机的用户名密码
        connectionFactory.setUsername("ems");
        connectionFactory.setPassword("123");
        //获取连接对象
        Connection connection = connectionFactory.newConnection();
        //通过连接中的通道
        Channel channel = connection.createChannel();
        //通道绑定对应的消息队列
        //参数1:队列名称,如果不存在,自动创建
        //参数2:用来定义队列是否要持久化 true持久化,false 不持久化
        //参数3:exclusive 是否独占队列 true独占队列 false不独占 允许其他通道绑定队列
        //参数4:autoDelete 是否在消费完成后自动删除队列, true  删除  false 不删除
        //参数5:额外的附加参数
        channel.queueDeclare("hello", false, false, false, null);

        //发布消息
        //参数1:交换机名称 参数2:队列名称 参数3:传递消息额外设置 参数4:消息的具体内容
        channel.basicPublish("", "hello", null, "hello rabbitmq".getBytes());

        channel.close();
        connection.close();
    }
}

消费者

public class Consumer {
    //消费消息
    public static void main(String[] args) throws IOException, TimeoutException {

        //创建mq的连接工厂
        ConnectionFactory connectionFactory = new ConnectionFactory();
        //设置连接rabbitmq主机
        connectionFactory.setHost("192.168.168.132");
        //设置端口号
        connectionFactory.setPort(5672);
        //设置连接哪个虚拟主机
        connectionFactory.setVirtualHost("/ems");
        //设置访问虚拟主机的用户名密码
        connectionFactory.setUsername("ems");
        connectionFactory.setPassword("123");
        //获取连接对象
        Connection connection = connectionFactory.newConnection();
        //通过连接中的通道
        Channel channel = connection.createChannel();
        //通道绑定对应的消息队列
        //参数1:队列名称,如果不存在,自动创建
        //参数2:用来定义队列是否要持久化 true持久化,false 不持久化
        //参数3:exclusive 是否独占队列 true独占队列 false不独占 允许其他通道绑定队列
        //参数4:autoDelete 是否在消费完成后自动删除队列, true  删除  false 不删除
        //参数5:额外的附加参数
        channel.queueDeclare("hello", false, false, false, null);
        //消费消息
        //参数1:消费哪个队列的消息
        //参数2:开始消息的自动确认机制
        //参数3:消费时的回调接口
        channel.basicConsume("hello", true, new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println(body);
            }
        });

        //因为consumer是需要一直对队列进行监听的,所以不建议关闭通道和连接
        // 只要生产者在队列中放进去一条消息,消费者就会立马进行消费
    }
}

因为生产者和消费者都需要获取连接,这样产生了大量的代码冗余,我们可以将代码提炼出来,封装成一个工具类

public class RabbitMQUtils {
    //工厂在项目加载时只创建一次
    private static ConnectionFactory connectionFactory;
    static {
        connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("192.168.168.132");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/ems");
        connectionFactory.setUsername("ems");
        connectionFactory.setPassword("123");
    }

    public static Connection getConnection() {
        try {
            return connectionFactory.newConnection();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (TimeoutException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void closeConnection(Channel channel, Connection connection) {
        try {
            if (channel != null) {
                channel.close();
            }
            if (connection != null) {
                connection.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (TimeoutException e) {
            e.printStackTrace();
        }
    }
}

RabbitMQ的API参数细节
通道绑定队列,通道可以绑定多个队列,单不一定会往队列里发送消息

   channel.queueDeclare("hello", false, false, false, null);

通道发布消息到队列,通过此方法通道将消息发布到对应的队列中

 channel.basicPublish("", "hello", null, "hello rabbitmq".getBytes());

队列的持久化

channel.queueDeclare("hello", true, false, false, null);
队列中消息持久化设置为true时,即使重启rabbitmq服务,队列也能保留,但是如果队列中发布的消息没有持久化,则重启之后队列中的消息会小时

发布消息的持久化

 channel.basicPublish("", "hello", MessageProperties.PERSISTENT_TEXT_PLAIN, "hello rabbitmq".getBytes());
MessageProperties.PERSISTENT_TEXT_PLAIN 就可以将消息持久化
		//通道绑定对应的消息队列
        //参数1:队列名称,如果不存在,自动创建
        //参数2:用来定义队列是否要持久化 true持久化,false 不持久化
        //参数3:exclusive 是否独占队列 true独占队列 false不独占 允许其他通道绑定队列
        //参数4:autoDelete 是否在消费完成后自动删除队列, true  删除  false 不删除  消费者会一直监听这个队列,只有当消费者关掉服务的时候,队列才会自动删除
        //参数5:额外的附加参数
        channel.queueDeclare("hello", false, false, false, null);
第二种模式:工作队列模式

在这里插入图片描述
生产者

public class Provider {
    public static void main(String[] args) throws IOException {
        //获取连接
        Connection connection = RabbitMQUtils.getConnection();
        //获取通道
        Channel channel = connection.createChannel();
        //绑定队列
        channel.queueDeclare("work",true,false,false,null);
        //发布队列消息
        for (int i = 1; i <= 10; i++) {
            channel.basicPublish("","work",null,(i+"hello work  quene").getBytes());
        }
        //关闭连接
        RabbitMQUtils.closeConnection(channel,connection);
    }
}

消费者-1

public class Consumer1 {
    public static void main(String[] args) throws IOException {
        //获取连接
        Connection connection = RabbitMQUtils.getConnection();
        //获取通道
        final Channel channel = connection.createChannel();
        channel.basicQos(1);//每次消费一个队列中的消息
        //绑定队列
        channel.queueDeclare("work",true,false,false,null);
        //消费队列消息
        //参数1:队列名称 参数2:消息自动确认   消费者向rabbitmq自动确认消息消费,不管消费者有没有消费完,队列都将删除确认过消费的消息
        channel.basicConsume("work",false,new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("消费者-1:"+new String(body));
                //手动确认 参数1:手动确认消息标识  参数2:false 每次确认一个
                channel.basicAck(envelope.getDeliveryTag(),false);
            }
        });
    }
}

消费者-2

public class Consumer2 {
    public static void main(String[] args) throws IOException {
        //获取连接
        Connection connection = RabbitMQUtils.getConnection();
        //获取通道
        final Channel channel = connection.createChannel();
        channel.basicQos(1);
        //绑定队列
        channel.queueDeclare("work",true,false,false,null);
        //消费队列消息
        channel.basicConsume("work",false,new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("消费者-2:"+new String(body));
                channel.basicAck(envelope.getDeliveryTag(),false);
            }
        });
    }
}
对于消费者1 和消费者2,队列默认是平均配分消息的
这样就会出现一种情况:
如果消费者1消费比较慢,那么消费者2消费完消息之后,消费者1还在慢慢的消费分配给他的消息
这样就可能造成消费者1的服务崩掉或者消费者2服务的浪费

在这里插入图片描述
在这里插入图片描述
实现能者多劳:
消息的自动确认机制

//消费消息
channel.basicConsume("work",true,new DefaultConsumer(channel))
当第二个参数为true时,消息的确认机制为 自动确认,消费者自动向rabbitmq确认消息消费,不管有没有消费完,
队列都会将已经确认消费的消息删除调,这样就会产生一个问题:如果消费能力弱的消费者,在消费一半信息的
时候突然宕机,那么剩下一般的消息,就会丢失。这是我们不允许的;

解决上述问题
1、关闭消息自动 确认机制

channel.basicConsume("work",false,new DefaultConsumer(channel))

2、告诉消息队列在消费消息时,不能一次性的把所有消息都分配给消费者,要一个个的消费

  channel.basicQos(1);//每次消费一个队列中的消息
第三种模式:广播模式 fanout

在这里插入图片描述
例如购物车结算的时候要调用库存系统和订单系统 ,就可以用到订阅模式
生产者

public class Provider {
    public static void main(String[] args) throws IOException {
        //获取连接对象
        Connection connection = RabbitMQUtils.getConnection();
        //获取通道
        Channel channel = connection.createChannel();
        //将通道声明指定的交换机,没有则创建新的交换机 参数1:交换机名称 参数2:交换机类型
        channel.exchangeDeclare("logs", "fanout");
        //发布消息
        channel.basicPublish("logs", "", null, "fanout : message".getBytes());
        //关闭资源
        RabbitMQUtils.closeConnection(channel, connection);
    }
}

消费者1、2、3

public class Consumer1 {
    public static void main(String[] args) throws IOException {
        //获取连接对象
        Connection connection = RabbitMQUtils.getConnection();
        Channel channel = connection.createChannel();
        //通道绑定交换机
        channel.exchangeDeclare("logs","fanout");
        //临时队列
        String queue = channel.queueDeclare().getQueue();
        //绑定交换机和队列
        channel.queueBind(queue,"logs","");
        //消费
        channel.basicConsume(queue,true,new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("消费者1:"+new String(body));
            }
        });
    }
}
第四种模式:路由模式(direct)在这里插入图片描述

生产者

public class Provider {
    public static void main(String[] args) throws IOException {
        //获取连接对象
        Connection connection = RabbitMQUtils.getConnection();
        //获取通道
        Channel channel = connection.createChannel();
        //绑定交换机,指定交换机类型为路由模式 参数1:交换机名称 参数2:交换机类型:路由模式
        channel.exchangeDeclare("logs_direct","direct");
        //声明路由名称
        String routingKey="info";
        //消费 参数2:指定消息发布的路由名称
        channel.basicPublish("logs_direct",routingKey,null,("这是direct模型发布的基于Routing key为["+routingKey+"]").getBytes());
        //关闭资源
        RabbitMQUtils.closeConnection(channel,connection);
    }
}

消费者1

public class Consumer1 {
    public static void main(String[] args) throws IOException {
        //获取连接对象
        Connection connection = RabbitMQUtils.getConnection();
        //获取通道
        Channel channel = connection.createChannel();
        //绑定交换机,指定交换机类型为路由模式 参数1:交换机名称 参数2:交换机类型:路由模式
        channel.exchangeDeclare("logs_direct","direct");
        //临时队列
        String queue = channel.queueDeclare().getQueue();
        //临时队列和交换机绑定 可以绑定多个
        channel.queueBind(queue,"logs_direct","error");
        channel.queueBind(queue,"log_direct","info");
        channel.queueBind(queue,"log_direct","warning");

        channel.basicConsume(queue,true,new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("消费者1:"+new String(body));
            }
        });
    }
}

消费者2

public class Consumer2 {
    public static void main(String[] args) throws IOException {
        //获取连接对象
        Connection connection = RabbitMQUtils.getConnection();
        //获取通道
        Channel channel = connection.createChannel();
        //绑定交换机,指定交换机类型为路由模式 参数1:交换机名称 参数2:交换机类型:路由模式
        channel.exchangeDeclare("logs_direct","direct");
        //临时队列
        String queue = channel.queueDeclare().getQueue();
        //绑定队列和交换机绑定
        channel.queueBind(queue,"logs_direct","error");
        channel.basicConsume(queue,true,new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("消费者2:"+new String(body));
            }
        });
    }
}
第五种模式:订阅模式(动态路由)topics

在这里插入图片描述
生产者

public class Provider {
    public static void main(String[] args) throws IOException {
        //获取连接对象
        Connection connection = RabbitMQUtils.getConnection();
        //获取通道
        Channel channel = connection.createChannel();
        //绑定交换机,指定交换机类型为路由模式 参数1:交换机名称 参数2:交换机类型:动态路由模式
        channel.exchangeDeclare("topics", "topic");
        //声明路由名称
        String routingKey = "user.save.result";
        //消费 参数2:指定消息发布的路由名称
        channel.basicPublish("topics", routingKey,null,("这里是topic动态路由模型,routingkey:["+routingKey+"]").getBytes());
        //关闭资源
        RabbitMQUtils.closeConnection(channel,connection);
    }
}

消费者

public class Consumer1 {
    public static void main(String[] args) throws IOException {
        //获取连接对象
        Connection connection = RabbitMQUtils.getConnection();
        //获取通道
        Channel channel = connection.createChannel();
        //绑定交换机,指定交换机类型为路由模式 参数1:交换机名称 参数2:交换机类型:路由模式
        channel.exchangeDeclare("topics","topic");
        //临时队列
        String queue = channel.queueDeclare().getQueue();
        //临时队列和交换机绑定 动态通配符形式绑定
        channel.queueBind(queue,"topics","user.*");//*代表一个单词
        channel.queueBind(queue,"topics","user.#");//#代表多个单词

        channel.basicConsume(queue,true,new DefaultConsumer(channel){
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("消费者1:"+new String(body));
            }
        });
    }
}

Springboot整合RabbitMQ

Springboot自带整合RabbitMQ
新建项目时,选择message下的springboot RabbitMQ的依赖即可

		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>
     	 <!--springboot自带rabbit的测试依赖-->
         <dependency>
            <groupId>org.springframework.amqp</groupId>
            <artifactId>spring-rabbit-test</artifactId>
            <scope>test</scope>
        </dependency>

配置RabbitMQ地址:

spring:
  rabbitmq:
  	host: 192.168.168.132
    port: 5672
    username: ems
    password: 123
    virtual-host: /ems    

1、直连模式

生产者

 //直连模式
    @RequestMapping("/hello")
    public String hello() {
        rabbitTemplate.convertAndSend("hello", "hello,world");
        return "success";
    }

消费者

@Component
//默认持久化的、非独占的、不是自动删除的队列
//@RabbitListener(queuesToDeclare = @Queue(value = "hello",durable = "true",autoDelete = "true"))
@RabbitListener(queuesToDeclare = @Queue("hello"))
public class HelloCustomer {

    @RabbitHandler//标注这个方法是拿到消息之后的回调函数
    public void callBack(String message) {
        System.out.println("message:" + message);
    }
}

2、工作模式

生产者

//工作模式
    @RequestMapping("/work")
    public String work() {
        for (int i = 0; i < 10; i++) {
            rabbitTemplate.convertAndSend("work", "work模式:" + i);
        }
        return "success";
    }

消费者

@Component
public class WorkConsumer {
    //标注监听,代表开启监听,并且标识这个方法为这个队列的消息回调函数
    @RabbitListener(queuesToDeclare = @Queue("work"))
    public void consumer1(String message){
        System.out.println("消费者1:"+message);
    }
    @RabbitListener(queuesToDeclare = @Queue("work"))
    public void consumer2(String message){
        System.out.println("消费者2:"+message);
    }
}

3、广播模式

生产者

//广播模式
    @RequestMapping("/fanout")
    public String fanout() {
        rabbitTemplate.convertAndSend("logs", "", "fanout模式:");
        return "success";
    }

消费者

@Component
public class FanoutConsumer {

    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue,//不指定名称即创建临时队列
                    exchange = @Exchange(value = "logs",type = "fanout")//参数1:交换机名称 参数2:交换机类型
            )
    })
    public void consumer1(String message){
        System.out.println("消费者1:"+message);
    }

    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue,//不指定名称即创建临时队列
                    exchange = @Exchange(value = "logs",type = "fanout")//参数1:交换机名称 参数2:交换机类型
            )
    })
    public void consumer2(String message){
        System.out.println("消费者2:"+message);
    }
}

4、路由模式

生产者

 //路由模式
    @RequestMapping("/direct")
    public String direct() {
        //参数1:交换机名称,参数2:路由名称 参数3:消息内容
        rabbitTemplate.convertAndSend("direct", "info", "路由为info的direct模式:");
        return "success";
    }

消费者

@Component
public class DirectConsumer {
    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue,
                    exchange = @Exchange(value = "direct", type = "direct"),
                    key = {"error"}
            )
    })
    public void consumer1(String message) {
        System.out.println("消费者1:"+message);
    }

    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue,
                    exchange = @Exchange(value = "direct", type = "direct"),
                    key = {"info","error","warning"}
            )
    })
    public void consumer2(String message) {
        System.out.println("消费者2:"+message);
    }
}

5、订阅模式

生产者

//订阅模式
    @RequestMapping("/topic")
    public String topic() {
        //参数1:交换机名称,参数2:路由名称 参数3:消息内容
        rabbitTemplate.convertAndSend("topic", "user.order.result", "路由为info的direct模式:");
        return "success";
    }

消费者

@Component
public class TopicConsumer {
    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue,
                    exchange = @Exchange(value = "topic",type = "topic"),
                    key ={"user.#"}
            )
    })
    public void consumer1(String message){
        System.out.println("消费者1:"+message);
    }
    
    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue,
                    exchange = @Exchange(value = "topic",type = "topic"),
                    key ={"user.*"}
            )
    })
    public void consumer2(String message){
        System.out.println("消费者2:"+message);
    }
}

RabbitMQ的应用场景
1、异步处理
在这里插入图片描述
2、应用解耦
在这里插入图片描述
3、流量削峰
在这里插入图片描述

RabblitMQ的集群

1、普通集群(副本集群)

架构图
在这里插入图片描述

核心解决问题:当集群中的master宕机,MQ集群不可用,但可以对Queue中的信息进行备份,不至于丢失
1、主节点上的队列也会同步到从节点上,但是主节点上队列的消息,不会同步到从节点,队列中的消息,建议持久化
2、主节点不宕机的情况下,消费者也可以连接从节点去消费消息,从节点消费的消息也是从主节点中拿过来的,消费之后,主节点中的消息也会同步消失

搭建集群

  • 准备一台虚拟机服务器,安装好RabbitMQ安装文件,克隆两台服务器
  • 要保证三台服务器的erLang.cookie文件一致,才能搭建集群 文件位置在 /var/lib/rabbitmq/.erlang.cookie
  • 启动三台RabbitMQ服务
  • 查看集群状态
    rabbitmqctl cluster_status
  • 加入集群
    rabbitmqctl join_cluster rabbit@192.168.168.132
  • 启动MQ
    rabbitmqctl start_app
    在这里插入图片描述

2、镜像集群(重点常用)

架构图
在这里插入图片描述

镜像队列就是将队列在三个节点之间设置主从关系,消息会在三个节点之间进行自动同步,如果其中一个节点不可用,并不会导致消息丢失,
或者服务不可用的情况,提升MQ集群整体的高可用性

策略说明:
rabbi
镜像模式是在普通集群的基础上,设置一下策略即可成为镜像集群,多个节点都可以同时提供服务
策略:
1、查看策略
rabbitmqctl list_policies
2、设置策略
rabbitmqctl set_policy ha-all '^hello' '{"ha-mode":"all","ha-sync-mode":"automatic"}'
说明:设置策略名为“ha-all”,匹配所有队列名称以“hello”开头的队列,镜像参数:镜像队列模式为:“all”,镜像同步方式为:“automatic”

设置策略之后在这里插入图片描述
说明:因为设置的策略是“all”,所有的节点都设置镜像,都对外提供服务
3、删除策略
rabbitmqctl clear_policy 策略名称

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值