RabbitMq入門(二)常用的工作模式

0、"Hello World!"

代碼 請參考 代碼

1、 Work queues

 工作隊列模式相比於helloworld入門程序就是同一個隊列被多個消費者綁定,

結果:
1、一條消息只會被一個消費者接收;
2、rabbit採用輪詢的方式將消息是平均發送給消費者的;
3、消費者在處理完某條消息後,纔會收到下一條消息。

2、Publish/Subscribe 

 消息生成者代碼

package com.whwe.rabbitmqdemo.produc;

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

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * @ClassName Producer02
 * @Description TODO
 * @Author yueyiming
 * @Date 2019/4/26 11:49
 * @Version 1.0
 * https://blog.csdn.net/hzau_itdog
 **/
public class Producer02 {
    //聲明兩個隊列1個交換機
    private static final String QUEUE_INFORM_EMAIL = "queue_inform_email";
    private static final String QUEUE_INFORM_SMS = "queue_inform_sms";
    private static final String EXCHANGE_FANOUT_INFORM = "exchange_fanout_inform";

    public static void main(String[] args) throws IOException, TimeoutException {
        Connection connection = null;
        Channel channel = null;
        //創建連接
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("192.168.20.129");
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");
        connectionFactory.setVirtualHost("/");
        try {
            connection = connectionFactory.newConnection();
            //創建channel通道
            channel = connection.createChannel();
            //申明交換機
            //類型  DIRECT("direct"), FANOUT("fanout"), TOPIC("topic"), HEADERS("headers");
            channel.exchangeDeclare(EXCHANGE_FANOUT_INFORM, BuiltinExchangeType.FANOUT);

            //聲明隊列
            channel.queueDeclare(QUEUE_INFORM_EMAIL,true,false,true,null);
            channel.queueDeclare(QUEUE_INFORM_SMS,true,false,true,null);

            //隊列和交換機進行綁定
            //queue 隊列名稱
            //exchange 交換機名稱
            //routingKey 路由key
            channel.queueBind(QUEUE_INFORM_EMAIL, EXCHANGE_FANOUT_INFORM, "");
            channel.queueBind(QUEUE_INFORM_SMS, EXCHANGE_FANOUT_INFORM, "");
            //發送消息
            for (int i = 0; i < 100; i++) {
                StringBuilder sb = new StringBuilder("inform to user---");
                sb.append(i);
                channel.basicPublish(EXCHANGE_FANOUT_INFORM, "", null, sb.toString().getBytes("utf-8"));
                System.out.println("發送消息------" + sb.toString());
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (channel != null) {
                channel.close();
            }
            if (connection != null) {
                connection.close();
            }
        }
    }

}

 消息消費者

package com.whwe.rabbitmqdemo.conc;

import com.rabbitmq.client.*;

import java.io.IOException;

/**
 * @ClassName Consumer02_subscribe_email
 * @Description TODO
 * @Author yueyiming
 * @Date 2019/4/26 14:35
 * @Version 1.0
 * https://blog.csdn.net/hzau_itdog
 **/
public class Consumer02_subscribe_email {
    private static final String QUEUE_INFORM_EMAIL = "queue_inform_email";
    private static final String EXCHANGE_FANOUT_INFORM = "exchange_fanout_inform";

