spring boot集成rabbitMQ:系列二

 

目录

RabbitMq实操direct方式

一、 在本地安装一个rabbitmq server:

二、 启动rabbitmq服务器:

三、 开启mq管理界面:http://localhost:15672/#/

四、 完成springboot项目中的代码和配置:

4.1 pom文件加入maven依赖

4.2 application加入全局配置

4.3 rabbitmq的config相关代码

4.4 生产者代码

4.5 消费者代码

4.6 测试代码


RabbitMq实操direct方式

一、 在本地安装一个rabbitmq server:

命令行输入brew install rabbitmq即可自动安装;如果提示需要手动先安装Erlang语言环境,可以命令行输入brew install erlang先安装Erlang;

二、 启动rabbitmq服务器:

在命令行终端输入/usr/local/Cellar/rabbitmq/3.7.14/sbin/rabbitmq-server start;

三、 开启mq管理界面:http://localhost:15672/#/

四、 完成springboot项目中的代码和配置:

4.1 pom文件加入maven依赖

<!-- 集成rabbitmq-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-amqp</artifactId>
            <version>2.1.4.RELEASE</version>
        </dependency>

4.2 application加入全局配置

#集成rabbitmq
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: guest
    password: guest
    virutalHost: /
    queue: spring-queue-async
    routingKey: spring-queue-async

4.3 rabbitmq的config相关代码

package org.maggiezhang.springbootdemo.common.mq;

import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
import org.springframework.amqp.rabbit.listener.api.ChannelAwareMessageListener;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

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

@Configuration
@Slf4j
public class RabbitConfig {

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

    @Value("${spring.rabbitmq.port}")
    private int port;

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

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

    /*direct类型的exchange*/
    public static final String EXCHANGE_DIRECT_A = "my-mq-exchange_direct_A";
    public static final String EXCHANGE_DIRECT_B = "my-mq-exchange_B";
    public static final String EXCHANGE_DIRECT_C = "my-mq-exchange_C";

    public static final String QUEUE_DIRECT_A = "QUEUE_DIRECT_A";
    public static final String QUEUE_DIRECT_B = "QUEUE_DIRECT_B";
    public static final String QUEUE_DIRECT_C = "QUEUE_DIRECT_C";

    public static final String ROUTINGKEY_A = "spring-boot-rootingKey_A";
    public static final String ROUTINGKEY_B = "spring-boot-rootingKey_B";
    public static final String ROUTINGKEY_C = "spring-boot-rootingKey_C";

    public static int count = 1;
    public static int getCount(){
        return ++count;
    }


    /*Topic类型的exchange*/

    @Bean
    public ConnectionFactory connectionFactory(){
        CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory();
        cachingConnectionFactory.setAddresses(host+":"+port);
        cachingConnectionFactory.setUsername(username);
        cachingConnectionFactory.setPassword(password);
        cachingConnectionFactory.setVirtualHost("/");
        cachingConnectionFactory.setPublisherConfirms(true);
        return cachingConnectionFactory;
    }

    @Bean
    @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
    public RabbitTemplate rabbitTemplate(){
        RabbitTemplate template=new RabbitTemplate((connectionFactory()));
        return template;
    }

    /**
     * 针对消费者配置
     * 1. 设置交换机类型
     * 2. 将队列绑定到交换机
     FanoutExchange: 将消息分发到所有的绑定队列,无routingkey的概念
     HeadersExchange :通过添加属性key-value匹配
     DirectExchange:按照routingkey分发到指定队列
     TopicExchange:多关键字匹配
     *
     * @return
     */
    @Bean
    public DirectExchange defaultExchangeA(){
        return new DirectExchange(EXCHANGE_DIRECT_A);
    }

    /**
     * 获取队列A
     * @return
     */
    @Bean
    public Queue queueA(){
        return new Queue(QUEUE_DIRECT_A, true);
    }

    /**
     * 获取队列B
     * @return
     */
    @Bean
    public Queue queueB(){
        return new Queue(QUEUE_DIRECT_B, true);
    }

