Spring boot集成RabbitMq

一、搭建RabbitMq

1.1 参考

RabbitMQ教程
erlong地址
rabbitmq地址
版本对应
在这里插入图片描述

1.2 配置erlong的环境变量

输入erl,可以看到输出

C:\Program Files\RabbitMQ Server\rabbitmq_server-3.8.0\sbin>erl
Eshell V10.0.1  (abort with ^G)
1>

1.3 RabbitMQ对应的在注册表中的位置

计算机\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services

二、使用教程

2.1 打开服务端

  • 以管理员身份启动rabbitmq服务:
net start rabbitmq
  • cmd 打开 G:\software\RabbitMQ Server\rabbitmq_server-3.8.0\sbin,
  • 输入:rabbitmq-plugins enable rabbitmq_management
    出现:
The following plugins have been configured:
  rabbitmq_management
  rabbitmq_management_agent
  rabbitmq_web_dispatch
Applying plugin configuration
  • 浏览器输入:localhost:15672
  • 账号和密码都是guest
    在这里插入图片描述

2.2 注意的问题

  • 配置文件中的端口号不能是15672
  • 配置文件:
#RabbitMQ配置
spring.rabbitmq.host=127.0.0.1
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.virtual-host=/
#消费者数量
spring.rabbitmq.listener.simple.concurrency=10
#消费者最大数量
spring.rabbitmq.listener.simple.max-concurrency=10
#消费,每次从队列中取多少个,取多了,可能处理不过来
spring.rabbitmq.listener.simple.prefetch=1
spring.rabbitmq.listener.direct.auto-startup=true
#消费失败的数据重新压入队列
spring.rabbitmq.listener.simple.default-requeue-rejected=true
#发送,队列满的时候,发送不进去,启动重置
spring.rabbitmq.template.retry.enabled=true
#一秒钟之后重试
spring.rabbitmq.template.retry.initial-interval=1000
#
spring.rabbitmq.template.retry.max-attempts=3
#最大间隔 10s
spring.rabbitmq.template.retry.max-interval=10000
#spring.rabbitmq.template.retry.multiplier=1.0

2.3 Queue的包

import org.springframework.amqp.core.Queue;

三、git命令

3.1 git remote

查看当前的远程库

3.2 git remote add origin “xxxx”

将xxx远程库简单命名origin,并且将添加该远程库

3.3 git push -u origin master

相当于: git push -u origin master:master
把本地仓库master的修改提交到远程仓库的master。

3.4 查看暂存区已经添加的文件

git ls-files

3.5 将当前HEAD复位到指定状态。

一般用于撤消之前的一些操作(如:git add,git commit等)。

git reset xx

3.6 将文件移除暂存区

 git rm --cached RabbitMq

3.7 初始化文件为一个仓库

 git rm --cached RabbitMq

3.8 仓库分类

工作区,暂存区和提交区,工作区就是我们操作文件的地方,git add之后文件被存到暂存区,git commit之后文件被提交到提交区。

3.9 提交文件到提交区

四、rabbitmq 使用

rabbitmq 使用

4.1 遇到的问题

服务启动,页面无法访问
Win10 RabbitMQ unable to perform an operation on node 错误解决方法

五、rabbitma的多种模式

5.1 点对点模式

5.2 工作模式

同案例1

5.3 发布订阅模式

  • 生产者把消息sned到交换机,交换机send到队列

  • 消费者通过绑定的队列获取消息

  • 队列和交换机定义及绑定

package com.example.myService.RabbitMq;

import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Collection;
import java.util.Map;

@Configuration
public class MQConfig {
    public static final String EXCHANGE = "EXCHANGE";
    public static final String EX_QUEUE1 = "ex_queue1";
    public static final String EX_QUEUE2 = "ex_queue2";
    @Bean
    public Queue queue1() {
        //名称,是否持久化
        return new Queue(EX_QUEUE1, true, false,true);
    }
    @Bean
    public Queue queue2() {
        //名称,是否持久化
        return new Queue(EX_QUEUE2, true, false,true);
    }
    @Bean
    public Exchange exchange() {
        return ExchangeBuilder.fanoutExchange(EXCHANGE).build();
    }
    @Bean
    public Binding bind_queue1(@Qualifier("queue1") Queue queue, @Qualifier("exchange") Exchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with("").noargs();
    }
    @Bean
    public Binding bind_queue2(@Qualifier("queue2")Queue queue, @Qualifier("exchange")Exchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with("").noargs();
    }
}

  • 消息发送
