消息隊列學習-ActiveMQ(四)

8 SpringBoot整合ActiveMQ

8.1 隊列(Queue)

8.1.1 隊列生產者

  1. 新建Maven工程並設置包名類名
    工程名:boot_mq_produce
    包名:com.sky.boot.activemq
  2. 配置POM文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
         http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.5.RELEASE</version>
        <relativePath />
    </parent>

    <groupId>com.sky.boot.activemq</groupId>
    <artifactId>boot_mq_produce</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-activemq</artifactId>
            <version>2.1.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>
  1. 配置yml文件
server:
  port: 7777
spring:
  activemq:
    broker-url: tcp://192.168.188.131:61616
    user: admin
    password: admin
  jms:
    pub-sub-domain: false # false = Queue(默認) true = Topic

# 自己定義隊列名稱
myqueue: boot-active-queue
  1. 配置bean
@Component
@EnableJms
public class ConfigBean {
    @Value("${myqueue}")
    private String myQueue;

    @Bean
    public Queue queue(){
        return new ActiveMQQueue(myQueue);
    }
}
  1. Queue_Producer
@Component
public class Queue_Produce {
    @Autowired
    private JmsMessagingTemplate jmsMessagingTemplate;
    @Autowired
    private Queue queue;

    public void produceMsg(){
        jmsMessagingTemplate.convertAndSend(queue, "*****:" 
        	+ UUID.randomUUID().toString().substring(0, 6));
    }
}
  1. 主啓動類
@SpringBootApplication
public class MainAppProduce {
    public static void main(String[] args) {
        SpringApplication.run(MainAppProduce.class);
    }
}
  1. 測試單元
@SpringBootTest(classes = MainAppProduce.class)
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
public class TestActiveMQ {
    @Resource
    private Queue_Produce queue_produce;

    @Test
    public void testSend() throws Exception{
        queue_produce.produceMsg();
    }
}

執行後,結果如下:
在這裏插入圖片描述

新需求:要求每隔3秒鐘,往MQ推送消息

  1. 修改Queue_Produce
@Scheduled(fixedDelay = 3000L)
    public void produceMsgScheduled(){
        jmsMessagingTemplate.convertAndSend(queue, "**scheduled:" 
        	+ UUID.randomUUID().toString().substring(0, 6));
        System.out.println("***** produceMsgScheduled send ok");
    }
  1. 修改主啓動類的MainAppProduce
@SpringBootApplication
@EnableScheduling
public class MainAppProduce {
    public static void main(String[] args) {
        SpringApplication.run(MainAppProduce.class, args);
    }
}

直接開啓主啓動類,間隔發送消息
在這裏插入圖片描述

8.1.2 隊列消費者

  1. 新建Mavaen工程並設置包名類名,同上一節
  2. POM文件,同上一節
  3. Yml文件,同上一節,注意:端口改了,eg:8888
  4. springboot的消息監聽註解
@Component
public class Queue_Consumer {
    @JmsListener(destination = "${myqueue}")
    public void receive(TextMessage textMessage) throws JMSException{
        System.out.println("****消費者收到消息:"+textMessage.getText());
    }
}

執行主方法後:
在這裏插入圖片描述

8.2 主題發佈訂閱(Topic)

8.2.1 Topic生產者

  1. 新建Maven工程並設置包名類名:略
  2. POM文件:略
  3. Yml文件
server:
  port: 6666
spring:
  activemq:
    broker-url: tcp://192.168.188.131:61616
    user: admin
    password: admin
  jms:
    pub-sub-domain: true # false = Queue(默認) true = Topic

# 自己定義隊列名稱
myTopic: boot-active-topic
  1. 配置bean
@Component
public class ConfigBean {
    @Value("${myTopic}")
    private String topicName;

    @Bean
    public Topic topic(){
        return new ActiveMQTopic(topicName);
    }
}
  1. Topic_Producer
@Component
public class Topic_Producer {
    @Autowired
    private JmsMessagingTemplate jmsMessagingTemplate;

    @Autowired
    private Topic topic;

    @Scheduled(fixedDelay = 3000L)
    public void produceTopic(){
        jmsMessagingTemplate.convertAndSend(topic, "主題消息:"
        	+ UUID.randomUUID().toString().substring(0, 6));
    }
}
  1. 主啓動類

@SpringBootApplication
@EnableScheduling
public class BootMqToppicProducerApplication {

    public static void main(String[] args) {
        SpringApplication.run(BootMqToppicProducerApplication.class, args);
    }

}

先啓動消費者,後啓動生產者

8.2.2 Topic消費者

  1. 新建Maven工程並設置包名類名:略
  2. POM文件:略
  3. Yml文件
server:
  port: 5555 # 啓動第二個時,改成5566
spring:
  activemq:
    broker-url: tcp://192.168.188.131:61616
    user: admin
    password: admin
  jms:
    pub-sub-domain: true # false = Queue(默認) true = Topic

# 自己定義隊列名稱
myTopic: boot-active-topic

  1. Topic_Consumer
@Component
public class Topic_Consumer {
    @JmsListener(destination = "${myTopic}")
    public void receive(TextMessage textMessage) throws JMSException {
        System.out.println("****消費者收到主題消息:"+textMessage.getText());
    }
}
  1. 主啓動類
