SpringBoot 使用 spring-boot-starter-amqp 起步依赖实现 RabbitMQ 代码示例(二)


RabbitMQ
本文是工作之余的随手记,记录在工作期间使用 RabbitMQ 的笔记。



1、实现方式说明

SpringBoot 使用 spring-boot-starter-amqp 起步依赖实现 RabbitMQ 代码示例(一)

本文是承接上文,使用以下方式实现 RabbitMQ 功能。

  • 发送消息有多种解决方式,本文使用注入 RabbitTemplate,直接调用 convertAndSend 方法发送消息,支持自动消息转换(如 JSON 序列化)。
  • 消费消息有多种解决方式,本文在方法上使用 @RabbitListener 注解监听队列,支持消息体自动反序列化为对象。

1、实现代码结构如下:

实现代码结构


2、交换机

交换机


3、队列和路由键绑定
队列和路由键绑定


2、配置文件:application.yml

server:
  port: 8089

#开发站
spring:
  rabbitmq:
    host: 10.106.18.54
    port: 5672
    username: root
    password: 123456789
    listener:
      type: direct
      direct:
        prefetch: 250
        concurrency: 16 # 消费线程池核心线程数
        max-concurrency: 32 # 消费线程池最大线程数
        acknowledge-mode: auto # 自动确认消息
    exchangeRjwTest: 'sync.ex.rjw.test'
    queueRjwTest: 'ha.queue.rjw.test'
    routeRjwTest: 'route.rjw.test'

3、依赖文件:pom.xml

<parent>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-parent</artifactId>
	<version>3.4.1</version>
	<relativePath/> <!-- lookup parent from repository -->
</parent>

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

4、配置类:RabbitMQConfig

package com.wen.rabbit.config;

import lombok.Data;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author : rjw
 * @date : 2025-07-07
 */
@Configuration
@Data
public class RabbitMQConfig {

    @Value("${spring.rabbitmq.exchangeRjwTest}")
    private String exchangeRjwTest;

    @Value("${spring.rabbitmq.queueRjwTest}")
    private String queueRjwTest;

    @Value("${spring.rabbitmq.routeRjwTest}")
    private String routeRjwTest;

    @Bean
    public DirectExchange exchangeRjwTest() {
        return new DirectExchange(exchangeRjwTest);
    }

    @Bean
    public Queue queueRjwTest() {
        return new Queue(queueRjwTest);
    }

    @Bean
    public Binding bindingRjwTest01() {
        return BindingBuilder.bind(queueRjwTest()).to(exchangeRjwTest()).with(routeRjwTest);
    }

}

5、消息类:MQEntity

package com.wen.rabbit.model;

import com.alibaba.fastjson.JSONObject;
import lombok.Data;

/**
 * @author : rjw
 * @date : 2025-07-07
 */
@Data
public class MQEntity<T> {

    private String type;

    private long tm;

    private int crmId;

    private String who;

    private boolean requeue;

    private T data;

    private JSONObject attachments;

}

6、消息类:TestEntity

package com.wen.rabbit.model;

import lombok.Data;

/**
 * @author : rjw
 * @date : 2025-07-07
 */
@Data
public class TestEntity {

    private String name;

    private Integer age;

    private String sex;

}

7、MQ客户端:MQClient

package com.wen.rabbit.service;

import com.wen.rabbit.config.RabbitMQConfig;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;

/**
 * @author : rjw
 * @date : 2025-07-07
 */
@Service
@Slf4j
public class MQClient {

    @Resource
    private RabbitTemplate rabbitTemplate;

    @Resource
    private RabbitMQConfig rabbitMQConfig;

    public boolean send(String exchange, String routingKey, Object message) {
        try {
            rabbitTemplate.convertAndSend(exchange, routingKey, message);
            return true;
        } catch (AmqpException e) {
            log.error("fail, exchange:{}, routingKey:{}, message:{}, exception:{}",
                    exchange, routingKey, message, e.toString());
            return false;
        }
    }

}

8、事件抽象接口:MqEvent

package com.wen.rabbit.service;

import java.util.List;

/**
 * @author : rjw
 * @date : 2025-07-07
 */
public interface MqEvent<T> {

    /**
     * 获取MQ的路由主键
     * @return
     */
    public String getRoutingKey();

    /**
     * 获取数据
     * @return
     */
    public List<T> getData();

}

9、事件类:MqEventTest

package com.wen.rabbit.service;