    /**
     * routingkey_A using: exchange_A and queue_A
     * @return
     */
    @Bean
    public Binding binding(){
        return BindingBuilder.bind(queueA()).to(this.defaultExchangeA()).with(RabbitConfig.ROUTINGKEY_A);
    }

    /**
     * routingkey_B using: exchange_A and queue_A
     * @return
     */
    @Bean
    public Binding bindingA(){
        return BindingBuilder.bind(queueA()).to(this.defaultExchangeA()).with(RabbitConfig.ROUTINGKEY_B);
    }

    /**
     * routingkey_B using: exchange_A and queue_B
     * @return
     */
    @Bean
    public Binding bindingB(){
        return BindingBuilder.bind(queueB()).to(this.defaultExchangeA()).with(RabbitConfig.ROUTINGKEY_B);
    }

    /**
     * 接收message写法二:使用SimpleMessageListenerContainer
     *
     * */
    @Bean
    public SimpleMessageListenerContainer simpleMessageListenerContainer(){
        SimpleMessageListenerContainer simpleMessageListenerContainer = new SimpleMessageListenerContainer(connectionFactory());

        simpleMessageListenerContainer.setQueues(queueB());
        simpleMessageListenerContainer.setExposeListenerChannel(true);

        simpleMessageListenerContainer.setMaxConcurrentConsumers(10);

        simpleMessageListenerContainer.setConcurrentConsumers(2);

        simpleMessageListenerContainer.setAcknowledgeMode(AcknowledgeMode.MANUAL);

        //后置处理器,接收到的消息都添加了Header请求头
        /*simpleMessageListenerContainer.setAfterReceivePostProcessors(message -> {
            message.getMessageProperties().getHeaders().put("desc",10);
            return message;
        });
        //设置消费者的consumerTag_tag
        simpleMessageListenerContainer.setConsumerTagStrategy(queue -> "order_queue_"+(++count));
        //设置消费者的Arguments
        Map<String, Object> args = new HashMap<>();
        args.put("module","订单模块");
        args.put("fun","发送消息");
        simpleMessageListenerContainer.setConsumerArguments(args);*/

        simpleMessageListenerContainer.setMessageListener(new ChannelAwareMessageListener() {
            @Override
            public void onMessage(Message message, Channel channel) throws Exception {
                channel.basicQos(1);
                byte[] body=message.getBody();
                log.info("---------监听并处理队列B中的消息:"+new String(body));

                channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
            }
        });
        return simpleMessageListenerContainer;
    }


}

4.4 生产者代码

package org.maggiezhang.springbootdemo.common.mq;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Service;

import java.util.UUID;

@Slf4j
@Service
public class MsgProducerA implements RabbitTemplate.ConfirmCallback {


    //由于rabbitTemplate的scope属性设置为ConfigurableBeanFactory.SCOPE_PROTOTYPE,所以不能自动注入
    private RabbitTemplate rabbitTemplate;

    @Autowired
    public MsgProducerA(RabbitTemplate rabbitTemplate) {
        this.rabbitTemplate = rabbitTemplate;
        rabbitTemplate.setConfirmCallback(this);//rabbitTemplate如果为单例的话,那回调就是最后设置的内容
    }

    public void sendMsgWithRoutingkeyA(String content){//default is queueA
        CorrelationData correlationId = new CorrelationData(UUID.randomUUID().toString());
        //把消息放入ROUTINGKEY_A对应的队列当中去,对应的是队列A
        rabbitTemplate.convertAndSend(RabbitConfig.EXCHANGE_DIRECT_A, RabbitConfig.ROUTINGKEY_A, content, correlationId);
    }

    public void sendMsgWithRoutingkeyB(String content){
        CorrelationData correlationId = new CorrelationData(UUID.randomUUID().toString());
        //把消息放入ROUTINGKEY_B对应的队列当中去,对应的是队列A和队列B,所以队列A和队列B将会同时收到消息
        rabbitTemplate.convertAndSend(RabbitConfig.EXCHANGE_DIRECT_A, RabbitConfig.ROUTINGKEY_B, content, correlationId);
    }