@SpringBootApplication
public class BootMqTopicConsumerApplication5555 {

    public static void main(String[] args) {
        SpringApplication.run(BootMqTopicConsumerApplication5555.class, 
        	args);
    }
}

在這裏插入圖片描述

9 ActiveMQ的傳輸協議

9.1 面試題

  • 默認的61616端口如何更改
  • 你生產上的連接協議如何配置的?使用tcp嗎?

9.2 官網

http://activemq.apache.org/configuring-version-5-transports.html

9.3 是什麼

ActiveMQ支持的client-broker通訊協議有:TVP、NIO、UDP、SSL、Http(s)、VM。
其中配置Transport Connector的文件在ActiveMQ安裝目錄的conf/activemq.xml中的標籤之內。
見下圖實際配置:
在這裏插入圖片描述
在上文給出的配置信息中,
URI描述信息的頭部都是採用協議名稱:例如
描述amqp協議的監聽端口時,採用的URI描述格式爲“amqp://······”;
描述Stomp協議的監聽端口時,採用URI描述格式爲“stomp://······”;
唯獨在進行openwire協議描述時,URI頭卻採用的“tcp://······”。這是因爲ActiveMQ中默認的消息協議就是openwire

9.4 有哪些

注意:前兩個較爲重要,其餘瞭解即可

9.4.1 Transmission Control Protocol(TCP)默認

  1. 這是默認的Broker配置,TCP的Client監聽端口61616
  2. 在網絡傳輸數據前,必須要先序列化數據,消息是通過一個叫wire protocol的來序列化成字節流
  3. TCP連接的URI形式如:tcp://HostName:port?key=value&key=value,後面的參數是可選的。
  4. TCP傳輸的的優點:
    (4.1)TCP協議傳輸可靠性高,穩定性強
    (4.2)高效率:字節流方式傳遞,效率很高
    (4.3)有效性、可用性:應用廣泛,支持任何平臺
  5. 關於Transport協議的可選配置參數可以參考官網: TCP詳情

9.4.2 New I/O API Protocol(NIO)

  1. NIO協議和TCP協議類似,但NIO更側重於底層的訪問操作。它允許開發人員對同一資源可有更多的client調用和服務器端有更多的負載。
  2. 適合使用NIO協議的場景:
    (2.1)可能有大量的Client去連接到Broker上,一般情況下,大量的Client去連接Broker是被操作系統的線程所限制的。因此,NIO的實現比TCP需要更少的線程去運行,所以建議使用NIO協議。
    (2.2)可能對於Broker有一個很遲鈍的網絡傳輸,NIO比TCP提供更好的性能。
  3. NIO連接的URI形式:nio://hostname:port?key=value&key=value
  4. 關於Transport協議的可選配置參數可以參考官網: NIO詳情

9.4.3 AMQP協議

Advanced Message Queuing Protocol,一個提供統一消息服務的應用層標準高級消息隊列協議,是應用層協議的一個開放標準,爲面向消息的中間件設計。基於此協議的客戶端與消息中間件可傳遞消息,並不受客戶端/中間件不同產品,不同開發語言等條件限制。

9.4.4 Stomp協議

STOP,Streaming Text Orientation Message Protocol,是流文本定向消息協議,是一種爲MOM(Message Oriented Middleware,面向消息中間件)設計的簡單文本協議。

9.4.5 Secure Sockets Layer Protocol(SSL)

9.4.6 MQTT協議

MQTT(Message Queuing Telemetry Transport,消息隊列遙測傳輸)是IBM開發的一個即時通訊協議,有可能成爲物聯網的重要組成部分。該協議支持所有平臺,幾乎可以把所有聯網物品和外部連接起來,被用來當作傳感器和致動器(比如通過Twitter讓房屋聯網)的通信協議。

擴展Githubhttps://github.com/fusesource/mqtt-client

9.4.7 WS協議(websocket)

9.4.8 小總結

在這裏插入圖片描述

9.5 NIO案例演示

9.5.1 修改配置文件

transportConnectors裏添加
<transportConnector name="nio" uri="nio://0.0.0.0:61618?trace=true" />
在這裏插入圖片描述
記得重啓activemq

9.5.2 生產和消費兩端協議代碼修改

都只改動這兩行即可

private static final String ActiveMQ_URL = "nio://192.168.188.131:61618";
private static final String QUEUE_NAME = "Protocol";

運行結果與前面一樣,略。

9.6 nio案例演示增強

問題:URI格式以"nio"開頭,代表這個端口使用TCP協議爲基礎的NIO網絡模型。
但是這樣的設置方式,只能使這個端口支持Openwire協議。

我們怎麼能夠讓這個端口既支持NIO網絡模型,又讓他支持多個協議呢?

解決:使用auto關鍵字、使用"+"符號來爲端口設置多種特性

transportConnectors中添加

<transportConnector name="auto+nio" uri="auto+nio://0.0.0.0:61608?maximumConnections=1000&amp;wireFormat.maxFrameSize=104857600&amp;org.apache.activemq.transport.nio.SelectorManager.corePoolSize=20&amp;org.apache.activemq.transport.nio.SelectorManager.maximumPoolSize=50"/>

在這裏插入圖片描述
重啓activeMQ後,
在這裏插入圖片描述

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