import com.wen.rabbit.model.TestEntity;
import lombok.Getter;

import java.util.List;

/**
 * @author : rjw
 * @date : 2025-07-07
 */
@Getter
public class MqEventTest implements MqEvent {

    private String routeKey;

    private final List<TestEntity> data;

    public MqEventTest(String routeKey, List<TestEntity> data) {
        this.routeKey = routeKey;
        this.data = data;
    }

    @Override
    public String getRoutingKey() {
        return this.routeKey;
    }

    @Override
    public List<TestEntity> getData() {
        return this.data;
    }
}

10、发布者:MQPublisher

package com.wen.rabbit.service;

import com.alibaba.fastjson.JSON;
import com.wen.rabbit.config.RabbitMQConfig;
import com.wen.rabbit.model.MQEntity;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * @author : rjw
 * @date : 2025-07-07
 */
@Component
public class MQPublisher {

    @Autowired
    private MQClient mqClient;

    @Autowired
    private RabbitMQConfig mqConfig;

    public void publish(MqEvent mqEvent) {
        MQEntity<List> mqEntity = new MQEntity<>();
        mqEntity.setTm(System.currentTimeMillis());
        mqEntity.setData(mqEvent.getData());
        mqEntity.setWho("one");
        mqEntity.setRequeue(false);
        mqClient.send(mqConfig.getExchangeRjwTest(), mqEvent.getRoutingKey(), JSON.toJSONBytes(mqEntity));
    }
}

11、监听者(消费者):DataListener

package com.wen.rabbit;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.TypeReference;
import com.rabbitmq.client.Channel;
import com.wen.rabbit.model.MQEntity;
import com.wen.rabbit.model.TestEntity;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.List;

/**
 * @author : rjw
 * @date : 2025-07-07
 */
@Component
@Slf4j
public class DataListener {

    @RabbitListener(queues = {"${spring.rabbitmq.queueRjwTest}"}, concurrency = "1", ackMode = "MANUAL")
    public void dataListenerEvent(Message message, Channel channel) throws IOException {
        long deliveryTag = message.getMessageProperties().getDeliveryTag();
        String consumerQueue = message.getMessageProperties().getConsumerQueue();

        try {
            byte[] body = message.getBody();
            String jsonBody = new String(body, StandardCharsets.UTF_8);
            MQEntity<List<TestEntity>> mqEntity = JSON.parseObject(jsonBody, new TypeReference<>() {
            });
            log.info("接收到的MQ消息是: {}", mqEntity.toString());
            channel.basicAck(deliveryTag, false);
        } catch (JSONException e) {
            log.error("parse mq msg exception, queue:{}, deliveryTag:{}", consumerQueue, deliveryTag, e);
            channel.basicReject(deliveryTag, false);
        } catch (RuntimeException e) {
            log.error("handle mq msg exception, queue:{}, deliveryTag:{}", consumerQueue, deliveryTag, e);
            channel.basicReject(deliveryTag, false);    //为true会重新放回队列
        }
    }
    
}

12、生产者:DataProducer

package com.wen.rabbit;

import com.alibaba.fastjson.JSON;
import com.wen.rabbit.config.RabbitMQConfig;
import com.wen.rabbit.model.TestEntity;
import com.wen.rabbit.service.MQPublisher;
import com.wen.rabbit.service.MqEventTest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * @author : rjw
 * @date : 2025-07-07
 */
@Slf4j
@Component
@EnableScheduling
public class DataProducer {

    @Autowired
    private MQPublisher publisher;

    @Autowired
    private RabbitMQConfig mqConfig;

    @Scheduled(cron = "0 0/1 * * * ?")
    public void createDataJob() {
        log.info("生产者生成数据开始-----");
        for (int i = 0; i < 20; i++) {
            TestEntity testEntity = new TestEntity();
            testEntity.setName("Jack" + i);
            testEntity.setAge(20 + i);
            testEntity.setSex(i % 2 == 0 ? "man" : "woman");
            publisher.publish(new MqEventTest(mqConfig.getRouteRjwTest(), List.of(testEntity)));
            log.info("消息数据:{}", JSON.toJSONString(new MqEventTest(mqConfig.getRouteRjwTest(), List.of(testEntity))));
        }
        log.info("生产者生成数据结束=====");
    }

}

注意:本文是使用 SpringBoot 项目为核心进行开发,所使用的依赖和类都如上展示,可以应用于基本业务逻辑。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值