今天簡單的搭建了RabbitMQ環(huán)境奥此,并整合了SpringBoot,中間遇到了許多坑雁比,總算搭建成功了稚虎。
RabbitMQ介紹
MQ全稱為Message Queue, 消息隊(duì)列(MQ)是一種應(yīng)用程序?qū)?yīng)用程序的通信方法。應(yīng)用程序通過讀寫出入隊(duì)列的消息(針對應(yīng)用程序的數(shù)據(jù))來通信偎捎,而無需專用連接來鏈接它們蠢终。消息傳遞指的是程序之間通過在消息中發(fā)送數(shù)據(jù)進(jìn)行通信,而不是通過直接調(diào)用彼此來通信茴她,直接調(diào)用通常是用于諸如遠(yuǎn)程過程調(diào)用的技術(shù)寻拂。排隊(duì)指的是應(yīng)用程序通過 隊(duì)列來通信。隊(duì)列的使用除去了接收和發(fā)送應(yīng)用程序同時(shí)執(zhí)行的要求丈牢。RabbitMQ是消息中間件的一種,消息中間件即分布式系統(tǒng)中完成消息的發(fā)送和接收的基礎(chǔ)軟件.這些軟件有很多,包括ActiveMQ(apache公司的),RocketMQ(阿里巴巴公司的,現(xiàn)已經(jīng)轉(zhuǎn)讓給apache).
環(huán)境搭建
安裝RabbitMQ需要安裝Erlang開發(fā)環(huán)境祭钉,這一步是最坑的,因?yàn)榘姹締栴}己沛,Erlang可能不兼容RabbiMQ慌核,博主嘗試了許多版本終于安裝成功。相應(yīng)的版本對應(yīng)關(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:
安裝rabbitmq
去官網(wǎng)或者下載博主的安裝包提取碼8ozw,下載完安裝蒙挑,一步步next下來就行宗侦。切換到安裝目錄的sbin目錄下,啟動(dòng)rabbitmq-server.bat忆蚀,
創(chuàng)建消息生產(chǎn)者
新建SpringBoot項(xiàng)目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)建一個(gè)發(fā)消息的業(yè)務(wù)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)建一個(gè)運(yùn)行發(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)建消息消費(fèi)者
同樣新建SpringBoot項(xiàng)目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);
}
}
啟動(dòng)customer會發(fā)現(xiàn)報(bào)錯(cuò):
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
我們要先去管理端添加一個(gè)隊(duì)列,隊(duì)列名字要與監(jiān)聽器指定的相同
再次啟動(dòng)customer和proucer欣鳖,會發(fā)現(xiàn)customer接收到了producer發(fā)送的消息:
說明整合成功了
這只是一個(gè)簡單的demo察皇,rabbitmq還有許多功能和特性待我去研究。