SpringBoot集成RabbitMQ-Fanout模式

本文介绍了如何在SpringBoot项目中集成RabbitMQ,通过创建生产者和消费者应用,实现了分布式环境下的异步消息传递。详细步骤包括配置RabbitMQ服务器、创建Fanout Exchange、定义队列并进行绑定,以及编写服务接口和服务实现。最后,通过测试验证了生产者发送订单信息,消费者成功监听并接收消息。

前言

需要在本地安装Rabbit的服务器

安装教程

使用场景

刚开始进入公司的时候,我们公司的架构还比较单一,就采用一种单体结构,而单体结构的话它是把所以的业务都堆积在一个项目里面,但是随着公司业务不断发展和推进,我们公司的负责人就开始把项目进行分裂,变成了一个分布式的架构,就把系统进行了一个拆分,在拆分的过程中我们就要考虑到一个问题,比如在拆分过程中,我们把用户模块和下单模块做了一个拆分,但是它们之间的数据要进行一个交互,因为在下单的时候需要获取到用户的一些资料,所以我们公司采用了一个消息队列,在选择的时候就一直在思考用什么消息队列,这个时候就选择了RebbitMQ,而我自己使用RebbitMQ的一个核心的感受,就是它是一个异步的多线程,是一个分发的多线程机制,然后它可以让我们网站的一个效率做成倍的提升,因为它是异步的所以它可以让我们处理数据的能力更加的高效和稳健

1.通过Spring官网快速创建一个RabbitMQ的生产者项目

2.导入项目后在application.yml文件中配置

# 服务端口
server:
  port: 8081
  
#配置rabbitmq服务 测试不用写,默认本机
spring:
  rabbitmq:
      username: guest #默认账号
      password: guest #默认密码
      virtual-host: /
      host: localhost
      port: 5672
      #消息确认配置项
      #确认消息已发送到交换机: Exchange
      publisher-confirm-type: correlated
      #确认消息已发送到队列: Queue
      publisher-returns: true

3.创建一个RabbitMqConfig配置类

package com.exam.RebbitMQ.config;

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 RabbitMqConfig {

	//1:声明注册fanout模式的交换机,参数1:对应的service的fanoutName,参数2:持久化(true,false),参数3:自动删除(false/true)
	@Bean
	public FanoutExchange fanoutExchange(){
		return new  FanoutExchange("fanout_order_exchang", true, false);
	}
	//2:声明队列 sms.fanout.queue,email.fanout.queue,duanxin.fanout.queue
	//参数1:名字,参数2:持久化队列true
	//短信队列
	@Bean
	public Queue smsQueue() {
		System.err.println("执行了sms");
		return new Queue("sms.fanout.queue",true);
	}
	@Bean
	public Queue duanxinQueue() {
		System.err.println("执行了duanxin");
		return new Queue("duanxin.fanout.queue",true);
	}
	//邮箱队列
	@Bean
	public Queue emailQueue() {
		System.err.println("执行了email");
		return new Queue("email.fanout.queue",true);
	}
	//3:完成绑定关系(队列和交换机完成绑定关系)
	@Bean
	public Binding smsBinding() {
		//把smsQueue放到fanoutExchange交换机上面
		return BindingBuilder.bind(smsQueue()).to(fanoutExchange());
	}
	@Bean
	public Binding duanxinBinding() {
		//把duanxinQueue放到fanoutExchange交换机上面
		return BindingBuilder.bind(duanxinQueue()).to(fanoutExchange());
	}
	@Bean
	public Binding emailBinding() {
		//把emailQueue放到fanoutExchange交换机上面
		return BindingBuilder.bind(emailQueue()).to(fanoutExchange());
	}

}

4.创建OrderService,OrderServiceImpl

  • OrderService
package com.exam.RebbitMQ.service;

public interface OrderService {
	void makeOrder(String userid,String productid,int num);
}
  • OrderServiceImpl
package com.exam.RebbitMQ.service.Impl;

import java.util.UUID;

import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.exam.RebbitMQ.service.OrderService;

@Service
public class OrderServiceImpl implements OrderService{
	
	@Autowired
	private RabbitTemplate rabbitTemplate;
	
	/**
	 * 模拟用户下单 
	 **/
	public void makeOrder(String userid,String productid,int num) {
		//1.根据商品ID查询商品是否充足
		//2.保存订单
		String  orderId = UUID.randomUUID().toString();
		System.err.println("订单生成成功"+orderId);
		//3.通过MQ来完成消息的分发
		//参数1:交换机 参数二:路由key/queue队列名称  参数三:消息内容
		String  exchangName ="fanout_order_exchang";
		String routingKey = "";
		rabbitTemplate.convertAndSend(exchangName, routingKey, orderId);
	}

}

5.在项目的test中发送请求

package com.huyi.rabbitmq;

import com.huyi.rabbitmq.service.OrderService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
class RabbitMqApplicationTests {

	@Autowired
	private OrderService orderService;

	@Test
	void contextLoads() {
		orderService.makeOrder("1","1", 18);
	}

}

6.访问网址: http://localhost:15672/#/queues

  • 账号和密码都是:guest

  • 点击Exchanges查看是否创建成功

  • 点击Queues查看是否创建成功

6.再创建一个消费者项目

7.在消费者项目中把生产者项目中的yml配置复制过来,改一下端口

