【RabbitMQ】走進RabbitMQ

00潤物無聲00發表於2017-03-12

  RabbitMQ是一個在AMQP基礎上完整的,可複用的企業訊息系統。他遵循Mozilla Public License開源協議。


  在瞭解RabbitMQ之前我們應該先了解一下,什麼是AMQP(Advanced Message Queuing Protocol),高階訊息佇列協議,一個提供統一訊息服務的應用層標準高階訊息佇列協議,是應用層協議的一個開放標準,為面向訊息的中介軟體設計。基於此協議的客戶端與訊息中介軟體可傳遞訊息,並不受客戶端/中介軟體不同產品,不同的開發語言等條件的限制。Erlang中的實現有 RabbitMQ等。解決眾多的訊息佇列需求和拓撲結構問題


  RabbitMQ 遵循AMQP協議,用erlang語言開發,一個開源的訊息代理和佇列伺服器,用來通過普通協議在完全不同的應用之間共享資料,或者簡單地將作業排隊以便讓分散式伺服器進行處理。


作用:

  使用訊息佇列解耦應用程式,訊息佇列使用訊息將應用程式連線起來,這些訊息通過像RabbitMQ這樣的訊息代理伺服器在應用程式之間路由。


基本概念:

  

  Broker:簡單來說就是訊息佇列伺服器實體。

  Exchange:訊息交換機,它指定訊息按什麼規則,路由到哪個佇列。

  Queue:訊息佇列載體,每個訊息都會被投入到一個或多個佇列。

  Binding:繫結,它的作用就是把exchange和queue按照路由規則繫結起來。

  Routing Key:路由關鍵字,exchange根據這個關鍵字進行訊息投遞。

  vhost:虛擬主機,一個broker裡可以開設多個vhost,用作不同使用者的許可權分離。

  producer:訊息生產者,就是投遞訊息的程式。

  consumer:訊息消費者,就是接受訊息的程式。

  channel:訊息通道,在客戶端的每個連線裡,可建立多個channel,每個channel代表一個會話任務。


Java,Hello World

  通過一個簡單的Demo,認識一下MQ的執行過程;

建立一個maven專案,加入依賴

<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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.dynamic.rabbitmq</groupId>
  <artifactId>dynamiac.rabbitmq</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>dynamiac.rabbitmq Maven Webapp</name>
  <url>http://maven.apache.org</url>
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>3.8.1</version>
      <scope>test</scope>
    </dependency>

      <dependency>
        <groupId>com.rabbitmq</groupId>
        <artifactId>amqp-client</artifactId>
        <version>3.4.1</version>
      </dependency>
      <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.7.7</version>
      </dependency>
      <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
        <version>3.3.2</version>
      </dependency>

      <dependency>
        <groupId>org.springframework.amqp</groupId>
        <artifactId>spring-rabbit</artifactId>
        <version>1.4.0.RELEASE</version>
      </dependency>

  </dependencies>
  <build>
    <finalName>dynamiac.rabbitmq</finalName>
  </build>
</project>

建立連線的工具類

package com.dynamic.rabbitmy.util;

import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;

/**
 * Created by fxq on 2017/3/10.
 */
public class ConnectionUtil {
    public static Connection getConnection() throws  Exception
    {
        //定義連線工廠
        ConnectionFactory factory = new ConnectionFactory();
        //設定服務地址
        factory.setHost("127.0.0.1");
        //埠
        factory.setPort(5672);
        //設定賬號資訊,使用者名稱,密碼,vhost
        factory.setVirtualHost("/taotao");
        factory.setUsername("taotao");
        factory.setPassword("taotao");
        //通過工程獲取連線
        Connection connection = factory.newConnection();
        return connection;
    }
}


生產者

package com.dynamic.rabbitmy.simple;

import com.dynamic.rabbitmy.util.ConnectionUtil;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;

/**
 * Created by fxq on 2017/3/10.
 */
public class Send {
    private final  static  String QUEUE_NAME="test_queue";//佇列名稱
    public static void main(String[] args) throws  Exception
    {
        //獲取到連線以及mq通道
        Connection connection = ConnectionUtil.getConnection();
        //連線中建立通道
        Channel channel = connection.createChannel();
        //宣告(建立)佇列
        channel.queueDeclare(QUEUE_NAME,false,false,false,null);
        String message = "Hello World!";
        channel.basicPublish("",QUEUE_NAME,null,message.getBytes());
        System.out.println("[x] Sent'" + message + "'" );
        //關閉通道和連線
        channel.close();
        connection.close();
    }
}

消費者

package com.dynamic.rabbitmy.simple;

/**
 * Created by fxq on 2017/3/10.
 */

import com.dynamic.rabbitmy.util.ConnectionUtil;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.QueueingConsumer;

/**
 * 消費者
 */
public class Recv {

    private final static String QUEUE_NAME="test_queue";
    public static void main(String[] args) throws  Exception {
        //獲取連線以及mq通道
        Connection connection = ConnectionUtil.getConnection();
        Channel channel = connection.createChannel();
        //宣告佇列
        channel.queueDeclare(QUEUE_NAME,false,false,false,null);
        //定義佇列的消費者
        QueueingConsumer consumer = new QueueingConsumer(channel);
        //監聽佇列
        channel.basicConsume(QUEUE_NAME,true,consumer);//true自動模式
        //獲取訊息
        while (true)
        {
            QueueingConsumer.Delivery delivery = consumer.nextDelivery();
            String message = new String(delivery.getBody());
            System.out.println(" [x] Received '" + message + "'");
        }
    }
}

  使用RabbitMq把應用程式之間解耦,使用訊息在應用程式之間進行傳遞,在專案中,將一些無需即時返回且耗時的操作提取出來,進行了非同步處理,而這種非同步處理的方式大大的節省了伺服器的請求響應時間,從而提高了系統的吞吐量。


相關文章