Spring Boot系列教程之7步集成RabbitMQ的方法
前言
RabbitMQ是一種我們經(jīng)常使用的消息中間件,RabbitMQ是實(shí)現(xiàn)AMQP(高級(jí)消息隊(duì)列協(xié)議)的消息中間件的一種,最初起源于金融系統(tǒng),用于在分布式系統(tǒng)中存儲(chǔ)轉(zhuǎn)發(fā)消息,在易用性、擴(kuò)展性、高可用性等方面表現(xiàn)不俗。RabbitMQ主要是為了實(shí)現(xiàn)系統(tǒng)之間的雙向解耦而實(shí)現(xiàn)的。當(dāng)生產(chǎn)者大量產(chǎn)生數(shù)據(jù)時(shí),消費(fèi)者無(wú)法快速消費(fèi),那么需要一個(gè)中間層。保存這個(gè)數(shù)據(jù)。
AMQP,即Advanced Message Queuing Protocol,高級(jí)消息隊(duì)列協(xié)議,是應(yīng)用層協(xié)議的一個(gè)開(kāi)放標(biāo)準(zhǔn),為面向消息的中間件設(shè)計(jì)。消息中間件主要用于組件之間的解耦,消息的發(fā)送者無(wú)需知道消息使用者的存在,反之亦然。AMQP的主要特征是面向消息、隊(duì)列、路由(包括點(diǎn)對(duì)點(diǎn)和發(fā)布/訂閱)、可靠性、安全。
RabbitMQ是一個(gè)開(kāi)源的AMQP實(shí)現(xiàn),服務(wù)器端用Erlang語(yǔ)言編寫(xiě),支持多種客戶端,如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等,支持AJAX。用于在分布式系統(tǒng)中存儲(chǔ)轉(zhuǎn)發(fā)消息,在易用性、擴(kuò)展性、高可用性等方面表現(xiàn)不俗。
今天這篇,我們來(lái)看看Spring Boot是如何集成RabbitMQ,發(fā)送消息和消費(fèi)消息的。同時(shí)我們介紹下死信隊(duì)列。
集成RabbitMQ
集成RabbitMQ只需要如下幾步即可
1、添加maven依賴(lài)
<!--rabbitmq--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency>
2、添加配置文件application.yaml
在application.yaml添加配置內(nèi)容如下
spring: rabbitmq: host: 192.168.1.161 port: 5672 username: guest password: guest cache: channel: size: 10 listener: type: simple simple: acknowledge-mode: auto concurrency: 5 default-requeue-rejected: true max-concurrency: 100 retry: enabled: true # initial-interval: 1000ms max-attempts: 3 # max-interval: 1000ms multiplier: 1 stateless: true # publisher-confirms: true</pre>
注意:
這里最基本的配置只需要配置host,port,username和password四個(gè)屬性即可
其他屬性都有各自的含義,比如retry是用于配置重試策略的,acknowledge-mode是配置消息接收確認(rèn)機(jī)制的。
3、編寫(xiě)配置類(lèi)
編寫(xiě)RabbitConfig配置類(lèi),采用Java Configuration的方式配置RabbitTemplate、Exchange和Queue等信息,具體如下所示
package com.jackie.springbootdemo.config;
import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
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 public class RabbitMQConfig implements InitializingBean { @Autowired
SimpleRabbitListenerContainerFactory simpleRabbitListenerContainerFactory;
@Override
public void afterPropertiesSet() throws Exception {
simpleRabbitListenerContainerFactory.setMessageConverter(new Jackson2JsonMessageConverter());
} @Bean("jackson2JsonMessageConverter")
public Jackson2JsonMessageConverter jackson2JsonMessageConverter(ConnectionFactory connectionFactory) {
return new Jackson2JsonMessageConverter();
} @Bean("rabbitTemplate")
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory,
@Qualifier("jackson2JsonMessageConverter") Jackson2JsonMessageConverter jackson2JsonMessageConverter) {
RabbitTemplate template = new RabbitTemplate(connectionFactory);
template.setMessageConverter(new Jackson2JsonMessageConverter());
return template;
} // --------------------- 聲明隊(duì)列 ------------------------
@Bean
public Queue demoQueue() {
return new Queue("demo_queue");
} // --------------------- 聲明exchange ------------------------ @Bean
public DirectExchange demoExchange() {
return new DirectExchange("demo_exchange");
} // --------------------- 隊(duì)列綁定 ------------------------
@Bean
public Binding bindingAlbumItemCreatedQueue(DirectExchange demoExchange,
Queue demoQueue) {
return BindingBuilder.bind(demoQueue).to(demoExchange).with("100");
} }
注意
這里聲明了Direct模式的Exchange,聲明一個(gè)Queue,并通過(guò)routing-key為100將demo_queue綁定到demo_exchange,這樣demo_queue就可以接收到demo_exchange發(fā)送的消息了。
4、編寫(xiě)消息發(fā)送類(lèi)
package com.jackie.springbootdemo.message;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.support.CorrelationData;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component public class Sender implements RabbitTemplate.ConfirmCallback { private RabbitTemplate rabbitTemplate;
/**
* 構(gòu)造方法注入 */ @Autowired
public Sender(RabbitTemplate rabbitTemplate) {
this.rabbitTemplate = rabbitTemplate;
rabbitTemplate.setConfirmCallback(this); //rabbitTemplate如果為單例的話,那回調(diào)就是最后設(shè)置的內(nèi)容
} public void sendMsg(String content) {
rabbitTemplate.convertAndSend("demo_exchange", "100", content);
} /**
* 回調(diào) */ @Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
System.out.println(" 回調(diào)id:" + correlationData);
if (ack) {
System.out.println("消息成功消費(fèi)");
} else {
System.out.println("消息消費(fèi)失敗:" + cause);
}
} }
注意
發(fā)送內(nèi)容content,路由到routing-key為100上,則我們就可以在demo_queue隊(duì)列中看到發(fā)送的消息內(nèi)容了
confirm函數(shù)是回調(diào)函數(shù),這里因?yàn)闆](méi)有消費(fèi)者,且acknoledge-mode是auto(其他兩種值分別是none和manual),所以ack是false。
5、編寫(xiě)發(fā)送消息測(cè)試類(lèi)
package com.jackie.springbootdemo;
import com.jackie.springbootdemo.message.Sender;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.web.WebAppConfiguration;
@RunWith(SpringRunner.class) @SpringBootTest(classes = SpringbootDemoApplication.class) @WebAppConfiguration public class RabbitApplicationTests { @Autowired
Sender sender;
@Test
public void contextLoads() throws Exception {
sender.sendMsg("test");
} }
運(yùn)行該測(cè)試類(lèi),我們可以看到如下結(jié)果

