Springboot集成RabbitMQ

前面我们已经了解了RabbitMQ的一些基本概念和原理,今天进入实战篇,在springboot框架中集成RabbitMQ,默认已经创建一个Springboot项目。

添加pom依赖

在pom.xml文件中引入以下依赖:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-amqp</artifactId>
	<version>${springboot.version}</version>
</dependency>

修改application.yml文件

在application.yml文件中添加以下配置:

spring:
  rabbitmq:
    addresses: 127.0.0.1:5672
    username: lzm
    password: lzm
    virtual-host: test

address是rabbitmq server的请求地址,5672为其默认的端口号,集群多个地址时可以使用逗号隔开
username:rabbitmq用户名
password: rabbitmq密码
virtual-host: 虚拟主机

以上配置是集成rabbitmq最基本的配置,如果要使用更多的配置,比如配置手动ack,消息发送confirm等属性,可以参考org.springframework.boot.autoconfigure.amqp.RabbitProperties类中的默认配置

声明一个队列

我们写一个配置类,在配置类中声明一个队列,也可以通过访问RabbitMQ的管理页面http://IP:15672手动创建一个队列,此处使用代码去声明一个队列,底层使用RabbitAdmin在Rabbit Server中创建队列。

import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

/**
 * @author lzm
 * @date 2020/7/22 22:45
 */
@Component
public class RabbitConfig {

    /**
     * 定义一个可持久化的队列
     * @return
     */
    @Bean
    public Queue firstQueue(){
        return new Queue(Constant.MY_FIRST_QUEUE_NAME,true,false,false);
    }
}

上述代码声明了一个可持久化的队列,创建队列时的四个参数解释如下:

name: 队列名称
durable: 为true时表示是可持久化的队列,即使rabbitmq服务重启以后,队列依然是存在的
exclusive: 为true时表示只能被定义该queue的连接使用,一旦这个连接关闭,队列也会跟着删除
autoDelete: 为true时表示当没有消费者再使用queue时,queue自动删除

添加以上代码后,启动springboot项目后就可以在RabbitMQ的管理界面看到我们定义的队列:

生产者

生产者向消息队列中发送消息,我们创建一个service,在service中实现发送数据的逻辑:

import com.lzm.rabbitmq.constant.Constant;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;

/**
 * @author lzm
 * @date 2020/7/22 23:00
 */
@Service
public class ProducerService {

    /**
     * 注入rabbit模板
     */
    @Resource
    private RabbitTemplate rabbitTemplate;

    public void produceMessage(){

        for (int i = 0; i < 10; i++) {
            rabbitTemplate.convertAndSend(Constant.MY_FIRST_QUEUE_NAME, "我是消息====>"+i);
        }
    }
}

上述代码中,首先向service中注入了RabbitTemplate,然后调用template的convertAndSend方法,闯入队列名称和消息内容后即可将消息发送到前面创建的队列中。

我们写一个controller用以调用service代码生产消息:

@RestController
@Slf4j
@RequestMapping("/")
public class IndexController {

    @Resource
    private ProducerService producerService;

    @GetMapping(value = "index")
    public String sendMessage(){
        producerService.produceMessage();
        return "消息已发送,请查看消息队列";
    }
}

启动tomcat,访问http://127.0.0.1:79999/index方法后,查看rabbitmq管理界面中队列中的数据如下所示:

可以看到此时队列中共有10条数据,且10条数据都处理ready状态,添加消费者后即可消息处于ready状态的数据,可以点进队列中,查看队列中的详细数据,如下所示:

通过Get Message面板可以查看当前队列中的消息,不仅可以看到消息体,还可以看到消息头,比如Wxchange是默认的交换机,Routing Key与队列名称相同,以及消息的优先级(priority),是否持久化(delivery_model)等各项内容

消费者

前面生产者已经将消息发送到消息队列中,此时需要创建一个消费者对队列中的数据进行消费,创建消费者的代码如下所示:

import com.lzm.rabbitmq.constant.Constant;
import com.rabbitmq.client.Channel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

/**
 * 消费者示例代码
 * @author lzm
 * @date 2020/7/22 23:26
 */
@Component
@Slf4j
public class MyConsumer {

    @RabbitHandler
    @RabbitListener(queues = { Constant.MY_FIRST_QUEUE_NAME})
    public void consumeMessage(String msg, Channel channel, Message message){
        log.debug(msg);
    }
}

启动项目后控制台打印效果:

可以看到此时消费端将队列中的全部消息都消费掉了,此时队列中是没有消息的。

注解解释:

@RabbitHandler 添加到方法上,用来处理特定类型的消息
@RabbitListener 可以添加到方法上,也可以添加到类上,该注解方法中最重要的属性是queues,即当前消费者从哪些队列中消费消息,该注解还有很多属性,比如绑定(bindings)、containerFactory、优先级(priority)等多个属性,可以根据实际需要进行配置

总结

通过以上配置即可在springboot中初步集成Rabbitmq,但是上述的集成只是简单的能够发送消息,但是并不能保证生产端发送的消息消费端一定可以接收到,对于分布式消息队列需要的消息投递的可靠性一点都没有涉及,下一篇将介绍Rabbitmq是如何实现消息的可靠投递的。

posted @ 2020-09-18 14:08  一步一年  阅读(1293)  评论(0编辑  收藏  举报