文章目錄
1 交換器
用來接收生產者發送的消息並將這些消息路由給服務器中的隊列。
三種常用的交換器類型:
direct
(發佈與訂閱 完全匹配)topic
(主題, 規則匹配)fanout
(廣播)
附
:這三個交換器都用這個座標
<!-- RabbitMQ的maven座標 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
1.1 Direct 交換器
Direct
交換器發佈與訂閱 完全匹配
1.1.1 使用需求
系統日誌處理場景
- 微服務產生的日誌,交給日誌處理器處理
- 日誌處理服務器有
2
個服務,分別爲info,error
- 服務的直接通信採用
direct
(發佈訂閱)
1.1.2 Consumer消費者
1.1.2.1 properties配置文件
# RabbitMQ的安裝地址
spring.rabbitmq.host=192.168.126.140
# RabbitMQ的訪問端口,和頁面的15672端口不一樣
spring.rabbitmq.port=5672
# RabbitMQ的用戶名
spring.rabbitmq.username=rabbitmq
# RabbitMQ的密碼
spring.rabbitmq.password=123456
####這些都是自定義的屬性名#######
# 設置交換器名稱
mq.config.exchange=log.direct
#設置info隊列名稱
mq.config.queue.info=log.info
#設置info路由名稱
mq.config.queue.info.routing.key=log.info.routing.key
#設置error隊列名稱
mq.config.queue.error=log.error
#設置error路由名稱
mq.config.queue.error.routing.key=log.error.routing.key
1.1.2.2 消費者實體類
@RabbitListener
- 屬性:
bindings
:綁定隊列 -
- 註解
@QueueBinding
- 註解
-
-
- 屬性:
value
:綁定隊列的名稱 (註解@Queue
:value
:配置隊列名稱,autoDelete
:是否是一個可刪除的臨時隊列)
- 屬性:
-
-
-
- 屬性:
exchange
:配置交換器(@Exchange
:value
·:爲交換器起個名稱,type
:指定具體的交換器類型)
- 屬性:
-
-
-
- 屬性:
key
:路由鍵
- 屬性:
-
@Component
@RabbitListener(
bindings =
@QueueBinding(value = @Queue(value = "${mq.config.queue.error}", autoDelete = "true"),
exchange = @Exchange(value = "${mq.config.exchange}", type = ExchangeTypes.DIRECT),
key = "${mq.config.queue.error.routing.key}")
)
public class ErrorReceiver {
/**
* 接收消息的方法 採用消息隊列監聽機制
*/
@RabbitHandler
public void process(String msg) {
System.out.println("error........." + msg);
}
}
1.1.3 Provider提供者
1.1.3.1 properties配置文件
# RabbitMQ的安裝地址
spring.rabbitmq.host=192.168.126.140
# RabbitMQ的訪問端口,和頁面的15672端口不一樣
spring.rabbitmq.port=5672
# RabbitMQ的用戶名
spring.rabbitmq.username=rabbitmq
# RabbitMQ的密碼
spring.rabbitmq.password=123456
##########此處的名字是自己隨意定義的############
# 設置交換器名稱
mq.config.exchange=log.direct
#設置info隊列名稱
mq.config.queue.info=log.info
#設置info路由名稱
mq.config.queue.info.routing.key=log.info.routing.key
#設置error隊列名稱
mq.config.queue.error=log.error
#設置error路由名稱
mq.config.queue.error.routing.key=log.error.routing.key
### 此處名字是rabbitmq的,不是自定義的,下面兩個屬性是爲了怕連不上,而設置的重試
# 是否打開重試次數
spring.rabbitmq.listener.simple.retry.enabled=true
# 設置rabbitmq最大重試次數
spring.rabbitmq.listener.simple.retry.max-attempts=5
1.1.3.2 生產消息實體
@Component
public class SenderDemo {
@Autowired
private AmqpTemplate template;
//交換器名稱
@Value("${mq.config.exchange}")
private String exchange;
//路由鍵
@Value("${mq.config.queue.info.routing.key}")
private String routingKey;
/**
* 發送消息
*/
public void send (String msg) {
//參數一:交換器名稱
//參數二:路由鍵名稱
//參數三:消息
this.template.convertAndSend(this.exchange,this.routingKey,msg);
}
}
1.1.3.3 測試類
@RunWith(SpringRunner.class)
@SpringBootTest(classes=AppAction.class)
public class TestSenderDemo {
@Autowired
private SenderDemo sender;
@Test
public void testSend() throws InterruptedException {
int flag=0;
while(true) {
flag++;
Thread.sleep(2000);
System.out.println(flag);
this.sender.send("Hello RabbitMQ============="+flag);
}
}
}
1.2 Topic 交換器
Topic
交換器,主題, 規則匹配,即模糊匹配
1.2.1 使用需求
1.2.2 Consumer消費者
1.2.2.1 properties配置文件
# RabbitMQ的安裝地址
spring.rabbitmq.host=192.168.126.140
# RabbitMQ的訪問端口,和頁面的15672端口不一樣
spring.rabbitmq.port=5672
# RabbitMQ的用戶名
spring.rabbitmq.username=rabbitmq
# RabbitMQ的密碼
spring.rabbitmq.password=123456
# 設置交換器名稱
mq.config.exchange=log.topic
#設置info隊列名稱
mq.config.queue.info=log.info
#設置error隊列名稱
mq.config.queue.error=log.error
#log 隊列名稱
mq.config.queue.logs=log.all
1.2.2.2 消費者實體類
@RabbitListener
- 屬性:
bindings
:綁定隊列 -
- 註解
@QueueBinding
- 註解
-
-
- 屬性:
value
:綁定隊列的名稱 (註解@Queue
:value
:配置隊列名稱,autoDelete
:是否是一個可刪除的臨時隊列)
- 屬性:
-
-
-
- 屬性:
exchange
:配置交換器(@Exchange
:value
·:爲交換器起個名稱,type
:指定具體的交換器類型)
- 屬性:
-
-
-
- 屬性:
key
:路由鍵
InfoReceiver.java
- 屬性:
-
@Component
@RabbitListener(
bindings=@QueueBinding(
value=@Queue(value="${mq.config.queue.info}",autoDelete="true"),
exchange=@Exchange(value="${mq.config.exchange}",type=ExchangeTypes.TOPIC),
key="*.log.info"
)
)
public class InfoReceiver {
/**
* 接收消息的方法。 採用消息隊列監聽機制
* @param msg
*/
@RabbitHandler
public void process(String msg){
System.out.println("......Info........receiver:"+msg);
}
ErrorReceiver.java
@Component
@RabbitListener(
bindings=@QueueBinding(
value=@Queue(value="${mq.config.queue.error}",autoDelete="true"),
exchange=@Exchange(value="${mq.config.exchange}",type=ExchangeTypes.TOPIC),
key="*.log.error"
)
)
public class ErrorReceiver {
@RabbitHandler
public void process(String msg){
System.out.println("......Error........receiver:"+msg);
}
}
LogsReceiver.java
@Component
@RabbitListener(
bindings=@QueueBinding(
value=@Queue(value="${mq.config.queue.logs}",autoDelete="true"),
exchange=@Exchange(value="${mq.config.exchange}",type=ExchangeTypes.TOPIC),
key="*.log.*"
)
)
public class LogsReceiver {
@RabbitHandler
public void process(String msg){
System.out.println("......All........receiver:"+msg);
}
}
1.2.3 Provider提供者
1.2.3.1 properties配置文件
# RabbitMQ的安裝地址
spring.rabbitmq.host=192.168.126.140
# RabbitMQ的訪問端口,和頁面的15672端口不一樣
spring.rabbitmq.port=5672
# RabbitMQ的用戶名
spring.rabbitmq.username=rabbitmq
# RabbitMQ的密碼
spring.rabbitmq.password=123456
#設置交換器的名稱
mq.config.exchange=log.topic
1.2.3.2 生產消息類實體
UserSender.java
@Component
public class UserSender {
@Autowired
private AmqpTemplate rabbitAmqpTemplate;
//exchange 交換器名稱
@Value("${mq.config.exchange}")
private String exchange;
/*
* 發送消息的方法
*/
public void send(String msg){
//向消息隊列發送消息
//參數一: 交換器名稱。
//參數二: 路由鍵
//參數三: 消息
this.rabbitAmqpTemplate.convertAndSend(this.exchange,"user.log.debug", "user.log.debug....."+msg);
this.rabbitAmqpTemplate.convertAndSend(this.exchange,"user.log.info", "user.log.info....."+msg);
this.rabbitAmqpTemplate.convertAndSend(this.exchange,"user.log.warn","user.log.warn....."+msg);
this.rabbitAmqpTemplate.convertAndSend(this.exchange,"user.log.error", "user.log.error....."+msg);
}
}
ProductSender
類
@Component
public class ProductSender {
@Autowired
private AmqpTemplate rabbitAmqpTemplate;
//exchange 交換器名稱
@Value("${mq.config.exchange}")
private String exchange;
/*
* 發送消息的方法
*/
public void send(String msg){
//向消息隊列發送消息
//參數一: 交換器名稱。
//參數二: 路由鍵
//參數三: 消息
this.rabbitAmqpTemplate.convertAndSend(this.exchange,"product.log.debug", "product.log.debug....."+msg);
this.rabbitAmqpTemplate.convertAndSend(this.exchange,"product.log.info","product.log.info....."+msg);
this.rabbitAmqpTemplate.convertAndSend(this.exchange,"product.log.warn","product.log.warn....."+msg);
this.rabbitAmqpTemplate.convertAndSend(this.exchange,"product.log.error", "product.log.error....."+msg);
}
}
OrderSender
@Component
public class OrderSender {
@Autowired
private AmqpTemplate rabbitAmqpTemplate;
//exchange 交換器名稱
@Value("${mq.config.exchange}")
private String exchange;
/*
* 發送消息的方法
*/
public void send(String msg){
//向消息隊列發送消息
//參數一: 交換器名稱。
//參數二: 路由鍵
//參數三: 消息
this.rabbitAmqpTemplate.convertAndSend(this.exchange,"order.log.debug", "order.log.debug....."+msg);
this.rabbitAmqpTemplate.convertAndSend(this.exchange,"order.log.info", "order.log.info....."+msg);
this.rabbitAmqpTemplate.convertAndSend(this.exchange,"order.log.warn","order.log.warn....."+msg);
this.rabbitAmqpTemplate.convertAndSend(this.exchange,"order.log.error", "order.log.error....."+msg);
}
}
測試方法同1.1.3.3
測試類,故不再贅述
1.3 Fanout 交換器
Fanout
交換器就是同步變異步,所有的隊列都要發送,因此不需要路由鍵了
1.3.1 需求
1.3.2 Consumer消費者
1.3.2.1 配置文件
# RabbitMQ的安裝地址
spring.rabbitmq.host=192.168.126.140
# RabbitMQ的訪問端口,和頁面的15672端口不一樣
spring.rabbitmq.port=5672
# RabbitMQ的用戶名
spring.rabbitmq.username=rabbitmq
# RabbitMQ的密碼
spring.rabbitmq.password=123456
#設置交換器的名稱
mq.config.exchange=order.fanout
#短信服務隊列名稱
mq.config.queue.sms=order.sms
#push 服務隊列名稱
mq.config.queue.push=order.push
1.3.2.2 消費者實體類
@RabbitListener
- 屬性:
bindings
:綁定隊列 -
- 註解
@QueueBinding
- 註解
-
-
- 屬性:
value
:綁定隊列的名稱 (註解@Queue
:value
:配置隊列名稱,autoDelete
:是否是一個可刪除的臨時隊列)
- 屬性:
-
-
-
- 屬性:
exchange
:配置交換器(@Exchange
:value
·:爲交換器起個名稱,type
:指定具體的交換器類型)
- 屬性:
-
-
-
- 屬性:
key
:路由鍵,因爲是廣播模式,所以不需要路由鍵
SmsReceiver.java
- 屬性:
-
@Component
@RabbitListener(
bindings=@QueueBinding(
value=@Queue(value="${mq.config.queue.sms}",autoDelete="true"),
exchange=@Exchange(value="${mq.config.exchange}",type=ExchangeTypes.FANOUT)
)
)
public class SmsReceiver {
@RabbitHandler
public void process(String msg){
System.out.println("Sms........receiver: "+msg);
}
}
PushReceiver.java
@Component
@RabbitListener(
bindings=@QueueBinding(
value=@Queue(value="${mq.config.queue.push}",autoDelete="true"),
exchange=@Exchange(value="${mq.config.exchange}",type=ExchangeTypes.FANOUT)
)
)
public class PushReceiver {
@RabbitHandler
public void process(String msg){
System.out.println("Push..........receiver: "+msg);
}
}
1.3.3 provider生產者
1.3.3.1 配置文件
# RabbitMQ的安裝地址
spring.rabbitmq.host=192.168.126.140
# RabbitMQ的訪問端口,和頁面的15672端口不一樣
spring.rabbitmq.port=5672
# RabbitMQ的用戶名
spring.rabbitmq.username=rabbitmq
# RabbitMQ的密碼
spring.rabbitmq.password=123456
#設置交換器的名稱
mq.config.exchange=order.fanout
1.3.3.2 生產者實體類
因爲是廣播模式,所以路由鍵是空字符串
@Component
public class Sender {
@Autowired
private AmqpTemplate rabbitAmqpTemplate;
//exchange 交換器名稱
@Value("${mq.config.exchange}")
private String exchange;
/*
* 發送消息的方法
*/
public void send(String msg){
//向消息隊列發送消息
//參數一: 交換器名稱。
//參數二: 路由鍵 因爲廣播模式,所以路由鍵是空字符串
//參數三: 消息
this.rabbitAmqpTemplate.convertAndSend(this.exchange,"",msg);
}
}
1.4 RabbitMQ的消息持久化處理
消息的可靠性是 RabbitMQ
的一大特色, 那麼 RabbitMQ
是如何保證消息可靠性的呢——消息持久化,主要通過在消息接收者上的註解@RabbitListener
修改內部屬性。
@Queue
屬性中的autoDelete
: 當所有消費客戶端連接斷開後, 是否自動刪除隊列true
: 刪除false
: 不刪除,默認爲空字符串@Exchange
屬性中的autoDelete
: 當所有綁定隊列都不在使用時, 是否自動刪除交換器true
: 刪除false
: 不刪除,默認爲false
如下爲@RabbitListener
的內部屬性:
- 屬性:
bindings
:綁定隊列 -
- 註解
@QueueBinding
- 註解
-
-
- 屬性:
value
:綁定隊列的名稱 (註解@Queue
:value
:配置隊列名稱,autoDelete
:是否是一個可刪除的臨時隊列)
- 屬性:
-
-
-
- 屬性:
exchange
:配置交換器(@Exchange
:value
·:爲交換器起個名稱,type
:指定具體的交換器類型)
- 屬性:
-
-
-
- 屬性:
key
:路由鍵
- 屬性:
-