RabbitMQ常用3種交換器詳解

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:綁定隊列的名稱 (註解@Queuevalue:配置隊列名稱,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:綁定隊列的名稱 (註解@Queuevalue:配置隊列名稱,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:綁定隊列的名稱 (註解@Queuevalue:配置隊列名稱,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修改內部屬性。

  1. @Queue屬性中的autoDelete: 當所有消費客戶端連接斷開後, 是否自動刪除隊列 true: 刪除 false: 不刪除,默認爲空字符串
  2. @Exchange屬性中的autoDelete: 當所有綁定隊列都不在使用時, 是否自動刪除交換器true: 刪除 false: 不刪除,默認爲false

如下爲@RabbitListener 的內部屬性:

  • 屬性:bindings:綁定隊列
    • 註解@QueueBinding
      • 屬性:value:綁定隊列的名稱 (註解@Queuevalue:配置隊列名稱,autoDelete:是否是一個可刪除的臨時隊列)
      • 屬性:exchange:配置交換器(@Exchange :value·:爲交換器起個名稱,type:指定具體的交換器類型)
      • 屬性:key:路由鍵
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章