SpringBoot从零整合RabbitMQ

今天简单的搭建了RabbitMQ环境,并整合了SpringBoot,中间遇到了许多坑,总算搭建成功了。

RabbitMQ介绍

MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法。应用程序通过读写出入队列的消息(针对应用程序的数据)来通信,而无需专用连接来链接它们。消息传递指的是程序之间通过在消息中发送数据进行通信,而不是通过直接调用彼此来通信,直接调用通常是用于诸如远程过程调用的技术。排队指的是应用程序通过 队列来通信。队列的使用除去了接收和发送应用程序同时执行的要求。RabbitMQ是消息中间件的一种,消息中间件即分布式系统中完成消息的发送和接收的基础软件.这些软件有很多,包括ActiveMQ(apache公司的),RocketMQ(阿里巴巴公司的,现已经转让给apache).

环境搭建

安装RabbitMQ需要安装Erlang开发环境,这一步是最坑的,因为版本问题,Erlang可能不兼容RabbiMQ,博主尝试了许多版本终于安装成功。相应的版本对应关系看这里。博主使用的rabbimq版本为3.7.9,Erlang版本为21.0.1。

安装Erlang

去官网或者下载博主的安装包提取码a0a2,下载完一步一步next就行,然后配置环境变量ERL_HOME,变量值D:\Program Files\erl10.0.1(你的安装路径),添加到path%ERL_HOME%\bin。打开控制台输入erl:

image.png
说明安装成功

安装rabbitmq

去官网或者下载博主的安装包提取码8ozw,下载完安装,一步步next下来就行。切换到安装目录的sbin目录下,启动rabbitmq-server.bat,

image.png
启动成功后打开http://localhost:15672,输入用户名guest密码guest登入管理台。

创建消息生产者

新建SpringBoot项目rabbitmq-producer,添加依赖

        
            org.springframework.boot
            spring-boot-starter-amqp
        

修改application.yml配置文件

server:
  port: 8081
spring:
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest

新建配置类ProducerConf

import com.rabbitmq.client.impl.AMQImpl.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ProducerConf {

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

创建一个发消息的业务HelloService

import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class HelloService {

    @Autowired
    private AmqpTemplate template;

    public void send () {
        template.convertAndSend("queue","hey, boys ^_^");
    }

}

再创建一个运行发消息的线程

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;

@Component
public class HelloServiceRunner implements ApplicationRunner {

    @Autowired
    private HelloService service;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        new Thread(() -> {
            while (true) {
                service.send();
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}

消息的生产者就写好了

创建消息消费者

同样新建SpringBoot项目rabbitmq-customer,配置文件

server:
  port: 8082
spring:
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest

创建HelleService的接收者HelloServiceReceive

import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
public class HelloServiceReceive {

    @RabbitListener(queues="queue")    //监听器监听指定的Queue
    public void process(String str) {
        System.out.println("Receive:"+str);
    }
}

启动customer会发现报错:

org.springframework.amqp.rabbit.listener.BlockingQueueConsumer$DeclarationException: Failed to declare queue(s):[queue]
    at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.attemptPassiveDeclarations(BlockingQueueConsumer.java:710) [spring-rabbit-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.passiveDeclarations(BlockingQueueConsumer.java:594) [spring-rabbit-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.start(BlockingQueueConsumer.java:581) [spring-rabbit-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.initialize(SimpleMessageListenerContainer.java:1196) [spring-rabbit-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer$AsyncMessageProcessingConsumer.run(SimpleMessageListenerContainer.java:1041) [spring-rabbit-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at java.lang.Thread.run(Thread.java:748) [na:1.8.0_201]
Caused by: java.io.IOException: null
    at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:126) ~[amqp-client-5.4.3.jar:5.4.3]
    at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:122) ~[amqp-client-5.4.3.jar:5.4.3]
    at com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:144) ~[amqp-client-5.4.3.jar:5.4.3]
    at com.rabbitmq.client.impl.ChannelN.queueDeclarePassive(ChannelN.java:1006) ~[amqp-client-5.4.3.jar:5.4.3]
    at com.rabbitmq.client.impl.ChannelN.queueDeclarePassive(ChannelN.java:52) ~[amqp-client-5.4.3.jar:5.4.3]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_201]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_201]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_201]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_201]
    at org.springframework.amqp.rabbit.connection.CachingConnectionFactory$CachedChannelInvocationHandler.invoke(CachingConnectionFactory.java:1110) ~[spring-rabbit-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    at com.sun.proxy.$Proxy64.queueDeclarePassive(Unknown Source) ~[na:na]
    at org.springframework.amqp.rabbit.listener.BlockingQueueConsumer.attemptPassiveDeclarations(BlockingQueueConsumer.java:689) [spring-rabbit-2.1.4.RELEASE.jar:2.1.4.RELEASE]
    ... 5 common frames omitted

我们要先去管理端添加一个队列,队列名字要与监听器指定的相同


image.png

再次启动customer和proucer,会发现customer接收到了producer发送的消息:
image.png

说明整合成功了
这只是一个简单的demo,rabbitmq还有许多功能和特性待我去研究。

你可能感兴趣的:(SpringBoot从零整合RabbitMQ)