    /**
     * 回调
     * @param correlationData
     * @param ack
     * @param cause
     */
    @Override
    public void confirm(@Nullable CorrelationData correlationData, boolean ack, @Nullable String cause) {
        log.info("回调id:"+correlationData);
        //log.info(correlationData.getReturnedMessage());
        if(ack){
            log.info("。。。消息成功消费");
        }else{
            log.info("。。。消息消费失败"+cause);
        }

    }
}

4.5 消费者代码

package org.maggiezhang.springbootdemo.common.mq;

import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.annotation.RabbitListeners;
import org.springframework.stereotype.Component;
/**
 * 接收message写法一:使用RabbitListener
 *
 * */
@Component
@RabbitListener(queues = RabbitConfig.QUEUE_DIRECT_A)
@Slf4j
public class MsgReceiverDirectQueueA {

    @RabbitHandler
    public void process(String content){
        log.info("接收处理队列A当中的消息:" + content);

    }



}

4.6 测试代码

package org.maggiezhang.springbootdemo.common;

import lombok.extern.slf4j.Slf4j;
import org.maggiezhang.springbootdemo.CaseBase;
import org.maggiezhang.springbootdemo.common.mq.MsgProducerA;
import org.maggiezhang.springbootdemo.common.mq.RabbitConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.testng.annotations.Test;

import java.util.Date;

@Slf4j
public class TestMsgProducerA extends CaseBase{

    @Autowired
    MsgProducerA msgProducerA;

    @Test
    public void testSend_DIRECTMsgA(){
        log.info("...testSendMsgA");//routingkey_A
        msgProducerA.sendMsgWithRoutingkeyA("这是A发送的消息"+ new Date());
        log.info("这是A发送的消息"+ new Date());
    }

    @Test
    public void testSend_DIRECTMsgB(){//routingkey_B
        log.info("...testSendMsgB");
        msgProducerA.sendMsgWithRoutingkeyB("这是B发送的消息"+ new Date());
        log.info("这是B发送的消息"+ new Date());
    }


}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring Boot 集成 RabbitMQ 是一种常见的实践,用于在基于 Spring Boot 的应用程序中集成消息队列系统,RabbitMQ 是一个开源的消息中间件,常用于分布式系统的解耦和异步通信。 下面是简单的集成步骤: 1. 添加依赖:首先,你需要在你的 Maven 或 Gradle 项目中添加 RabbitMQ 客户端的依赖。对于 Maven,可以在 `pom.xml` 中添加: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> ``` 对于 Gradle,添加到 `build.gradle` 文件的 `dependencies` 节点: ```groovy implementation 'org.springframework.boot:spring-boot-starter-amqp' ``` 2. 配置 RabbitMQ:在 application.properties 或者 application.yml 文件中配置 RabbitMQ 的连接信息,如主机名、端口号、用户名和密码等: ```properties spring.rabbitmq.host=localhost spring.rabbitmq.port=5672 spring.rabbitmq.username=admin spring.rabbitmq.password=password ``` 3. 创建消息生产者:使用 Spring 的 `RabbitTemplate` 类创建发送消息的方法,通常在服务中定义: ```java @Autowired private RabbitTemplate rabbitTemplate; public void sendMessage(String message) { rabbitTemplate.convertAndSend("queue-name", message); } ``` 4. 创建消息消费者:创建监听特定队列的消费者,可以是传统的 Java 接收器,也可以使用注解驱动(@RabbitListener)的方式: ```java @RabbitListener(queues = "queue-name") public void handleMessage(String message) { System.out.println("Received message: " + message); } ``` 5. 启动应用:运行 Spring Boot 应用,Spring Boot 自动会初始化 RabbitMQ 连接并注册你的消费者。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值