【笔记】RabbitMQ安装和Spring AMQP

本文详细介绍了如何在RabbitMQ上安装和配置,包括使用Docker启动RabbitMQ容器,以及在SpringAMQP中实现消息发送、接收和不同类型的交换机(如DirectExchange、TopicExchange和FannoutExchange)。还探讨了如何使用Jackson2JsonMessageConverter进行消息转换以提高效率。
摘要由CSDN通过智能技术生成

目录

一、安装

消息发送

接收消息(消费者)

 消息发送(FannoutExchange)

消息发送(DirectExchange)

消息发送(TopicExchange)

消息转换器:


RabbitMQ 是一种可靠且成熟的消息传递和流媒体代理 

一、安装

docker启动RabbitMQ容器,

sudo docker run -d --rm \
-e RABBITMQ_DEFAULT_USER=jungle \
-e RABBITMQ_DEFAULT_PASS=123456 \
--name rabbitmq \
-p 5672:5672 \
-p 15672:15672 \
rabbitmq:3.13-management
  • --rm:表示容器退出时自动删除容器。这意味着当容器停止后,它的文件系统和其他内容将会被删除。如果你想保留容器的数据,可以省略此参数。
  • RABBITMQ_DEFAULT_USER=用户名
  • RABBITMQ_DEFAULT_PASS=密码
  • 5672  控制台端口
  • 15672 平台访问端口

换成docker-compose.yml内容:

version: '3.8'

services:
  rabbitmq:
    image: rabbitmq:3.13-management
    container_name: rabbitmq
    ports:
      - "5672:5672" #控制台端口
      - "15672:15672" #平台访问端口

 ip+端口访问,输入自己设置的用户名密码登录,我的是http://172.30.171.205:15672/

 进入:

 

 二、使用Spring AMQP进行消息传递

        Spring AMQP提供了一个 "Template",作为发送和接收消息的高级抽象。

在项目中父工程引入依赖:

        <!--AMQP依赖,包含RabbitMQ-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
        </dependency>

【注意】AMQP依赖,包含RabbitMQ,无需引入以下rabbitmq的依赖,

        <!-- Spring AMQP -->
        <dependency>
            <groupId>org.springframework.amqp</groupId>
            <artifactId>spring-rabbit</artifactId>
            <version>3.1.4</version>
        </dependency>

 引入可能会报错

        JDK版本不对应

        consumer thread error, thread abort.(消费者线程错误,线程中止)

消息发送

Spring官方文档: What’s New :: Spring AMQPicon-default.png?t=N7T8https://docs.spring.io/spring-amqp/reference/whats-new.html

添加队列 simple.queue :

  

      在需要做消息发送的服务A中application.yml文件中添加以下配置信息,对RabbitMQ服务主机名、端口、虚拟主机、用户名、密码进行配置

spring:
  rabbitmq:
    host: 172.30.171.205 # 主机名
    port: 5672 # 端口
    virtual-host: / # 虚拟主机
    username: jungle # 用户名
    password: 123456# 密码

编写测试类,测试消息发送

@SpringBootTest
public class PublisherTest {

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Test
    public void publisher(){
        // 队列名称
        String queueName = "simple.queue";
        // 消息
        String message = "消息发送内容,hello AMQP !";
        // 发送消息
        rabbitTemplate.convertAndSend(queueName, message);
    }
}

接收消息(消费者)

在需要接收消息的服务中,依然需要引依赖和加RabbitMQ的配置信息,新建一个类SpringRabbitListener测试接收消息,启动服务后,可接收simple.queue队列消息

@Component
public class SpringRabbitListener {

    @RabbitListener(queues = "simple.queue")
    public void listenSimpleQueueMessage(String msg){
        System.out.println("Spring 消费者接收到消息:【" + msg + "】");
    }
}

当使用多个消费者去处理消息时,配置消费预取限制,根据服务的能力,规定每次能处理的消息数量

spring:
  rabbitmq:
    listener:
      simple:
        prefetch: 1 #每次只能获取一条消息,处理完成才能获取下一个消息
 

 消息发送(FannoutExchange)

所有订阅的队列都消费

声明交换机、队列以及消费者中配置队列绑定到交换机的关系(可在rabbitmq平台页面查看):

