RabbitMQ安装与springboot集成

RabbitMQ

1.安装RabbitMQ

在这里插入图片描述

rpm -Uvh *.rpm --nodeps --force

2.启动RabbitMQ

#任意路径执行
service rabbitmq-server start #启动mq
#启动成功 Starting rabbitmq-server (via systemctl):                  [  OK  ]
service rabbitmq-server stop #停止mq
service rabbitmq-server restart #重新启动mq
systemctl status rabbitmq-server#查看mq状态

3.启动可视化界面

#开启管理页面
rabbitmq-plugins enable rabbitmq_management
#出现Applying plugin configuration to rabbit@www... started 6 plugins.即启动成功
#修改默认配置信息
cp /usr/share/doc/rabbitmq-server-3.6.5/rabbitmq.config.example /etc/rabbitmq/rabbitmq.config

vi /etc/rabbitmq/rabbitmq.config
#将注释放开,并去掉后面的逗号

在这里插入图片描述

然后重启rabbitmq关闭防火墙,在页面输入ip和端口号(默认15672)即可进入登录页面,账号密码guest

(15672是管理页面的端口,mq的端口号是5672)
在这里插入图片描述

在这里插入图片描述

4.模型

1.第一种模型(一对一)

生产者—>队列—>消费者

#生产者发送消息
创建连接mq的连接工厂对象
设置连接rabbitmq主机 192.168.112.132
设置连接rabbitmq主机端口号 5672
设置连接rabbitmq的虚拟主机 /test
设置连接虚拟主机的用户名和密码 test 123
获取连接对象
获取连接中的通道
通道绑定对应消息队列 
	参数1:队列名称(自动创建)
    参数2:用于定义队列特性是否持久化(重启mq队列不丢失,消息丢失) fasle 不持久化(重启mq会丢失队列和消息)
	参数3:是否独占队列 false 当前队列不止当前通道可以使用 
	参数4:是否在消费完成后自动删除队列 false不自动删除
	参数5:附加参数 null
发布消息 虚拟机(直连没有虚拟机""),队列名称,发布消息额外设置(可以设置队列中的消息重启mq消息也不会消失),具体内容.geBytes()
 //获取连接对象
        Connection connection = connectionFactory.newConnection();
        //获取连接中的管道
        Channel channel = connection.createChannel();
        /*
        参数1:队列名称(自动创建)
        参数2:用于定义队列特性是否持久化(重启mq队列不丢失,消息丢失) fasle 不持久化(重启mq会丢失队列和消息)
        参数3:是否独占队列 false 当前队列不止当前通道可以使用
        参数4:是否在消费完成后自动删除队列 false不自动删除
        参数5:附加参数 null
        */
        channel.queueDeclare("hello",false,false,false,null);
        //发布消息
        Map<String,String> map = new HashMap<>();
        map.put("name","张三");
        map.put("age","15");
        String message = JSON.toJSONString(map);
        /*
        参数1:交换机(直连没有交换机"")
        参数2:队列名称
        参数3:发布消息额外设置(可以设置队列中的消息重启mq消息也不会消失)
        MessageProperties.PERSISTENT_TEXT_PLAIN代表持久化
        参数4:具体内容.geBytes()
        * */ 			     channel.basicPublish("","hello",MessageProperties.PERSISTENT_TEXT_PLAIN,message.getBytes());
        channel.close();
        connection.close();
#消费者消息
创建连接mq的连接工厂对象
设置连接rabbitmq主机 192.168.112.132
设置连接rabbitmq主机端口号 5672
设置连接rabbitmq的虚拟主机 /test
设置连接虚拟主机的用户名和密码 test 123
消费消息 队列名称,开启消息自动确认机制,消费时回调的接口
		ConnectionFactory connectionFactory =ConnectionUtil.getConnection();
        Connection connection = connectionFactory.newConnection();
        Channel channel = connection.createChannel();
        //每次消费只能消费一个消息
        channel.basicQos(1);
        channel.queueDeclare("hello",false,false,false,null);
        //消费信息
        /*
        参数1:消费那个队列的名称
        参数2:开启消息自动确认机制
        参数3:消费时的回调函数
        * */
        channel.basicConsume("hello",false,new DefaultConsumer(channel) {
            @Override
            public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                System.out.println("==============="+new String(body));
                 /**
                 * 参数1:确认队列中的具体的哪个消息
                 * 参数2:是否开启多个消息同时确认
                 */
                channel.basicAck(envelope.getDeliveryTag(),false);
                 System.out.println("===============消费完毕");
            }
        });

2.任务队列(一对多 轮询)

当消费处理比较耗时时,生产消息的速度大于消费的速度,造成消息越来越多,无法处理,让多个消费者同时消费一个队列

—>消费者

生产者—>队列 —>消费者

生产者不变 消费者代码复制两遍

消息确认机制