# 服务端口
server:
  port: 8082

#配置rabbitmq服务 测试不用写,默认本机
spring:
  rabbitmq:
    username: guest #默认账号
    password: guest #默认密码
    virtual-host: /
    host: localhost
    port: 5672
    #消息确认配置项
    #确认消息已发送到交换机: Exchange
    publisher-confirm-type: correlated
    #确认消息已发送到队列: Queue
    publisher-returns: true

8. 创建对应的service文件

  • SmsConsumerService、SmsConsumerServiceImpl
package com.huyi.rabbitmq_consumber.service;

public interface SmsConsumerService {
    void reviceMessage(String message);
}

package com.huyi.rabbitmq_consumber.service.Impl;

import com.huyi.rabbitmq_consumber.service.SmsConsumerService;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

@Component
//注意:这里要和生产者RabbitMqConfig文件中的名字对应起来
@RabbitListener(queues = {"sms.fanout.queue"})
public class SmsConsumerServiceImpl implements SmsConsumerService {

    @RabbitHandler
    public void reviceMessage(String message) {
        System.err.println("sms_fanout--接收到了订单信息");
    }
}

  • EmailConsumerService、EmailConsumerServiceImpl
package com.huyi.rabbitmq_consumber.service;

public interface EmailConsumerService {
    void reviceMessage(String message);
}

package com.huyi.rabbitmq_consumber.service.Impl;

import com.huyi.rabbitmq_consumber.service.EmailConsumerService;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

@Component
@RabbitListener(queues = {"email.fanout.queue"})
public class EmailConsumerServiceImpl implements EmailConsumerService {
    @RabbitHandler
    public void reviceMessage(String message) {
        System.err.println("Email_fanout--接收到了订单信息"+message);
    }
}

  • DuanxinConsumerService、DuanxinConsumerServiceImpl
package com.huyi.rabbitmq_consumber.service;

public interface DuanxinConsumerService {
    void reviceMessage(String message);
}

package com.huyi.rabbitmq_consumber.service.Impl;


import com.huyi.rabbitmq_consumber.service.DuanxinConsumerService;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;

@Component
@RabbitListener(queues = {"duanxin.fanout.queue"})
public class DuanxinConsumerServiceImpl implements DuanxinConsumerService {
    @RabbitHandler
    public void reviceMessage(String message) {
        System.err.println("Duanxin_fanout--接收到了订单信息"+message);
    }

}

9.启动消费者项目

10.启动生产者项目

11.查看消费者项目是否监听到了生产者的信息

  • SpringBoot集成RabbitMQ-Fanout项目编写成功
### Spring Boot 集成 RabbitMQ 交换机与队列的工厂初始化实现 在 Spring Boot 中,可以通过声明式的配置类来完成 RabbitMQ 的交换机、队列以及绑定关系的初始化。以下是具体的实现方式: #### 添加依赖 为了支持 RabbitMQ 功能,在项目的 `pom.xml` 文件中需引入以下 Maven 依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> ``` 此依赖会自动导入 RabbitMQ 所需的核心库和 Spring AMQP 支持[^2]。 #### 创建配置类 通过定义一个 Java 配置类,可以利用 Spring 提供的 Bean 定义机制来初始化交换机、队列及其绑定关系。下面是一个完整的示例代码: ```java import org.springframework.amqp.core.*; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class RabbitMqConfig { // 定义队列 @Bean public Queue myQueue() { return new Queue("my.queue", true, false, false); } // 定义交换机 @Bean public TopicExchange myExchange() { return new TopicExchange("my.exchange"); } // 绑定队列到交换机 @Bean public Binding binding(Queue myQueue, TopicExchange myExchange) { return BindingBuilder.bind(myQueue).to(myExchange).with("routing.key"); } } ``` 在此代码片段中,分别创建了一个持久化的队列 (`my.queue`) 和一个主题类型的交换机 (`my.exchange`) 并将其绑定在一起,指定路由键为 `"routing.key"`[^3]。 #### 工厂模式下的自定义初始化 如果需要更复杂的逻辑控制或者动态参数化,则可通过继承默认的工厂类来自定义行为。例如,重写 `DirectExchange`, `FanoutExchange`, 或者 `TopicExchange` 来满足特定业务场景的要求。 对于高级特性如 **死信队列 (DLQ)** ,也可以通过扩展的方式实现: ```java @Bean public Queue deadLetterQueue() { Map<String, Object> args = new HashMap<>(); args.put("x-dead-letter-exchange", "dlx.exchange"); // 死信转发的目标交换机名称 args.put("x-message-ttl", 60000); // 设置消息存活时间(ms),超时进入 DLX return new Queue("dead.letter.queue", true, false, false, args); } ``` 上述例子展示了如何基于参数化构造函数传递额外属性给队列实例,从而启用死信功能[^3]。 --- #### 性能优化建议 当面对高并发环境时,考虑调整线程池大小或预取计数等性能调优选项可能有助于提升吞吐量和服务稳定性。这些设置通常位于 application.properties/yml 文件下,比如: ```properties spring.rabbitmq.listener.simple.concurrency=5-10 spring.rabbitmq.listener.direct.prefetch=10 ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小狐狸崽子OvO

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

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

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

打赏作者

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

抵扣说明:

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

余额充值