SpringBoot對非同步訊息(MQ)的支援

weixin_33860722發表於2017-09-12

1.非同步訊息的定義

  非同步訊息的主要目的是為了系統與系統之間的通訊,所謂非同步訊息即訊息傳送者無需等待訊息接收者的處理以及返回,甚至無需關心訊息是否傳送成功
  在非同步訊息中有兩個很重要的概念,即訊息代理和目的地,當訊息傳送者傳送訊息之後,訊息將由訊息代理接管,訊息代理保證訊息傳遞到指定目的地。
  非同步訊息主要有兩種目的地形式,佇列(queue)和主題(topic),佇列用於點對點形式的訊息通訊,主題用於釋出訂閱式的訊息通訊。

1.1目的地形式分類

1.1.1點對點式

  當訊息傳送者傳送訊息,訊息代理將訊息後將訊息放進一個佇列裡,當有訊息接收者來接收訊息的時候,訊息將從佇列中取出傳遞給訊息接收者,這時候佇列裡就沒有了這條訊息。點對點式確保每一條訊息只有唯一的傳送者和接收者,但這並不能說明只有一個接收者能夠從佇列中接收訊息,因為佇列中有多個訊息,點對點式只保證每一條訊息只有唯一的傳送者和接收者

1.1.2釋出/訂閱式

  釋出訂閱式是訊息傳送者傳送訊息到主題,而多個訊息接收者監聽這個主題,此時的訊息傳送者和接收者分別叫做釋出者和訂閱者

1.2 企業級訊息代理

  JMS即JAVA訊息服務,是基於JVM的訊息代理規範,ActiveMQ是一個JMS的實現
AMQP也是一個訊息代理的規範,他不僅相容JMS,還支援跨語言和平臺,AMQP的主要實現是RabbitMQ

1.3 Spring以及SpringBoot的支援

  Spring針對JMS和RabbitMQ分別提供了JmsTemplete和RabbitTemplete來傳送訊息。為我們提供了@JmsListener,@RabbitListener註解來監聽訊息代理髮送的訊息。我們分別需要通過@EnableJms和@EnableRabbit來開啟支援
  SpringBoot自動配置了上述@EnableJms,@EnableRabbit,JmsTemplete,RabbitTemplete的支援,同時我們可以在application.properties檔案中分別以spring.activemq和spring.rabbitmq來分別配置所需的屬性。

2.SpringBoot對JMS(ActiveMQ)的支援

下載安裝

ActiveMQ的官方下載地址:http://activemq.apache.org/download.html,下載安裝完成後
進入bin目錄,發現有win32和win64兩個資料夾,這2個資料夾分別對應windows32位和windows64位作業系統的啟動指令碼。進入對應的資料夾中雙擊activemq.bat。即可正常啟動
訪問http://localhost:8161/admin。輸入預設的使用者名稱和密碼:admin/admin即可進入ActiveMQ的控制檯

2.2 配置

SpringBoot提供了針對ActiveMQ的支援,只需要在pom.xml檔案中引入即可:

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

在application.properties配置ActiveMQ的訊息代理地址:

spring.activemq.broker-url=tcp://localhost:61616

注意,此處配置的訊息代理必須讓ActiveMQ啟動時才有作用,否則無效

在實際情況下,訊息的釋出者和接受者一般都是分開的,而這裡,我們僅作測試,將訊息傳送者和接收者放在一個程式中

2.3程式碼檔案

2.3.1訊息定義

public class Msg implements MessageCreator {
    @Override
    public Message createMessage(Session session) throws JMSException {
        return session.createTextMessage("測試訊息");
    }
}

2.3.2訊息傳送及目的地定義

@SpringBootApplication
public class SpringBootMqApplication implements CommandLineRunner{

    @Autowired
    JmsTemplate  jmsTemplate;
    public static void main(String[] args) {
        SpringApplication.run(SpringBootMqApplication.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
            jmsTemplate.send("my-destination",new Msg());
    }
}

CommandLineRunner介面中的run方法,是在程式啟動後就會執行的程式碼。JmsTemplate 是用來操作JMS訊息的操作類。

2.3.3訊息監聽

@Component
public class Receiver {
    @JmsListener(destination = "my-destination")
    public void  receivedMessage(String message){
        System.out.println("接受到"+message);
    }
}

@JmsListener顯示的定義了指定要監聽的目的地。

2.3.4執行結果

執行結果顯示監聽收到了訊息


837553-8cacc431a2f14092
這裡寫圖片描述

ActiveMQ的控制檯中顯示我們傳送的訊息


837553-8f474fc875bfbf0f
這裡寫圖片描述

3.SpringBoot對AMQP(RabbitMQ)的支援

3.1RabbitMQ的安裝配置

  RabbitMQ是基於Erlang語言開發的。所以安裝RabbitMQ之前需要先下載安裝配置Erlang,下載地址:http://www.erlang.org/downloads
並將安裝後的D:\Program Files\erl9.0\bin的bin目錄配置到path環境變數中。然後下載安裝RabbitMQ。下載地址:http://www.rabbitmq.com/download.html
安裝完成之後在開始選單中找到RabbitMQ Command Promt,開啟控制檯,輸入命令

rabbitmq-plugins enable rabbitmq_management

控制檯無錯誤之後,訪問http://localhost:15672。使用預設的使用者名稱/密碼:guest/guest進行登入
即可見到如圖所示介面:

837553-df82f21f4a027bdf
這裡寫圖片描述

3.2 RabbitMQ測試程式碼檔案

SpringBoot預設Rabbit的主機為localhost,埠號為5672,所以我們無需為RabbitMQ配置其他資訊。
入口檔案

import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

import java.lang.annotation.Annotation;

@SpringBootApplication
public class SpringBootAmqpApplication implements CommandLineRunner {
    @Autowired
     RabbitTemplate rabbitTemplate;
    public static void main(String[] args) {
        SpringApplication.run(SpringBootAmqpApplication.class, args);
    }

    @Bean //2
    public Queue wiselyQueue(){
        return new Queue("my-queue");
    }

    @Override
    public void run(String... strings) throws Exception {
        rabbitTemplate.convertAndSend("my-queue","來自RabbitMQ的問候");
    }
}

接收類

@Component
public class Receiver {
    @RabbitListener(queues = "my-queue")
    public  void  ReceiveMesaage(String  message){
        System.out.println("接受到"+message);
    }
}

3.3 測試結果

837553-02cc20c8ad608395
這裡寫圖片描述

在RabbitMQ控制檯中額可以看到


837553-0824137605246ba9
這裡寫圖片描述

4 小結

  這裡主要是對ActiveMQ和RabbitMQ進行了簡單的嘗試,瞭解了非同步訊息的通訊。有興趣的同學可以進行深入研究。

程式碼檔案
參考書籍:JavaEE開發的顛覆者--SpringBoot實戰

相關文章