@Component
public class MqSender {
    public static final Logger log = LoggerFactory.getLogger(MqSender.class);
    @Autowired
    AmqpTemplate amqpTemplate;
    public void send(String str){
        for (int i = 0; i < 10; i++) {
            //""表示路由key
            amqpTemplate.convertAndSend(MQConfig.EXCHANGE,"",str + i);
            log.info("发送的消息是" + str + i);
        }
    }
}
  • 消息消费
@Component
public class MqReciver {
    public static Logger log  = LoggerFactory.getLogger(MqReciver.class);
    @RabbitListener(queues = MQConfig.EX_QUEUE1)
    public void receive1(String str){
        log.info("接收到的消息" + str);
        System.out.println("queue1" + str);
    }
    @RabbitListener(queues = MQConfig.EX_QUEUE2)
    public void receive2(String str){
        log.info("接收到的消息" + str);
        System.out.println("queue2" + str);
    }
}

  • 测试
 @Autowired
    MqSender mqSender;
    @Test
    public void test6() {
        mqSender.send("你好不呀");
    }

5.4 路由模式

  • 交换机,路由,key定义及绑定
  • 路由的交换机是directExchange
  • amqpTemplate.convertAndSend(MQConfig.EXCHANGE,MQConfig.EX_QUEUE1,msg):参数依次是交换机,路由器
package com.example.myService.RabbitMq;

import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Collection;
import java.util.Map;

@Configuration
public class MQConfig {
    public static final String EXCHANGE = "T_EXCHANGE";
    public static final String EX_QUEUE1 = "T_queue1";
    public static final String EX_QUEUE2 = "T_queue2";
    public static final String ROUTE1 = "father";
    public static final String ROUTE2 = "mother";
    @Bean
    public Queue t_queue11() {
        //名称,是否持久化
        return new Queue(EX_QUEUE1,false,false,false);
        //return QueueBuilder.nonDurable(EX_QUEUE2).exclusive().build();
    }
    @Bean
    public Queue t_queue22() {
        //名称,是否持久化
        return new Queue(EX_QUEUE2,false,false,false);
        //return QueueBuilder.nonDurable(EX_QUEUE2).build();
    }
    @Bean
    public DirectExchange t_exchange1() {
        DirectExchange directExchange = new DirectExchange(EXCHANGE, true, false);
        directExchange.setInternal(false);
        return directExchange;
    }
    @Bean
    public Binding bind_queue1(@Qualifier("t_queue11") Queue queue, @Qualifier("t_exchange1") DirectExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(MQConfig.ROUTE1);
    }
    @Bean
    public Binding bind_queue2(@Qualifier("t_queue22")Queue queue, @Qualifier("t_exchange1")DirectExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(MQConfig.ROUTE2);
    }
}

  • 发送者
package com.example.myService.RabbitMq;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;



@Component
public class MqSender {
    public static final Logger log = LoggerFactory.getLogger(MqSender.class);
    @Autowired
    AmqpTemplate amqpTemplate;
    public void send(String str) throws InterruptedException {
        for (int i = 0; i < 5; i++) {
            //""表示路由key
            String msg = str + "给队列1发送的" + i;
            amqpTemplate.convertAndSend(MQConfig.EXCHANGE,"father",msg);
            log.info(msg);
        }
//        for (int i = 0; i < 5; i++) {
//            //""表示路由key
//            String msg = str + "给队列2发送的" + i;
//            amqpTemplate.convertAndSend(MQConfig.EXCHANGE,MQConfig.EX_QUEUE2,msg);
//            log.info(msg);
//        }
    }
}
  • 消费者
package com.example.myService.RabbitMq;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.TopicExchange;
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.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;


@Component
public class MqReciver {
    public static Logger log  = LoggerFactory.getLogger(MqReciver.class);
    @RabbitListener( bindings = {
            @QueueBinding(value = @Queue(value =MQConfig.EX_QUEUE1,durable = "false",exclusive = "false",autoDelete = "false"),
                    exchange = @Exchange(value = MQConfig.EXCHANGE, type = ExchangeTypes.DIRECT,internal = "false",autoDelete = "false"),
                    key = MQConfig.ROUTE1)})
    public void receive1(String str){
        log.info("接收到的消息" + str);
        System.out.println("queue1" + str);
    }
    @RabbitListener(bindings = {
            @QueueBinding(value = @Queue(value =MQConfig.EX_QUEUE2,durable = "false",exclusive = "false",autoDelete = "false"),
                    exchange = @Exchange(value = MQConfig.EXCHANGE,type = ExchangeTypes.DIRECT,internal = "false",autoDelete = "false"),
                    key = MQConfig.ROUTE2)})
    public void receive2(String str){
        log.info("接收到的消息" + str);
        System.out.println("queue2" + str);
    }
}



  • 测试同上