6、編寫(xiě)消息消費(fèi)類(lèi)
package com.jackie.springbootdemo.message;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
@Component public class Receiver { @RabbitListener(queues = "demo_queue")
public void created(String message) {
System.out.println("orignal message: " + message);
} }
注意
消息消費(fèi)類(lèi)也非常簡(jiǎn)單,添加注解@RabbitListener,指定要監(jiān)聽(tīng)的隊(duì)列名稱(chēng)即可
除了注解@RabbitListener,我們經(jīng)常還能看到@RabbitHandler,這兩個(gè)注解可以配合起來(lái)使用。
@RabbitListener 標(biāo)注在類(lèi)上面表示當(dāng)有收到消息的時(shí)候,就交給 @RabbitHandler 的方法處理,具體使用哪個(gè)方法處理,根據(jù) MessageConverter 轉(zhuǎn)換后的參數(shù)類(lèi)型,形如
@RabbitListener(queues = "demo_queue") public class Receiver { @RabbitHandler public void processMessage1(String message) {
System.out.println(message);
} @RabbitHandler
public void processMessage2(byte[] message) {
System.out.println(new String(message));
} }
7、運(yùn)行消息發(fā)送測(cè)試類(lèi)

從執(zhí)行結(jié)果可以看到,因?yàn)橛辛讼M(fèi)者,所以這次打印的結(jié)果是"消息消費(fèi)成功"
而且,我們看到Receiver類(lèi)將消息消費(fèi)并打印出消息的內(nèi)容為"test"。
代碼已經(jīng)提交至項(xiàng)目rome:https://github.com/DMinerJackie/rome (本地下載)
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
- RabbitMQ 3.9.7 鏡像模式集群與Springboot 2.5.5 整合
- SpringAMQP消息隊(duì)列(SpringBoot集成RabbitMQ方式)
- 一文掌握Springboot集成RabbitMQ的方法
- springboot2.5.6集成RabbitMq實(shí)現(xiàn)Topic主題模式(推薦)
- Springboot集成RabbitMQ死信隊(duì)列的實(shí)現(xiàn)
- SpringBoot集成RabbitMQ的方法(死信隊(duì)列)
- springboot2.0集成rabbitmq的示例代碼
- springboot集成rabbitMQ之對(duì)象傳輸?shù)姆椒?/a>
- spring boot集成rabbitmq的實(shí)例教程
- 詳解spring boot集成RabbitMQ
- Spring Boot 3 集成 RabbitMQ 實(shí)踐指南(原理解析)
相關(guān)文章
基于Java判斷網(wǎng)絡(luò)是否正常代碼實(shí)例
這篇文章主要介紹了基于Java判斷網(wǎng)絡(luò)是否正常代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03
Java?Spring?boot實(shí)現(xiàn)生成二維碼
大家好,本篇文章主要講的是Java?Spring?boot實(shí)現(xiàn)生成二維碼,感興趣的同學(xué)趕快來(lái)看一看吧,對(duì)你有幫助的話記得收藏一下2022-02-02
SpringBoot中Mybatis + Druid 數(shù)據(jù)訪問(wèn)的詳細(xì)過(guò)程
Spring Boot 底層都是采用 SpringData 的方式進(jìn)行統(tǒng)一處理各種數(shù)據(jù)庫(kù),SpringData也是Spring中與SpringBoot、SpringCloud 等齊名的知名項(xiàng)目,下面看下SpringBoot Mybatis Druid數(shù)據(jù)訪問(wèn)的詳細(xì)過(guò)程,感興趣的朋友一起看看吧2021-11-11
java通過(guò)ssh連接服務(wù)器執(zhí)行shell命令詳解及實(shí)例
這篇文章主要介紹了java通過(guò)ssh連接服務(wù)器執(zhí)行shell命令詳解及實(shí)例方法的相關(guān)資料2017-02-02
SpringBoot整合mybatisplus和druid的示例詳解
這篇文章主要介紹了SpringBoot整合mybatisplus和druid的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-08-08
SpringBoot實(shí)現(xiàn)redis延遲隊(duì)列的示例代碼
延時(shí)隊(duì)列場(chǎng)景在我們?nèi)粘I(yè)務(wù)開(kāi)發(fā)中經(jīng)常遇到,它是一種特殊類(lèi)型的消息隊(duì)列,本文就來(lái)介紹一下SpringBoot實(shí)現(xiàn)redis延遲隊(duì)列的示例代碼,具有一定的參考價(jià)值,感興趣的可以了解一下2024-02-02

