rabbitMQ结合SpringAMQP基本用法

RabbitMQ 结合 SpringAMQP 基本用法

SpringAMQP

Spring AMQP是Spring框架提供的一个基于AMQP(高级消息队列协议)的消息队列解决方案,用于简化Spring应用程序对消息队列的使用。它主要包含以下几个模块:

  1. spring-amqp:该模块是Spring AMQP的核心模块,定义了与AMQP相关的通用操作,如发送消息、接收消息等。
  2. spring-rabbit:该模块是基于RabbitMQ的消息中间件,它提供了模板化的发送和接收消息的抽象层,简化了RabbitMQ的使用。
  3. spring-erlang:该模块是基于Erlang的消息中间件,它提供了与RabbitMQ的交互方式,方便使用Erlang语言的开发者使用Spring AMQP。

Spring AMQP的主要优点在于它提供了一个高级别的抽象,使得生产者和消费者可以用简单的方式与消息队列进行通信,同时减少了开发者对AMQP协议的细节处理。此外,Spring AMQP还支持多种消息传递模式,如发布/订阅、点对点、请求/响应等。

支持范围

Spring AMQP支持多种消息队列,包括但不限于以下几种:

  1. RabbitMQ:一个基于AMQP标准、开放源代码的、可移植的、分布式的消息代理软件。RabbitMQ是使用Erlang语言编写的一个开源消息代理软件,它实现了AMQP协议,提供了多种语言的客户端库。
  2. ActiveMQ:一个流行的基于Java的消息传递系统,它实现了JMS(Java消息服务)规范以及其他AMQP标准。ActiveMQ具有高度可靠性和灵活性,支持多种消息协议和数据传输格式。
  3. Apache Kafka:一个开源的分布式流处理系统,它以高吞吐量、可扩展性和实时性著称。Apache Kafka通常被用于处理和分析大规模的数据流,但它也可以作为消息队列使用。
  4. Amazon SQS:亚马逊云服务中的简单队列服务(Simple Queue Service),它是一个分布式消息队列系统,可以在多个亚马逊EC2实例之间安全地传递消息。

以上是一些常见的消息队列,Spring AMQP可以与这些消息队列进行集成,帮助开发者更方便地使用这些消息队列进行应用程序的消息传递。

pom依赖

<dependencies>  
    <dependency>  
        <groupId>org.springframework.boot</groupId>  
        <artifactId>spring-boot-starter-amqp</artifactId>  
    </dependency>  
</dependencies>

配置文件

spring:
	rabbitmq:
		host: 127.0.0.1 # ip
		port: 5672 # 端口
		username: root # 用户名
		password: root # 密码
		virtural-host: / # 虚拟地址 
		listener:
			simple:
				prefetch: 1 # 设置这个和值 可以控制预取到消息的上限 这里默认是无限
  • 消费预取限制
listener:
	simple:
		prefetch: 1 # 设置这个和值 可以控制预取到消息的上限 这里默认是无限

交换机

如果不加入交换机 默认被消费者消费之后就会从消息队列中删除,可以投递给多个队列,这样就解决了一次发送,多次接收的问题

分为以下几类:

  • Fanout 广播
  • Direct 路由
  • Topic 话题

FanoutExchange(广播模式)最简单!

  • 在springAMQP中提供了生命交换机、队列、绑定关系的API

image-20230905125421899

1、添加配置类

在consumer服务声明EXchange、Queue、Binding

在consumer服务常见一个类 添加@Configuration注解, 并声明FanoutExchange,Queue 和绑定关系对象Binding,代码如下:

@Configuration
public class FanoutConfig{
    // 声明 FanoutExchange 交换机
    @Bean
    public FanoutExchange fanoutExchange(){
        return new FanoutExchange("zky.fanout");
    }
    
    // 声明 队列1
    @Bean
    public Queue fanoutQueue1(){
        return new Queue("fanout.queue");
    }
    
    // 绑定 队列1 和 交换机
    @Bean
    public Binding fanoutBinding1(Queue fanoutQueue1, FanoutExchange fanoutExchange){
        return BindingBuilder.bind(fanoutQueue1).to(fanoutExchange);
    }
    
    // 声明 队列2
    @Bean
    public Queue fanoutQueue1(){
        return new Queue("fanout.queue");
    }
    
    // 绑定 队列2 和 交换机
    @Bean
    public Binding fanoutBinding1(Queue fanoutQueue2, FanoutExchange fanoutExchange){
        return BindingBuilder.bind(fanoutQueue2).to(fanoutExchange);
    }
}
2、消息发送
public void sendFanoutExchange(){
    // 交换机名称
	String exchangeName = "zky.fanout";
	// 消息内容
	String message = "hello, everyone!"
	// 发送消息
	rabbitTemplate.convertAndSend(exchangeName,"", message);
}
3、消息接收
@RabbitListener(queues = "fanout.queue1")
public void listentFanoutQueue1(String msg){
    System.out.println("消费者收到fanout.queue1的消息:" + msg);
}

