SpringBoot從零整合RabbitMQ

今天簡單的搭建了RabbitMQ環(huán)境,并整合了SpringBoot,中間遇到了許多坑,總算搭建成功了。

RabbitMQ介紹

MQ全稱為Message Queue, 消息隊列(MQ)是一種應用程序?qū)贸绦虻耐ㄐ欧椒?。應用程序通過讀寫出入隊列的消息(針對應用程序的數(shù)據(jù))來通信,而無需專用連接來鏈接它們。消息傳遞指的是程序之間通過在消息中發(fā)送數(shù)據(jù)進行通信,而不是通過直接調(diào)用彼此來通信,直接調(diào)用通常是用于諸如遠程過程調(diào)用的技術(shù)。排隊指的是應用程序通過 隊列來通信。隊列的使用除去了接收和發(fā)送應用程序同時執(zhí)行的要求。RabbitMQ是消息中間件的一種,消息中間件即分布式系統(tǒng)中完成消息的發(fā)送和接收的基礎(chǔ)軟件.這些軟件有很多,包括ActiveMQ(apache公司的),RocketMQ(阿里巴巴公司的,現(xiàn)已經(jīng)轉(zhuǎn)讓給apache).

環(huán)境搭建

安裝RabbitMQ需要安裝Erlang開發(fā)環(huán)境,這一步是最坑的,因為版本問題,Erlang可能不兼容RabbiMQ,博主嘗試了許多版本終于安裝成功。相應的版本對應關(guān)系看這里。博主使用的rabbimq版本為3.7.9,Erlang版本為21.0.1。

安裝Erlang

官網(wǎng)或者下載博主的安裝包提取碼a0a2,下載完一步一步next就行,然后配置環(huán)境變量ERL_HOME,變量值D:\Program Files\erl10.0.1(你的安裝路徑),添加到path%ERL_HOME%\bin。打開控制臺輸入erl:

image.png
說明安裝成功

安裝rabbitmq

官網(wǎng)或者下載博主的安裝包提取碼8ozw,下載完安裝,一步步next下來就行。切換到安裝目錄的sbin目錄下,啟動rabbitmq-server.bat,

image.png
啟動成功后打開http://localhost:15672,輸入用戶名guest密碼guest登入管理臺。

創(chuàng)建消息生產(chǎn)者

新建SpringBoot項目rabbitmq-producer,添加依賴

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

修改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();
    }
}

創(chuàng)建一個發(fā)消息的業(yè)務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 ^_^");
    }

}

再創(chuàng)建一個運行發(fā)消息的線程

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();
    }
}

消息的生產(chǎn)者就寫好了

創(chuàng)建消息消費者

同樣新建SpringBoot項目rabbitmq-customer,配置文件

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

創(chuàng)建HelleService的接收者HelloServiceReceive

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

@Component
public class HelloServiceReceive {

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

啟動customer會發(fā)現(xiàn)報錯:

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

我們要先去管理端添加一個隊列,隊列名字要與監(jiān)聽器指定的相同


image.png

再次啟動customer和proucer,會發(fā)現(xiàn)customer接收到了producer發(fā)送的消息:
image.png

說明整合成功了
這只是一個簡單的demo,rabbitmq還有許多功能和特性待我去研究。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內(nèi)容