RabbitMq 概念與基礎使用

------------------------------------------------------------------------RabbitMq 核心概念-----------------------------------------------------------------------

AMQP:高級消息隊列協議

Server :Broker接受客戶端的連接,實現AMQP 實體服務

Connection:連接 ,應用程序與Broker 建立連接

Channel:網絡通信, 幾乎所有的操作都在Channel中進行,是進行消息讀寫的通道,每一個channel代表一個會話任務

Message:消息,傳送的數據 由Properties 和Body 組成

Virtual host:虛擬主機,用於邏輯隔離,最上層的消息路由的劃分。同一個Virtual host 不能有相同名稱的Exchange或Queue

Exchange :交換機,接受消息,根據路由鍵轉發消息到綁定的隊列

Binding: Exchange  和Queue 之間的虛擬連接,bingding中可以包含routing key

Routing key : 一個路由規則,虛擬機可以用它來確定如何路由一個特別消息

Queue : message queue,消息隊列

------------------------------------------------------------------------RabbitMq 安裝使用-----------------------------------------------------------------------

erlang/socat/rabbitmq

官網下載 erlang(相當於java 的jdk), 和rabbitMq 服務。

配置環境變量後 cmd 執行:

rabbitmqctl status --查看狀態

rabbitmq-plugins.bat enable rabbitmq_management //管理界面插件

rabbitmq-server.bat --啓動mq 服務

登陸 http://localhost:15672 用戶名密碼:guest/guest

-----------------------------------------------------------------------命令行操作與管控臺-基礎操作----------------------------------------------------------

rabbitmqctl  stop_app:關閉應用

rabbitmqctl  add_user username password: 添加用戶

rabbitmqctl list_users: 列出所有用戶

rabbitmqctl delete_user username : 刪除用戶

rabbitmqctl  add_vihost vhostpath :創建虛擬主機

rabbitmqctl list_vihost  : 列出所有虛擬主機

rabbitmqctl list_queues:查看所有隊列信息

rabbitmqctl  reset :移除所有數據,要在rabbitmqctl  stop_app 之後使用

rabbitmqctl join_cluster <cluster_node> [--ram] : 組成集羣命令

rabbitmqctl cluster_status :查看集羣狀態

....

所有管控臺能操作得步驟,控制檯命令都可操作。

-----------------------------------------------------------------------Exchange 交換機---------------------------------------------------------------

Exchange有以下屬性:

Name:交換機名稱

Type:Direct,Topic,Fanout ,Headers(不常用)

Durability:(durable-持久化/transient-瞬變)是否需要持久化,true/durable 爲持久化 

Auto Delete:當最後一個綁定到Exchange 上得隊列刪除後,自動刪除改Exchange

Internal:當前Exchange是否用於RabbitMQ 內部使用,默認爲false/no(基本不做設定使用默認)

Argument:擴展參數,用於擴展AMQP協議自制定化使用

-----------------------------------------------------------------------Direct Exchange 模式---------------------------------------------------------------