@RabbitListener(queues = "fanout.queue2")
public void listentFanoutQueue2(String msg){
    System.out.println("消费者收到fanout.queue2的消息:" + msg);
}

DirectExchange(路由模式)

发布给指定的Queue 因此叫做路由模式

  • 每一个Queue都与Exchange设置一个BingdingKey

  • 发布者发送消息是,指定消息的RoutingKey

  • Exchange将消息路由到BindingKey与消息RoutingKey一致的队列

分为以下几个步骤:

1、利用@RabbitListener 声明Exchange、Queue、RoutingKey

2、在consumer服务中,编写两个消费者方法,分别监听direct.queue1 和 direct.queue2

3、在publisher 中编写测试方法,向 zky.direct 发送消息[[]]

1、消息接收
@RabbitListener(bindings = @QueueBinding(
		value = @Queue(name = "direct.queue1"),
    	exchange = @Exchange(name = "zky.direct", type = ExchangeTypes.DIRECT),
    	key = {"red", "blue"}
))
public void listenDirectQueue1(String msg){
    System.out.println("消费者收到fanout.queue1的消息:" + msg);
}


@RabbitListener(bindings = @QueueBinding(
		value = @Queue(name = "direct.queue2"),
    	exchange = @Exchange(name = "zky.direct", type = ExchangeTypes.DIRECT),
    	key = {"yellow", "red"}
))
public void listenDirectQueue2(String msg){
    System.out.println("消费者收到fanout.queue2的消息:" + msg);
}
2、消息发送
public void sendDirectExchange(){
    // 交换机名称
	String exchangeName = "zky.fanout";
	// 消息内容
	String message = "hello, blue!"
	// 发送消息
	rabbitTemplate.convertAndSend(exchangeName, "blue", message);
}

TopicExchange(话题模式)

和directExchange 模式类似,区别在于routingKey 必须是多个单词组成的列表,并且以 . 分割

例如:china.news

​ china.weather

​ …

Queue与Exchange指定BindingKey时可以使用通配符:

#: 代指0或多个单词

*: 代指一个单词

1、消息发送
public void sendTopicExchange(){
    // 交换机名称
	String exchangeName = "zky.topic";
	// 消息内容
	String message = "你好, 中国!"
	// 发送消息
	rabbitTemplate.convertAndSend(exchangeName, "china.news", message);
}
2、消息接收
@RabbitListener(bindings = @QueueBinding(
		value = @Queue(name = "topic.queue1"),
    	exchange = @Exchange(name = "zky.topic", type = ExchangeTypes.TOPIC),
    	key = "china.#"
))
public void listenDirectQueue1(String msg){
    System.out.println("消费者收到topic.queue1的消息:" + msg);
}


@RabbitListener(bindings = @QueueBinding(
		value = @Queue(name = "topic.queue2"),
    	exchange = @Exchange(name = "zky.topic", type = ExchangeTypes.TOPIC),
    	key = "#.news"
))
public void listenDirectQueue2(String msg){
    System.out.println("消费者收到topic.queue2的消息:" + msg);
}

消息转换器

@Bean
public Queue objectQueue(){
    return new Queue("objectQueue");
}
public void sendObjectQueue(){
    Map<String,Object> map = new HashMap<>();
    msg.put("name", "鸽鸽");
    msg.put("age", "21")
    rabbitTemplate.convertAndSend("object.queue", msg);
}

序列化性能优化

Spring 的对消息对象的处理是由 org.springframework.amqp.support.converter.MessageConverter来处理的,而默认实现是SimpleMessageConverter 基于JDK 的ObjectOutputStream 完成序列化

如果要修改只需要定义一个MessageConverter 类型的Bean 即可,推荐用JSON方式序列化 applicaton/json 格式,步骤如下:

引入依赖
<dependencies>  
    <dependency>  
        <groupId>com.fasterxml.jackson.dataformat</groupId>  
        <artifactId>jackson-dataformat-xml</artifactId>  
        <version>2.9.10</version>  
    </dependency>  
</dependencies>
声明Bean
  • 服务声明MessageConvert 在amqp包下面啊!
@Bean
public MessageConverter jsonMessageConverter(){
    return new Jackson2JsonMessageConverter();
}

发送消息(不用变)

接收消息

@RabbitListener(queues = "obejct.queue")
public void listenerObjectQueue(Map<String, Obejct> map){
    System.out.println("消费者收到obejct.queue的消息:" + map);
}

RabbitMQ 高级特性

消息确认、消息可靠投递、备份交换机、消息幂等性保障、自定义消费者、消费端限流、ack超时重传机制、TTL队列/消息、死信队列、延迟队列、优先级、持久化

总之就是保持消息的可靠传输

RabbitMQ-高级特性(面试和工作重点)_zdkdchao的博客-CSDN博客

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Kaiyue.zhao

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值