Spring Boot 20天入門(day9)

Springboot與消息

AMQP

Advanced Message Queuing Protocol 高級消息隊列協議,是面向消息中間件提供的應用層協議。 基於此協議的消息提供者和接受者可實現消息的交互傳遞,且不受平臺語言限制。

消息隊列

消息Message是指在應用間傳送的數據。消息可以非常簡單,比如只包含文本字符串,也可以更復雜,可能包含嵌入對象。

消息隊列Message Queue是一種應用間的通信方式,消息發送後可以立即返回,由消息系統來確保消息的可靠傳遞。消息發佈者只管把消息發佈到 MQ 中而不用管誰來取,消息使用者只管從 MQ 中取消息而不管是誰發佈的。這樣發佈者和使用者都不用知道對方的存在。

消息隊列的應用場景

1)、系統解耦:

系統間通過MQ傳遞消息,而無需關係其他業務的處理

2)、流量削峯:

MQ可以緩解服務器壓力,比如MySQL一次只能處理2000條sql,但是在流量高峯期同時有5000個請求進來,也就是5000條sql,通過MQ接收5000條請求,但是實際發送給sql執行的請求只有2000個。

3)、日誌處理:

複雜的系統架構必然需要處理大量日誌,MQ可以傳輸日誌

4)、廣播:

在分佈式系統中,可以通過MQ將消息廣播給各個節點。

MQ概念模型

消費者(訂閱者)訂閱某個消息隊列,發佈者(生產者)發佈消息給對應消息隊列,最後由消費者消費。

img

RabbitMQ

什麼是RabbitMQ

RabbitMQ 是一個由 Erlang 語言開發的 AMQP 的開源實現。RabbitMQ 最初起源於金融系統,用於在分佈式系統中存儲轉發消息,在易用性、擴展性、高可用性等方面表現不俗。

RabbitMQ基本概念

先來看下RabbitMQ的內部結構圖:

img

RabbitMQ主要設計以下概念:

  • Message消息:消息即需要發送的數據,由消息體和消息頭組成。消息體是消息的內容,消息頭則是對消息體的描述。由許多的Property屬性組成,如路由鍵,優先級,持久化等等。
  • Producer(Publisher)生產者: 生產者即發佈者,它是發佈消息的一方,可以是一個RabbitMQ的客戶端應用程序。
  • Consumer(Subscriber)消費者:消費者即訂閱者,它是接收消息的一方,可以是一個RabbitMQ的客戶端應用程序。
  • Exchange交換機:交換機用戶接收消息,並將消息按照路由規則轉發給指定的消息隊列
  • Binding綁定:綁定一種規則,它將Exchange交換機與Queue消息隊列按照路由規則綁定起來。
  • Routing-Key路由鍵:路由鍵即路由規則,Exchange交換機根據Producer發送過來的Routing Key將消息轉發到指定的消息隊列
  • Queue消息隊列:消息隊列是一個消息容器,本質是一個先進先出的隊列,用戶存儲消息和發送消息,一個消息可以投遞到多個消息隊列,一個消息隊列也可以被多個消費者讀取。
  • Connection網絡連接:無論是發佈消息還是消費消息,都需要通過TCP連接來完成
  • Channel管道:每一次的TCP連接都要消耗一部分網絡資源,對於計算機服務器來說,網絡是非常寶貴的資源,如果每次發佈/訂閱消息都需要建立一次鏈接的話,就太耗費網絡資源了,於是引入的Channel管道的概念。每次發佈/訂閱消息,都由管道來完成而多個管道又可以共享一條TCP連接,這樣就節省了很多的網絡資源。
  • Virtual Host 虛擬主機: 虛擬主機是一個虛擬概念。 在Redis中,一個Redis服務器實例可以被分爲16個庫,但不是說這16個庫的大小就是相等的, 比如1個庫也可以佔9g內存,其他15個庫可以共佔1g內存。 虛擬主機也是如此,它可以看做是一個獨立的rabbitmq服務器實例, 它包含了屬於他的一系列的Exchange,Queue等內容。
  • Broker: Broker即RabbitMQ服務實例。

Rabbit的工作模型

建議大家去RabbitMQ的官網進行學習,官網多個語言的例子。

RabbitMQ主要有5種工作模型:

在這裏插入圖片描述

簡單模式

它是最簡單的消息收發模型,生產者和消費者直接通過Queue進行消息的收發。

(P) -> [|||] -> (C)

工作模式

工作模式與簡單模式相似,但是工作模式支持多個消費者競爭同一個消息隊列。

img

發佈/訂閱模式

發佈訂閱模式是真正意義上的RabbitMQ工作模型,發佈者不會直接將消息發送到隊列上,而是發送給交換機,由交換機把消息廣播到綁定的每個隊列上,訂閱者也只需要監聽它自己的隊列就行了。

img

Routing(direct)路由模式

RabbitMQ路由模式

發佈者在發佈消息的時候可以指定一個路由鍵(Routing key) 接收者也會與消息隊列綁定一個路由鍵。當消息被髮送到 交換機(Exchange)時,交換機會根據路由鍵,將消息發送到擁有相同路由鍵的消息隊列中。

主題模式(topic)

主題模式是一種特殊的路由模式, 與路由模式不同的是: 主題模式的路由鍵支持通配符,可以做到更加多樣化的路由鍵匹配。

RabbitMQ主题模式

RabbitMQ Exchange的類型

RabbitMQ共有3種Exchange類型:

  1. fanout: fanout即發佈者 / 訂閱者模式,發佈者將消息發送到fanout類型的Exchange,Exchange再將消息廣播給與此交換機綁定的Queue。
  2. direct: direct即路由模式,Exchange根據Routing Key,將消息發送到匹配的隊列中。
  3. topic: topic也屬於路由模式,不過它支持"*","#"等通配符進行路由。

Springboot整合rabbitmq

引入依賴

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

配置RabbitMQ

spring.rabbitmq.host=47.93.116.82
spring.rabbitmq.port=5672
spring.rabbitmq.username=weleness
spring.rabbitmq.password=a8761797
spring.rabbitmq.connection-timeout=15000ms

發佈消息

 @Autowired
    RabbitTemplate rabbitTemplate;

    @Autowired
    AmqpAdmin amqpAdmin;

  
    @Test
    void contextLoads() {
        Map<String, Object> map = new HashMap<>();
        map.put("msg", "這是第一個消息");
        map.put("data", Arrays.asList("helloword", 123, true));
                                     //交換器,消息隊列,消息
        rabbitTemplate.convertAndSend("exchange.direct", "weleness.news", map));
    }

接收消息

    @Test
    public void receive() {
        Object o = rabbitTemplate.receiveAndConvert("weleness.news");
        System.out.println(o.getClass());
        System.out.println(o);
    }

使用監聽器異步監聽消息隊列

@Service
public class BookService {

    @RabbitListener(bindings = @QueueBinding(
            exchange = @Exchange("exchange-redirect"),
            key = "weleness",
            value = @Queue("weleness.news")
    ))
    @RabbitListener(queues = "weleness.news")
    public void receive(Book book) {
        System.out.println(book);
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章