Direct Exchange:所有發送到 Direct Exchange 得消息被轉發到RoutingKey 中指定得Queue (注意:Direct 模式可以使用RabbitMQ自帶得Exchange:default Exchange,所以不需要將Exchange進行任何綁定(binding)操作,消息傳遞時,Routingkey 必須完全匹配纔會被隊列接收,否則消息會被拋棄

/**
 * Created by LIUYAO823 on 2019-9-3 15:00
 * 生產者
 */
public class Producer {

    public static void main(String[] args) throws Exception{
        //創建ConnectionFactory
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("127.0.0.1");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");

        //通過ConnectionFactory 創建Connection
        Connection connection =connectionFactory.newConnection();

        //通過Connection創建Channel(核心通信)
        Channel channel = connection.createChannel();
        String Massage = "hello mq test direct exchange";

        String exchangename = "test_direct_exchange";
        String routingKey = "test_direct";

        for (int i = 0; i <5 ; i++) {
            //發消息時必須要指定Exchange, 如果沒有指定, 默認找default Exchange 通過指定得Routing Key 去找對應得名字
            //1.exchange 2.routing key
            channel.basicPublish(exchangename,routingKey,null,Massage.getBytes());
        }
        channel.close();
        connection.close();

    }

}
/**
 * Created by LIUYAO823 on 2019-9-3 15:01
 * 消費者
 */
public class Counsumer {

    public static void main(String[] args) throws Exception{
        //創建ConnectionFactory
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("127.0.0.1");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");

        //通過ConnectionFactory 創建Connection
        Connection connection =connectionFactory.newConnection();

        //通過Connection創建Channel(核心通信)
        Channel channel = connection.createChannel();

        //聲明
        String exchangename = "test_direct_exchange";
        String exchangeType = "direct";
        String queuename = "test_direct_queue";
        String routingKey = "test_direct";
        //聲明一個交換機
        channel.exchangeDeclare(exchangename,exchangeType,true,false,false,null);
        //聲明一個隊列
        channel.queueDeclare(queuename,true,false,false,null);
        //交換機和隊列通過routingkey綁定
        channel.queueBind(queuename,exchangename,routingKey);

        //創建一個消費者
        channel.basicConsume(queuename, true, new DefaultConsumer(channel) {
                @Override
                public void handleDelivery(String consumerTag,
                                           Envelope envelope,
                                           AMQP.BasicProperties properties,
                                           byte[] body)
                        throws IOException
                {
                    System.out.println("消費者......");
                    //String routingKey = envelope.getRoutingKey();
                    //String contentType = properties.getContentType();
                    long deliveryTag = envelope.getDeliveryTag();
                    channel.basicAck(deliveryTag, false);
                }
         });

    }
}

-----------------------------------------------------------------------Topic Exchange 模式---------------------------------------------------------------

Topic Exchange:所有發送到 Topic Exchange 的消息被轉發到所有關心RoutingKey中指定的Topic的Queue上(Exchange 將RoutingKey 和某Topic進行模糊匹配,此時隊列需要綁定一個Topic 注意:可以使用通配符進行模糊匹配 "#" 匹配一個或多個詞;"*" 匹配不多不少一個詞,例如:"log.#" 能夠匹配到"log.info.oa" ; "log.*"只會匹配到"log.erro")

/**
 * Created by LIUYAO823 on 2019-9-3 15:01
 * 消費者
 */
public class Counsumer {

    public static void main(String[] args) throws Exception{
        //創建ConnectionFactory
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("127.0.0.1");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");

        //通過ConnectionFactory 創建Connection
        Connection connection =connectionFactory.newConnection();

        //通過Connection創建Channel(核心通信)
        Channel channel = connection.createChannel();

        //聲明
        String exchangename = "test_topic_exchange";
        String exchangeType = "topic";
        String queuename = "test_topic_queue";
        String routingKey = "user.#";
        //聲明一個交換機
        channel.exchangeDeclare(exchangename,exchangeType,true,false,false,null);
        //聲明一個隊列
        channel.queueDeclare(queuename,false,false,false,null);
        //交換機和隊列通過routingkey綁定
        channel.queueBind(queuename,exchangename,routingKey);

        //創建一個消費者
        channel.basicConsume(queuename, true, new DefaultConsumer(channel) {
                @Override
                public void handleDelivery(String consumerTag,
                                           Envelope envelope,
                                           AMQP.BasicProperties properties,
                                           byte[] body)throws IOException{
                    System.out.println("消費者consumerTag ["+consumerTag+"]envelope["+envelope+"]properties["+properties+"]");
                    //String routingKey = envelope.getRoutingKey();
                    //String contentType = properties.getContentType();
                    long deliveryTag = envelope.getDeliveryTag();
                    channel.basicAck(deliveryTag, false);
                   // System.out.println("消費者收到的消息["++"]");
                }
         });

    }
}
/**
 * Created by LIUYAO823 on 2019-9-3 15:00
 * 生產者
 */
public class Producer {

    public static void main(String[] args) throws Exception{
        //創建ConnectionFactory
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("127.0.0.1");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");

        //通過ConnectionFactory 創建Connection
        Connection connection =connectionFactory.newConnection();

        //通過Connection創建Channel(核心通信)
        Channel channel = connection.createChannel();
        String Massage = "hello mq test direct exchange";

        String exchangename = "test_topic_exchange";
        String routingKey1 = "user.save";
        String routingKey2 = "user.update";
        String routingKey3 = "user.delete.abc";

        System.out.println("生產者......");
        channel.basicPublish(exchangename,routingKey1,null,Massage.getBytes());
        channel.basicPublish(exchangename,routingKey2,null,Massage.getBytes());
        channel.basicPublish(exchangename,routingKey3,null,Massage.getBytes());

        channel.close();
        connection.close();

    }

}

-----------------------------------------------------------------------Fanout Exchange 模式---------------------------------------------------------------

Fanout Exchange:不處理任何的路由鍵,只需要簡單的將隊列綁定到交換機上;發送到交換機上的消息都會被轉發到與該交換機綁定的所有隊列上;Fanout 交換機轉發消息是最快的。

/**
 * Created by LIUYAO823 on 2019-9-3 15:00
 * 生產者
 */
public class Producer {

    public static void main(String[] args) throws Exception{
        //創建ConnectionFactory
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("127.0.0.1");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");

        //通過ConnectionFactory 創建Connection
        Connection connection =connectionFactory.newConnection();

        //通過Connection創建Channel(核心通信)
        Channel channel = connection.createChannel();
        String Massage = "hello mq test direct exchange";

        String exchangename = "test_fanout_exchange";
        String routingKey1 = ""; //無論是否設置路由鍵, fanout模式都忽略,直接看交換機的一個綁定關係
       /* String routingKey2 = "user.update";
        String routingKey3 = "user.delete.abc";*/

        System.out.println("生產者......");
        for (int i = 0; i <3 ; i++) {
            channel.basicPublish(exchangename,routingKey1,null,Massage.getBytes());

        }
        channel.close();
        connection.close();

    }
}
/**
 * Created by LIUYAO823 on 2019-9-3 15:01
 * 消費者
 */
public class Counsumer {

    public static void main(String[] args) throws Exception{
        //創建ConnectionFactory
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("127.0.0.1");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");

        //通過ConnectionFactory 創建Connection
        Connection connection =connectionFactory.newConnection();

        //通過Connection創建Channel(核心通信)
        Channel channel = connection.createChannel();

        //聲明
        String exchangename = "test_fanout_exchange";
        String exchangeType = "fanout";
        String queuename = "test_fanout_queue";
        String routingKey = "";//不設置路由鍵
        //聲明一個交換機
        channel.exchangeDeclare(exchangename,exchangeType,true,false,false,null);
        //聲明一個隊列
        channel.queueDeclare(queuename,false,false,false,null);
        //交換機和隊列通過routingkey綁定
        channel.queueBind(queuename,exchangename,routingKey);

        //創建一個消費者
        channel.basicConsume(queuename, true, new DefaultConsumer(channel) {
                @Override
                public void handleDelivery(String consumerTag,
                                           Envelope envelope,
                                           AMQP.BasicProperties properties,
                                           byte[] body)throws IOException{
                    System.out.println("消費者consumerTag ["+consumerTag+"]envelope["+envelope+"]properties["+properties+"]");
                    //String routingKey = envelope.getRoutingKey();
                    //String contentType = properties.getContentType();
                    long deliveryTag = envelope.getDeliveryTag();
                    channel.basicAck(deliveryTag, false);
                }
         });

    }
}

-----------------------------------------------------------------------Binding-綁定---------------------------------------------------------------------------------

Binding-綁定: Exchange 和Exchange、Queue之間的連接關係 ; Binding中可以包含RoutingKey或者參數

-----------------------------------------------------------------------Queue-消息隊列----------------------------------------------------------------------------Queue-消息隊列:實際存儲消息數據

Durability:是否需要持久化,durable-是/ transient-否

Auto Delete:當最後一個綁定到Exchange 上得隊列刪除後,自動刪除改Exchange

-----------------------------------------------------------------------Message-消息----------------------------------------------------------------------------

Message:服務和應用程序之間傳送的數據;本質上就是一段數據 由Properties 和Body 組成

常用屬性:delivery mode、headers(自定義屬性)

其它屬性:content_type、content_encoding、priority ;

                 correlation_id、reply_to、expiration、message_id;

                 timestamp、type、user_id、app_id、cluster_id;

/**
 * Created by LIUYAO823 on 2019-9-3 15:00
 * 生產者
 */
public class Producer {

    public static void main(String[] args) throws Exception{
        //創建ConnectionFactory
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("127.0.0.1");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");

        //通過ConnectionFactory 創建Connection
        Connection connection =connectionFactory.newConnection();

        //通過Connection創建Channel(核心通信)
        Channel channel = connection.createChannel();
        String Massage = "hello mq test direct exchange";
        String routingKey= "test001"; 
        Map<String, Object> map = new HashMap<>();
        map.put("my1","111");
        map.put("my2","222");
        AMQP.BasicProperties  Properties= new AMQP.BasicProperties.Builder()
                .deliveryMode(2) //常用模式 2-持久化 服務器重啓消息依舊存在
                .contentType("UTF-8")//
                .expiration("50000") //消息過期時間
                .headers(map)//放自定義的屬性
                .build();
        for (int i = 0; i <3 ; i++) {
            System.out.println("生產者......");
            //發送一個帶有附加屬性的消息
            channel.basicPublish("",routingKey,Properties,Massage.getBytes());

        }
        channel.close();
        connection.close();

    }
}
/**
 * Created by LIUYAO823 on 2019-9-3 15:01
 * 消費者
 */
public class Counsumer {

    public static void main(String[] args) throws Exception{
        //創建ConnectionFactory
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("127.0.0.1");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");

        //通過ConnectionFactory 創建Connection
        Connection connection =connectionFactory.newConnection();

        //通過Connection創建Channel(核心通信)
        Channel channel = connection.createChannel();

        //聲明
        String queuename = "test001";
        //聲明一個隊列
        channel.queueDeclare(queuename,true,false,false,null);

        //創建一個消費者
        channel.basicConsume(queuename, true, new DefaultConsumer(channel) {
                @Override
                public void handleDelivery(String consumerTag,
                                           Envelope envelope,
                                           AMQP.BasicProperties properties,
                                           byte[] body)throws IOException{
                    System.out.println("消費者consumerTag ["+consumerTag+"]envelope["+envelope+"]properties["+properties.getHeaders().get("my1")+"]");
                    //String routingKey = envelope.getRoutingKey();
                    //String contentType = properties.getContentType();
                    long deliveryTag = envelope.getDeliveryTag();
                    channel.basicAck(deliveryTag, false);
                }
         });

    }
}

 

 

 

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