问题:在消费消息时,有一个参数设置为开启消息自动确认机制,当消息队列中有5条消息时,自动确认机制会将这5个消息全给一个消费者,然后删除队列中的数据,但当消费者宕机后还没有消费完的消息将会丢失

解决:将自动确认改为false,设置每次消费一个消息,并在消费后手动确认实现能者多劳

 //每次消费只能消费一个消息
 channel.basicQos(1);
 //消费自动确认机制为false
channel.basicConsume("hello",false,new DefaultConsumer(channel) {
    ...
    System.out.println("==============="+new String(body));
     /**
      * 参数1:确认队列中的具体的哪个消息
      * 参数2:是否开启多个消息同时确认
      */
    channel.basicAck(envelope.getDeliveryTag(),false);
    System.out.println("===============消费完毕");
}
3.发布(广播)fanout

—>(临时)队列—>消费者

生产者—>交换机—>(临时)队列—>消费者

应用场景:比如一个人注册之后会进行邮箱验证逻辑、给这个人加积分逻辑等等操作

生产者把消息给交换机,生产者无法决定发给哪个队列,交换机会把一个消息给多个队列,实现一条消息多个消费者消费实现不同的逻辑

生产者:创建管道,连接交换机,将消息给交换机

ConnectionFactory connectionFactory = ConnectionUtil.getConnection();
 //获取连接对象
 Connection connection = connectionFactory.newConnection();
 //获取连接中的管道
 Channel channel = connection.createChannel();
 /**
 * 管道声明交换机
 * 参数1:交换机名称
 * 参数2:交换机类型 fanout:广播类型
 */
 channel.exchangeDeclare("register","direct");
 //发布消息
 Map<String,String> map = new HashMap<>();
 map.put("name","张三");
 map.put("age","15");
 map.put("routingkey","error")
 String message = JSON.toJSONString(map);
 channel.basicPublish("register","","error",message.getBytes());
 channel.close();
 connection.close();

消费者:创建管道,绑定交换机,创建临时队列,队列绑定交换机,消费消息

 ConnectionFactory connectionFactory =ConnectionUtil.getConnection();
 Connection connection = connectionFactory.newConnection();
 Channel channel = connection.createChannel();
 //声明交换机
 channel.exchangeDeclare("register","fanout");
 //临时队列
 String queue = channel.queueDeclare().getQueue();
 //绑定交换机和队列
 channel.queueBind(queue,"register","error");
 //消费信息
 /*
 参数1:消费那个队列的名称
 参数2:开启消息自动确认机制
 参数3:消费时的回调函数
 * */
 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("==============="+new String(body));
            }
	});

4.路由
1.路由之订阅模型-direct(直连)

key->(临时)队列—>消费者1

生产者—>交换机–key->(临时)队列—>消费者2

在广播模式中,一条消息被所有订阅的都消费,我们希望不同的消息被不同的队列消费

生产者:交换机改为直连,向交换机发送消息时指定routingkey

channel.exchangeDeclare("register","direct");
channel.basicPublish("register","","error",message.getBytes());

消费者1:在交换机和队列绑定时需指定一个routingkey,接受error信息

消费者2:在交换机和队列绑定时需指定一个routingkey,接受warning,info信息

channel.exchangeDeclare("register","direct");
//绑定交换机和队列
 channel.queueBind(queue,"register","error");
channel.exchangeDeclare("register","direct");
//绑定交换机和队列
channel.queueBind(queue,"register","error");
channel.queueBind(queue,"register","info");
channel.queueBind(queue,"register","waring");
2.路由之订阅模型-topic

对于直连来说,topic对于routingkey可以使用通配符

*代表一个

#代表一个或者多个

5.springboot整合

1.搭建环境
1.1引入依赖
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-amqp</artifactId>
 </dependency>
2.配置配置文件
spring:
  rabbitmq:
    host: 192.168.112.132
    username: guest
    password: guest
    virtual-host: /test
    port: 5672

RabbitTemplate用于简化操作,使用时直接在项目中注入即可

2.实战
1.第一种模型
/**
* 生产者生产消息,此时不会直接创建队列,有消费者后才会创建
*/
@Slf4j
@SpringBootTest
public class TestRabbitMQ {
    @Autowired
    RabbitTemplate rabbitTemplate;

    @Test
    @DisplayName("测试hello word")
    public void test(){
        //参数1:队列名称 参数2:消息实体
        rabbitTemplate.convertAndSend("hello","hello world");
    }
}

/**
* 消费者消费消息
*/
@Component
//默认是持久化,非独占,不是自动删除的
@RabbitListener(queuesToDeclare = @Queue(value = "hello",durable = "true",autoDelete = "false"))
public class HelloConsumer {
    @RabbitHandler
    public void receive(String message){
        System.out.println("message===="+message);
    }
}
2.任务队列轮询
//生产者
@Test
@DisplayName("测试任务队列")
public void testWork(){
	for (int i=0;i<10;i++){
		rabbitTemplate.convertAndSend("work","work模型"+i);
	}
}
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
*消费者
*/
@Component
public class WorkConsumer {
    @RabbitListener(queuesToDeclare = @Queue(value = "work"))
    public void receive1(String message){
        System.out.println("message1===="+message);
    }