声明交换机、队列和绑定关系的Bean 时注意方法名不用重复,绑定关系的方法的参数类型和参数名要与之前声明Bean的方法名对应,例如方法FanoutExchange fanoutExchange(){}和方法Queue fanoutQueue1(){} 对应参数 Binding bindQueue1(FanoutExchange fanoutExchange,Queue fanoutQueue1){},参数名和方法名不对应则会使注入对象失败:Could not autowire.(不能自动注入)


import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.FanoutExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class FanoutConfiguration {

    //交换机 jungle.fanout
    @Bean
    public FanoutExchange fanoutExchange(){
        return new FanoutExchange("jungle.fanout");
    }
    //队列1 fanout.queue1
    @Bean
    public Queue fanoutQueue1(){
        return new Queue("fanout.queue1");
    }

    //队列2 fanout.queue2
    @Bean
    public Queue fanoutQueue2(){
        return new Queue("fanout.queue2");
    }


    //绑定队列1到交换机 fanout.queue1
    @Bean
    public Binding bindQueue1(FanoutExchange fanoutExchange,Queue fanoutQueue1){
        return BindingBuilder
                .bind(fanoutQueue1)
                .to(fanoutExchange);
    }
    //绑定队列2到交换机 fanout.queue1
    @Bean
    public Binding bindQueue2(FanoutExchange fanoutExchange,Queue fanoutQueue2){
        return BindingBuilder
                .bind(fanoutQueue2)
                .to(fanoutExchange);
    }
}

向交换机为jungle.fanout的所有队列发送消息

    /**
     * 向多个消费者发送同一消息
     */
    @Test
    public void publisherFanoutExchange(){
        // 交换机名称
        String exchangeName = "jungle.fanout";
        // 消息
        String message = "消息群送内容,hello,everyone AMQP !";
        // 发送消息
        rabbitTemplate.convertAndSend(exchangeName,"", message);
    }

消息发送(DirectExchange)

含有指定的routingKey的队列消息才会被消费

发送消息,指定routingKey为keyName1

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /**
     * 向多个消费者发送同一消息,含有routingKey为keyName1
     */
    @Test
    public void publisherFanoutExchange(){
        // 交换机名称
        String exchangeName = "jungle.fanout";
        // 消息
        String message = "消息群送内容,hello,everyone AMQP !";
        // 发送消息
        rabbitTemplate.convertAndSend(exchangeName,"keyName1", message);
    }

以下例子中,监听jungle.direct交换机中的direct.queue1队列,并且routingKey有keyName1、keyName2的消息才会被消费。


@RabbitListener(bindings = @QueueBinding(
        value = @Queue("direct.queue1"),
        exchange = @Exchange(name = "jungle.direct",type = ExchangeTypes.DIRECT),
        key = {"keyName1","keyName2"}
))
public void listenDirectQueue(String msg) {
    System.out.println("消费者2 接收到direct消息:【" + msg + "】");
}

消息发送(TopicExchange)

可用使用通配符来指定routingKey的值,routingkey 一般都是有一个或多个单词组成,多个单词之间以”.”分割,例如: china.weacher

 通配符规则:

#:匹配一个或多个词

*:只匹配1个词

例如:china.*  

    //监听jungle.topic.queue1队列,并且routingKey满足通配符china.# 的消息
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue("topic.queue1"),
            exchange = @Exchange(name = "jungle.direct",type = ExchangeTypes.TOPIC),
            key = {"china.#"}
    ))
    public void listenTopicQueue(String msg) {
        System.out.println("消费者2 接收到topic消息:【" + msg + "】");
    }

【注意】在rabbitmq页面创建对应的交换机、队列在配置类中声明对应的交换机或队列

消息转换器:

默认使用JDK序列化方式,消息体积大,可读性小

在启动类中添加或者自己新建一个配置类添加: 


    //配置消息转换器类型,JDK序列化方式并不合适。希望消息体的体积更小、可读性更高,因此可以使用JSON方式来做序列化和反序列化
    @Bean
    public MessageConverter jsonMessageConverter(){
        return new Jackson2JsonMessageConverter();
    }

发送消息:

    @Test
    public void publisher(){
        // 队列名称
        String queueName = "simple.queue";
        // 消息
        Student student =new Student();
        student.setName("Jungle");
        student.setAge(25);

        // 发送消息
        rabbitTemplate.convertAndSend(queueName, student);
    }

 接收消息:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值