    public static void main(String[] args) {
        Connection connection = null;
        Channel channel = null;
        //創建連接
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("192.168.20.129");
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");
        connectionFactory.setVirtualHost("/");
        try {
            connection = connectionFactory.newConnection();
            //創建channel通道
            channel = connection.createChannel();
            //申明交換機
            //類型  DIRECT("direct"), FANOUT("fanout"), TOPIC("topic"), HEADERS("headers");
            channel.exchangeDeclare(EXCHANGE_FANOUT_INFORM, BuiltinExchangeType.FANOUT);

            //聲明隊列
            channel.queueDeclare(QUEUE_INFORM_EMAIL, true, false, true, null);

            //隊列和交換機進行綁定
            //queue 隊列名稱
            //exchange 交換機名稱
            //routingKey 路由key
            channel.queueBind(QUEUE_INFORM_EMAIL, EXCHANGE_FANOUT_INFORM, "");

            //定義消費方法
            DefaultConsumer consumer = new DefaultConsumer(channel) {
                @Override
                public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                    //消息id
                    long msgId = envelope.getDeliveryTag();
                    //交換機名稱
                    String exchange = envelope.getExchange();
                    //路由key
                    String routingKey = envelope.getRoutingKey();
                    //是否重新傳遞
                    boolean redeliver = envelope.isRedeliver();
                    System.out.println("msgId------" + msgId);
                    System.out.println("exchange------" + exchange);
                    System.out.println("routingKey------" + routingKey);
                    System.out.println("redeliver------" + redeliver);
                    System.out.println("接受消息爲:------" + new String(body, "utf-8"));

                }
            };
            channel.basicConsume(QUEUE_INFORM_EMAIL,true,consumer);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

3、Routing

 消息生產者

package com.whwe.rabbitmqdemo.produc;

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

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * @ClassName Producer03_routing
 * @Description TODO
 * @Author yueyiming
 * @Date 2019/4/26 14:59
 * @Version 1.0
 * https://blog.csdn.net/hzau_itdog
 **/
public class Producer03_routing {
    //聲明兩個隊列1個交換機
    private static final String QUEUE_INFORM_EMAIL = "queue_inform_email";
    private static final String QUEUE_INFORM_SMS = "queue_inform_sms";
    private static final String EXCHANGE_DIRECT_INFORM = "exchange_direct_inform";

    public static void main(String[] args) throws IOException, TimeoutException {
        Connection connection = null;
        Channel channel = null;
        //創建連接
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("192.168.20.129");
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");
        connectionFactory.setVirtualHost("/");
        try {
            connection = connectionFactory.newConnection();
            //創建channel通道
            channel = connection.createChannel();
            //申明交換機
            //類型  DIRECT("direct"), FANOUT("fanout"), TOPIC("topic"), HEADERS("headers");
            channel.exchangeDeclare(EXCHANGE_DIRECT_INFORM, BuiltinExchangeType.DIRECT);

            //聲明隊列
            channel.queueDeclare(QUEUE_INFORM_EMAIL, true, false, true, null);
            channel.queueDeclare(QUEUE_INFORM_SMS, true, false, true, null);

            //隊列和交換機進行綁定
            //queue 隊列名稱
            //exchange 交換機名稱
            //routingKey 路由key
            channel.queueBind(QUEUE_INFORM_EMAIL, EXCHANGE_DIRECT_INFORM, "0");
            channel.queueBind(QUEUE_INFORM_SMS, EXCHANGE_DIRECT_INFORM, "1");
            //發送消息
            for (int i = 0; i < 100; i++) {
                StringBuilder sb = new StringBuilder("inform to user---");
                sb.append(i);
                channel.basicPublish(EXCHANGE_DIRECT_INFORM, "" + i % 2, null, sb.toString().getBytes("utf-8"));
                System.out.println("發送消息------" + sb.toString());
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (channel != null) {
                channel.close();
            }
            if (connection != null) {
                connection.close();
            }
        }
    }
}

消息消費者

package com.whwe.rabbitmqdemo.conc;

import com.rabbitmq.client.*;

import java.io.IOException;

/**
 * @ClassName Consumer03_routing_email
 * @Description TODO
 * @Author yueyiming
 * @Date 2019/4/26 15:04
 * @Version 1.0
 * https://blog.csdn.net/hzau_itdog
 **/
public class Consumer03_routing_email {
    private static final String QUEUE_INFORM_EMAIL = "queue_inform_email";
    private static final String EXCHANGE_DIRECT_INFORM = "exchange_direct_inform";

    public static void main(String[] args) {
        Connection connection = null;
        Channel channel = null;
        //創建連接
        ConnectionFactory connectionFactory = new ConnectionFactory();
        connectionFactory.setHost("192.168.20.129");
        connectionFactory.setPort(5672);
        connectionFactory.setUsername("guest");
        connectionFactory.setPassword("guest");
        connectionFactory.setVirtualHost("/");
        try {
            connection = connectionFactory.newConnection();
            //創建channel通道
            channel = connection.createChannel();
            //申明交換機
            //類型  DIRECT("direct"), FANOUT("fanout"), TOPIC("topic"), HEADERS("headers");
            channel.exchangeDeclare(EXCHANGE_DIRECT_INFORM, BuiltinExchangeType.DIRECT);

            //聲明隊列
            channel.queueDeclare(QUEUE_INFORM_EMAIL, true, false, true, null);

            //隊列和交換機進行綁定
            //queue 隊列名稱
            //exchange 交換機名稱
            //routingKey 路由key
            channel.queueBind(QUEUE_INFORM_EMAIL, EXCHANGE_DIRECT_INFORM, "0");

            //定義消費方法
            DefaultConsumer consumer = new DefaultConsumer(channel) {
                @Override
                public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
                    //消息id
                    long msgId = envelope.getDeliveryTag();
                    //交換機名稱
                    String exchange = envelope.getExchange();
                    //路由key
                    String routingKey = envelope.getRoutingKey();
                    //是否重新傳遞
                    boolean redeliver = envelope.isRedeliver();
                    System.out.println("msgId------" + msgId);
                    System.out.println("exchange------" + exchange);
                    System.out.println("routingKey------" + routingKey);
                    System.out.println("redeliver------" + redeliver);
                    System.out.println("接受消息爲:------" + new String(body, "utf-8"));

                }
            };
            channel.basicConsume(QUEUE_INFORM_EMAIL, true, consumer);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

Routing模式和Publish/subscibe有啥區別?

Routing模式要求隊列在綁定交換機時要指定routingkey,消息會轉發到符合routingkey的隊列。

4、Topics

Topics與Routing唯一不同的是路由key中包含匹配符,功能比Routing更加強大

 隊列綁定交換機指定通配符:
統配符規則:
中間以“.”分隔。
符號#可以匹配多個詞,

符號*可以匹配一個詞語。

5、 RPC

 RPC即客戶端遠程調用服務端的方法 ,使用MQ可以實現RPC的異步調用,基於Direct交換機實現,流程如下:
1、客戶端即是生產者就是消費者,向RPC請求隊列發送RPC調用消息,同時監聽RPC響應隊列。
2、服務端監聽RPC請求隊列的消息,收到消息後執行服務端的方法,得到方法返回的結果
3、服務端將RPC方法 的結果發送到RPC響應隊列
4、客戶端(RPC調用方)監聽RPC響應隊列,接收到RPC調用結果。

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