RabbitMQ详细讲解

RabbitMQ概述

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

JMS

在这里插入图片描述

RabbitMQ快速入门

创建SpringBoot工程,勾选web,RabbitMQ
在这里插入图片描述

先配置yaml文件

spring:
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: guest
    password: guest

创建包config
创建一个公共配置类,定义一些配置信息

@Configuration
public class RabbitConfig {
    /**
     * 1、name:    队列名称
     * 2、durable: 是否持久化
     * 3、exclusive: 是否独享、排外的。如果设置为true,定义为排他队列。则只有创建者可以使用此队列。也就是private私有的。
     * 4、autoDelete: 是否自动删除。也就是临时队列。当最后一个消费者断开连接后,会自动删除。
     * */
    //RabbitMQ队列主题的名称
    public static final String RABBITMQ_DEMO_NAME="rabbitmqDemoTopic";

    //RabbitMQ的DIRECT交换机名称
    public static final String RABBIT_DEMO_DIRECT_EXCHANGE="rabbitmqDemoDirectExchange";

    //RabbitMQ的DIRECT交换机和队列绑定的匹配键 DirectRouting
    public static final String RABBITMQ_DEMO_DIRECT_ROUTING="rabbitmqDemoDirectRouting";
}

生产者这边创建一个Direct交换机以及队列的配置类

@Configuration
public class DirectRabbitConfig {
    @Bean
    public Queue rabbitmqDemoDirectQueue(){
        /**
         * 1、name:队列名称
         * 2、durable是否持久化
         * 3、exclusive:是否独享、排外的。如果设置为true,定义为排他队列,则只有创建者可以使用此队列
         * 4、autoDelete:是否自动删除 也就是临时队列 当最后一个消费者断开连接后 会自动删除
         */
        return new Queue(RabbitConfig.RABBITMQ_DEMO_NAME,true,false,false);
    }

    @Bean
    public DirectExchange rabbitmqDemoDirectExchange(){
        //Direct交换机
        return new DirectExchange(RabbitConfig.RABBIT_DEMO_DIRECT_EXCHANGE,true,false);
    }

    @Bean
    public Binding bindDirect(){
        //链式写法 绑定交换机和队列 并设置匹配键
        return BindingBuilder
                //绑定队列
                .bind(rabbitmqDemoDirectQueue())
                //到交换机
                .to(rabbitmqDemoDirectExchange())
                //并设置匹配键
                .with(RabbitConfig.RABBITMQ_DEMO_DIRECT_ROUTING);
    }
}

创建service类

@Service
public class RabbitMQServiceImpl implements RabbitMQService {
    //日期格式化
    private static SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    @Resource
    private RabbitTemplate rabbitTemplate;

    @Override
    public String sendMsg(String msg) {
        try {
            String msgID= UUID.randomUUID().toString().replace("-","").substring(0,32);
            String sendTime =sdf.format(new Date());
            Map<String,Object> map=new HashMap<>();
            map.put("msgId",msgID);
            map.put("sendTime",sendTime);
            map.put("msg",msg);
            rabbitTemplate.convertAndSend(RabbitConfig.RABBIT_DEMO_DIRECT_EXCHANGE,RabbitConfig.RABBITMQ_DEMO_DIRECT_ROUTING,map);
            return "OK";
        }catch (Exception ex){
            ex.printStackTrace();
            return "error";
        }
    }
}

根据业务放在需要用的地方,比如定时任务,或者接口。我这里就简单一点使用Controller层进行发送

@RestController
@RequestMapping("/mall/rabbit")
public class RabbitMQController {
    @Resource
    private RabbitMQService rabbitMQService;

    //发送消息
    @PostMapping("/sendMsg")
    public String sendMsg(@RequestParam(name="msg") String msg){
        return rabbitMQService.sendMsg(msg);
    }
}

生产者写完了后,该写消费者代码,@RabbitListener注解写上监听队列的名称,

@Component
@RabbitListener(queues = RabbitConfig.RABBITMQ_DEMO_NAME) //队列名称 可以有多个
public class RabbitConsumer {
    @RabbitHandler
    public void process(Map map){
        System.out.println("消费者从RabbitMQ服务端服务消费者信息:"+map.toString());
    }
}

这时候去运行,会发现无法正常运行,为什么会这样了?
答:未在RabbitMQ服务器中创建队列
打开RabbitMQ文件所在位置,打开sbin文件包,运行cmd,如图
在这里插入图片描述

输入rabbitmq-plugins enable rabbitmq_management命令安装管理页面的插件
在这里插入图片描述
然后双击rabbitmq-server.bat启动脚本,这时候打开浏览器输入
http://localhost:15672,账户密码默认是guest/guest
在这里插入图片描述
点开Queues

在这里插入图片描述
要先启动生产者,发一条消息(打开Postman)
在这里插入图片描述
在启动工程,进行消费
在这里插入图片描述

问题改进

由于队列不存在,启动消费者报错的这个问题。最好的方法是生产者和消费者都尝试创建队列
在文件DirectRabbitConfig中新添加代码

/**
 * 自动配置
 * 1、RabbitConfiguration
 * 2、有自动配置了连接工厂ConnectionFactory
 * 3、RabbitProperties:封装了RabbitMQ的配置
 * 4、RabbitTemplate:给RabbitMQ发送消息
 * 5、AmqpAdmin:RabbitMQ系统管理功能组件
 *      AmqpAdmin:创建和删除 Queue、Exchange、Binding
 * @EnableRabbit+@RabbitListener监听消息内容
 */
@Component
@Configuration
//实现BeanPostProcessor类,使用Bean的生命周期函数
public class DirectRabbitConfig implements BeanPostProcessor {
    //这是创建交换机和队列用的rabbitAdmin对象
    @Resource
    private RabbitAdmin rabbitAdmin;

    //初始化rabbitAdmin
    @Bean
    public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory){
        RabbitAdmin rabbitAdmin=new RabbitAdmin(connectionFactory);
        //只有设置为true,spring才能加载RabbitAdmin这个类
        rabbitAdmin.setAutoStartup(true);
        return rabbitAdmin;
    }

    //实例化Bean后 也就是Bean的后置处理器


    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        //创建交换机
        rabbitAdmin.declareExchange(rabbitmqDemoDirectExchange());
        //创建队列
        rabbitAdmin.declareQueue(rabbitmqDemoDirectQueue());
        return null;
    }
}

这样启动生产者就会自动创建交换机和队列,不用等到发送消息才创建。

消费者也需要添加一些代码

@Component
//@RabbitListener(queues = RabbitConfig.RABBITMQ_DEMO_NAME) //队列名称 可以有多个
//使用queuesToDeclare属性,如果不存在则会创建队列
@RabbitListener(queuesToDeclare = @Queue(RabbitConfig.RABBITMQ_DEMO_NAME))
public class RabbitConsumer {
    @RabbitHandler
    public void process(Map map){
        System.out.println("消费者从RabbitMQ服务端服务消费者信息:"+map.toString());
    }
}

现在就不会出问题了
完整代码如下

https://gitee.com/jiang-yingcai011012/rabbit-mq

Exchange类型

在这里插入图片描述

在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值