    @RabbitListener(queuesToDeclare = @Queue(value = "work"))
    public void receive2(String message){
        System.out.println("message2===="+message);
    }

}

这种默认轮询机制,要实现能者多劳要另外配置

3.发布广播
//生产者
 @Test
    @DisplayName("测试广播形式fanout")
    public void testFanout(){
        //参数1: 交换机,参数2:路由key 参数3:消息实体
        rabbitTemplate.convertAndSend("logs","","Fanout模型");
    }

import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
/**
*消费者
*/
@Component
public class FountConsumer {
    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue,//创建临时队列
                    exchange =@Exchange(value = "logs",type="fanout")//绑定的交换机
            )
    })
    public void receive1(String message){
        System.out.println("message1===="+message);
    }

    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue,//创建临时队列
                    exchange =@Exchange(value = "logs",type="fanout")//绑定的交换机
            )
    })
    public void receive2(String message){
        System.out.println("message2===="+message);
    }
}
4.路由
4.1 直连
//生产者
@Test
@DisplayName("测试路由形式direct")
public void testDirect(){
	//参数1: 交换机,参数2:路由key 参数3:消息实体
	rabbitTemplate.convertAndSend("directs","info","direct模型发送的info类型的信息");
}
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

/**
 * direct消费者
 */
@Component
public class DirectConsumer {
    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue,//创建临时队列
                    exchange =@Exchange(value = "directs",type="direct"),//绑定的交换机
                    key={"info","error","warn"}//路由的key
            )
    })
    public void receive1(String message){
        System.out.println("message1===="+message);
    }

    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue,//创建临时队列
                    exchange =@Exchange(value = "directs",type="direct"),//绑定的交换机
                    key={"error"}//路由的key
            )
    })
    public void receive2(String message){
        System.out.println("message2===="+message);
    }

}
4.2topic
//生产者
 @Test
    @DisplayName("测试路由形式topic")
    public void testTopics(){
        //参数1: 交换机,参数2:路由key 参数3:消息实体
        rabbitTemplate.convertAndSend("topics","user.save","topic模型发送的user.save的信息");
    }
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

/**
 * topic消费者
 */
@Component
public class TopicConsumer {
    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue,//创建临时队列
                    exchange =@Exchange(value = "topics",type="topic"),//绑定的交换机
                    key={"usr.save","user.*"}//路由的key
            )
    })
    public void receive1(String message){
        System.out.println("message1===="+message);
    }

    @RabbitListener(bindings = {
            @QueueBinding(
                    value = @Queue,//创建临时队列
                    exchange =@Exchange(value = "topics",type="topic"),//绑定的交换机
                    key={"order.#","user.*"}//路由的key
            )
    })
    public void receive2(String message){
        System.out.println("message2===="+message);
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot集成RabbitMQ可以通过以下步骤完成: 1. 添加Maven依赖:在pom.xml文件中添加RabbitMQSpring Boot Starter依赖。 ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> ``` 2. 配置RabbitMQ连接信息:在application.properties(或application.yml)文件中配置RabbitMQ的连接信息。 ```properties spring.rabbitmq.host=your_rabbitmq_host spring.rabbitmq.port=your_rabbitmq_port spring.rabbitmq.username=your_rabbitmq_username spring.rabbitmq.password=your_rabbitmq_password ``` 3. 创建RabbitMQ发送者:创建一个发送消息的类,使用`RabbitTemplate`发送消息到指定的交换机和队列。 ```java import org.springframework.amqp.core.RabbitTemplate; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class RabbitMQSender { @Autowired private RabbitTemplate rabbitTemplate; public void sendMessage(String exchange, String routingKey, Object message) { rabbitTemplate.convertAndSend(exchange, routingKey, message); } } ``` 4. 创建RabbitMQ接收者:创建一个接收消息的类,使用`@RabbitListener`注解监听指定的队列,处理接收到的消息。 ```java import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.stereotype.Component; @Component public class RabbitMQReceiver { @RabbitListener(queues = "your_queue_name") public void receiveMessage(Object message) { // 处理接收到的消息 System.out.println("Received message: " + message.toString()); } } ``` 5. 发送和接收消息:在需要发送或接收消息的地方调用对应的方法。 ```java @Autowired private RabbitMQSender rabbitMQSender; public void sendMessage() { rabbitMQSender.sendMessage("your_exchange_name", "your_routing_key", "Hello, RabbitMQ!"); } ``` 以上是基本的使用方式,你可以根据实际需求进行扩展和配置。注意,你还需要安装并启动RabbitMQ服务。 希望对你有所帮助!如果有任何疑问,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值