5.5 topic模式

  • 匹配规则
星号 (*):匹配一个单词。单词是由点号 (.) 分隔的字符串。
井号 (#):匹配零个或多个单词。
  • 自定义
package com.example.myService.RabbitMq;

import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Collection;
import java.util.Map;

@Configuration
public class MQConfig {
    public static final String EXCHANGE = "T_EXCHANGE";
    public static final String EX_QUEUE1 = "T_queue1";
    public static final String EX_QUEUE2 = "T_queue2";
    public static final String TOPIC1 = "aa.bb.*";
    public static final String TOPIC2 = "aa.cc.#";
    @Bean
    public Queue t_queue11() {
        //名称,是否持久化
        return new Queue(EX_QUEUE1,false,false,false);
        //return QueueBuilder.nonDurable(EX_QUEUE2).exclusive().build();
    }
    @Bean
    public Queue t_queue22() {
        //名称,是否持久化
        return new Queue(EX_QUEUE2,false,false,false);
        //return QueueBuilder.nonDurable(EX_QUEUE2).build();
    }
    @Bean
    public TopicExchange t_exchange1() {
        TopicExchange topicExchange = new TopicExchange(EXCHANGE, true, false);
        topicExchange.setInternal(false);
        return topicExchange;
    }
    @Bean
    public Binding bind_queue1(@Qualifier("t_queue11") Queue queue, @Qualifier("t_exchange1") TopicExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(MQConfig.TOPIC1);
    }
    @Bean
    public Binding bind_queue2(@Qualifier("t_queue22")Queue queue, @Qualifier("t_exchange1")TopicExchange exchange) {
        return BindingBuilder.bind(queue).to(exchange).with(MQConfig.TOPIC2);
    }
}

  • 发送者
package com.example.myService.RabbitMq;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;



@Component
public class MqSender {
    public static final Logger log = LoggerFactory.getLogger(MqSender.class);
    @Autowired
    AmqpTemplate amqpTemplate;
    public void send(String str) throws InterruptedException {
        for (int i = 0; i < 5; i++) {
            //""表示路由key
            String msg = str + "给队列2发送的" + i;
            amqpTemplate.convertAndSend(MQConfig.EXCHANGE,"aa.cc.ee",msg);
            log.info(msg);
        }
//        for (int i = 0; i < 5; i++) {
//            //""表示路由key
//            String msg = str + "给队列2发送的" + i;
//            amqpTemplate.convertAndSend(MQConfig.EXCHANGE,MQConfig.EX_QUEUE2,msg);
//            log.info(msg);
//        }
    }
}
  • 消费者
package com.example.myService.RabbitMq;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.TopicExchange;
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.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;


@Component
public class MqReciver {
    public static Logger log  = LoggerFactory.getLogger(MqReciver.class);
    @RabbitListener( bindings = {
            @QueueBinding(value = @Queue(value =MQConfig.EX_QUEUE1,durable = "false",exclusive = "false",autoDelete = "false"),
                    exchange = @Exchange(value = MQConfig.EXCHANGE, type = ExchangeTypes.TOPIC,internal = "false",autoDelete = "false"),
                    key = MQConfig.TOPIC1)})
    public void receive1(String str){
        log.info("接收到的消息" + str);
        System.out.println("queue1" + str);
    }
    @RabbitListener(bindings = {
            @QueueBinding(value = @Queue(value =MQConfig.EX_QUEUE2,durable = "false",exclusive = "false",autoDelete = "false"),
                    exchange = @Exchange(value = MQConfig.EXCHANGE,type = ExchangeTypes.TOPIC,internal = "false",autoDelete = "false"),
                    key = MQConfig.TOPIC2)})
    public void receive2(String str){
        log.info("接收到的消息" + str);
        System.out.println("queue2" + str);
    }
}

5.6 head模式

package com.example.myService.RabbitMq;

import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

@Configuration
public class MQConfig {
    public static final String EXCHANGE = "H_EXCHANGE";
    public static final String EX_QUEUE1 = "H_queue1";
    public static final String EX_QUEUE2 = "H_queue2";
    @Bean
    public Queue h_queue11() {
        //名称,是否持久化
        return new Queue(EX_QUEUE1,false,false,false);
        //return QueueBuilder.nonDurable(EX_QUEUE2).exclusive().build();
    }
    @Bean
    public Queue h_queue22() {
        //名称,是否持久化
        return new Queue(EX_QUEUE2,false,false,false);
        //return QueueBuilder.nonDurable(EX_QUEUE2).build();
    }
    @Bean
    public HeadersExchange h_exchange1() {
        HeadersExchange directExchange = new HeadersExchange(EXCHANGE, true, false);
        directExchange.setInternal(false);
        return directExchange;
    }
    @Bean
    public Binding binding1(@Qualifier("h_queue11")Queue queue, @Qualifier("h_exchange1")HeadersExchange exchange) {
        Map<String, Object> headers = new HashMap<>();
        headers.put("content-type", "application/json");
        headers.put("user-id", "123");
        return BindingBuilder.bind(queue)
                .to(exchange)
                .whereAll(headers).match();
    }
    @Bean
    public Binding binding2(@Qualifier("h_queue22")Queue queue, @Qualifier("h_exchange1")HeadersExchange exchange) {
        Map<String, Object> headers = new HashMap<>();
        headers.put("content", "application");
        headers.put("user", "12");
        return BindingBuilder.bind(queue)
                .to(exchange)
                .whereAll(headers).match();
    }
}

  • 发送者
package com.example.myService.RabbitMq;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageDeliveryMode;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;


@Component
public class MqSender {
    public static final Logger log = LoggerFactory.getLogger(MqSender.class);
    @Autowired
    AmqpTemplate amqpTemplate;
    public void send(String str) throws InterruptedException {
        Map<String, Object> headers = new HashMap();
        headers.put("content-type", "application/json");
        headers.put("user-id", "123");
        MessageProperties messageProperties = new MessageProperties();
        // 设置消息是否持久化。Persistent表示持久化,Non-persistent表示不持久化
        messageProperties.setDeliveryMode(MessageDeliveryMode.NON_PERSISTENT);
        messageProperties.setContentType("UTF-8");
        messageProperties.getHeaders().putAll(headers);

        for (int i = 0; i < 5; i++) {
            //""表示路由key
            String msg = str + "给队列1发送的" + i;
            Message message = new Message(msg.getBytes(), messageProperties);
            amqpTemplate.convertAndSend(MQConfig.EXCHANGE,null,message);
            log.info(msg);
        }
    }
}
  • 接受者
package com.example.myService.RabbitMq;


import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.TopicExchange;
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.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;


@Component
public class MqReciver {
    public static Logger log  = LoggerFactory.getLogger(MqReciver.class);
    @RabbitListener( bindings = {
            @QueueBinding(value = @Queue(value =MQConfig.EX_QUEUE1,durable = "false",exclusive = "false",autoDelete = "false"),
                    exchange = @Exchange(value = MQConfig.EXCHANGE, type = ExchangeTypes.HEADERS,internal = "false",autoDelete = "false"))})
    public void receive1(String str){
        log.info("接收到的消息" + str);
        System.out.println("queue1" + str);
    }
    @RabbitListener(bindings = {
            @QueueBinding(value = @Queue(value =MQConfig.EX_QUEUE2,durable = "false",exclusive = "false",autoDelete = "false"),
                    exchange = @Exchange(value = MQConfig.EXCHANGE,type = ExchangeTypes.HEADERS,internal = "false",autoDelete = "false"))})
    public void receive2(String str){
        log.info("接收到的消息" + str);
        System.out.println("queue2" + str);
    }
}

六、队列设置

6.1 exclusive

exclusive 表示队列是否是排他的。如果一个队列被声明为排他的,那么只有声明该队列的连接才能使用它,连接断开时会自动删除这个队列。设置为 true 表示队列是排他的。

6.2 durable

持久性设置:如果你声明队列时设置了 durable=False,而 RabbitMQ 服务重启后,队列会丢失

6.3 auto-delete

  • 如果你声明队列时设置了 auto-delete 属性,那么在没有消费者订阅时,队列会被自动删除。因此,如果你的应用程序启动时没有消费者订阅队列,队列可能会被删除。

6.4 internal

  • 默认是true
  • 在RabbitMQ中,交换机有一个属性称为internal。当一个交换机被标记为internal时,它只能被其他交换机使用,不能被客户端(生产者或消费者)直接使用。这种类型的交换机通常用于更复杂的消息路由方案中,在交换机之间进行消息传递。

属性说明

6.5 队列无法创建

  • 交换机创建出错,需要对比本地和客户端的交换机配置是否一致。
    RabbitMQ不自动生成队列问题【记录】
  • 所有错误检查后,就要检查消费者exchange,queue的设置是否与原来的一致
  • exchange的durable设置成true
  • 百分之90的错误都在消费者
    在这里插入图片描述
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值