系列文章(更新ing):
「 從0到1學習微服務SpringCloud 」01 一起來學呀! 「 從0到1學習微服務SpringCloud 」02 Eureka服務註冊與發現
「 從0到1學習微服務SpringCloud 」03 Eureka的自我保護機制
「 從0到1學習微服務SpringCloud 」04服務消費者Ribbon+RestTemplate
「 從0到1學習微服務SpringCloud 」05消費者Fegin
「 從0到1學習微服務SpringCloud 」06 統一配置中心Spring Cloud Config
在上篇文章中,我們已經用到了MQ,用於實現配置自動刷新。接下來,就具體說說MQ的應用場景以及RabbtMq的基本使用。
MQ應用場景
-
異步處理
比如用戶註冊之後,需要加積分和發短信。就可以在用戶信息入庫後,通過異步消息讓積分服務和短信服務做它們的事,用戶無需等待這個過程,從而提高用戶體驗。
-
流量削峯
最常見的是秒殺場景,一般會因爲流量暴增,甚至應用掛掉。爲解決這種情況,需要在應用前端加入消息隊列。服務器接收用戶的請求後,首先寫入消息隊列。假如消息隊列長度超過最大數量,則直接拋棄用戶請求或跳轉到錯誤頁面。
-
日誌處理
最典型的就是kafka,kafka最初的設計就是爲了日誌處理,大數據裏用得特別多。通過日誌採集,定時寫入kafka隊列,然後kafka對日誌進行接收,儲存和轉發
-
應用解耦
比如用戶下單後,訂單系統需要通知庫存系統。傳統的做法是,訂單系統調用庫存系統的接口。但假如庫存系統無法訪問,則訂單減庫存將失敗,從而導致訂單失敗,訂單系統與庫存系統耦合。引入應用消息隊列後,用戶下單後,訂單系統完成持久化處理,將消息寫入消息隊列,返回用戶訂單下單成功,庫存系統閱下單的消息,進行庫存操作。在下單時庫存系統不能正常使用。也不影響正常下單,因爲下單後,訂單系統寫入消息隊列就不再關心其他的後續操作了。實現訂單系統與庫存系統的應用解耦
-
消息通訊
消息通訊是指,消息隊列一般都內置了高效的通信機制,因此也可以用在純的消息通訊。比如實現點對點消息隊列,或者聊天室等
基本使用
繼續使用eureka-client項目
1.添加maven
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
2.添加配置
spring:
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
3.Mq接收-發送
有3種接收方式,我這裏爲了方便,在同一個應用中寫的發送和接收,大家可以想象一下它們是在不同應用中,如下
3.1 不自動創建Queue,需要在Mq手動建立對應名字的隊列,否則會報"找不到隊列"的錯誤
//接收消息
@Log4j2
@Component
public class MqReceiver {
//不會自動創建隊列
@RabbitListener(queues = "myQueue1")
public void receiver1 (String message){
log.info("MqReceiver1: {}", message);
}
}
//發送消息
@RunWith(SpringRunner.class)
@SpringBootTest
public class MqSenderTest{
@Autowired
private AmqpTemplate amqpTemplate;
@Test
public void send1(){
amqpTemplate.convertAndSend("myQueue1","Hello!Mq Message!");
}
}
3.2 若Mq中無相應名稱的隊列,會自動創建Queue
//接收消息
@RabbitListener(queuesToDeclare = @Queue("myQueue2"))
public void receiver2 (String message){
log.info("MqReceiver2: {}", message);
}
//發送消息
@Test
public void send2(){
amqpTemplate.convertAndSend("myQueue2","Hello!Mq Message!");
}
3.3 消息隊列分組,將不同的隊列歸爲一組,以不同關鍵字區分(會自動創建隊列)
這裏以訂單服務爲例,假設現有兩種訂單,一種是數碼訂單,另一種是水果訂單,數碼供應商和水果供應商兩個服務同時訂閱訂單服務,但數碼供應商只關心數碼訂單,水果供應商只關心水果訂單,這裏就需要對訂單消息進行分類了
//接收消息
/**
* 數碼供應商服務 接收消息
* @param message
*/
@RabbitListener(bindings = @QueueBinding(
exchange = @Exchange("myOrder"),//相當於分組名
key = "computer",//相當於分類名
value = @Queue("computerQueue")
))
public void computerReceiver (String message){
log.info("computerReceiver: {}", message);
}
/**
* 水果供應商服務 接收消息
* @param message
*/
@RabbitListener(bindings = @QueueBinding(
exchange = @Exchange("myOrder"),//相當於分組名
key = "fruit",//相當於分類名
value = @Queue("fruitQueue")
))
public void fruitReceiver (String message){
log.info("fruitReceiver: {}", message);
}
//發送消息
@Test
public void sen4(){
amqpTemplate.convertAndSend("myOrder","computer","computer Order!");
}
@Test
public void sen5(){
amqpTemplate.convertAndSend("myOrder","fruit","fruit Order!");
}
4.啓動eureka-client,eureka-server,config應用,運行剛纔寫的單元測試
發送接收消息成功啦!
如果覺得不錯,分享給你的朋友!
THANDKS
- End -
一個立志成大腿而每天努力奮鬥的年輕人
伴學習伴成長,成長之路你並不孤單!