RabbitMQ - 发布订阅模式

Publish/Subscribe 模式

之前讲的 工作队列模式,一个工作队列中的任务只能分发给一个 消费者。而我们今天要聊的这个 发布/订阅模式 有着更复杂的工作模式, 他可以将一个消息发给多个消费者。如下图所示:


Exchanges

从上面的图中,我们可以看到明显比之前的工作队列模式,多了一个组成部分(即图中的 x ),他就是 exchanges,那么这个东西到底是什么呢? 这里引用官网的一句话 Exchange is like JFK airport,这是个形象的比喻。下面会具体说明。

full messaging model

核心思想就是生产者不再发消息给 queue, 而是发给 exchanges,并且在这个过程中,生产者并不知道把消息发到了哪个 queue。取而代之的是,生产者将消息发给了 exchanges(exchanges 负责接收生产者发来的消息,并将消息传送到队列当中),而exchanges 要根据某种规则来判断怎么处理接收过来的消息(是把消息发给一个队列,还是发给多个队列, 或者其他)。而这些规则被声明成了 exchange type;

exchanges type

  1. direct
  2. topic
  3. headers
  4. fanout

示例程序

下面代码 使用了 fanout(负责把消息以类似广播的形式,发送到多个队列) 类型的 exchangs,代码较之前的代码做了微小改动。

/**
 * 生产者
 * @author Administrator
 *
 */
   public class Producer {

	private static final String EXCHANGE_NAME = "logs";
	
	public static void main(String[] args) {
		ConnectionFactory factory = new ConnectionFactory();
	    factory.setHost("localhost");
	    try (Connection connection = factory.newConnection();
	        Channel channel = connection.createChannel()) {
	        channel.exchangeDeclare(EXCHANGE_NAME, "fanout");

	        String message = "info: Hello World!";
	        channel.basicPublish(EXCHANGE_NAME, "", null, message.getBytes("UTF-8"));
	        System.out.println(" [x] Sent '" + message + "'");
	    }catch(Exception e){
	    	e.printStackTrace();
	    }
	}
	
}
**
 * 消费者
 * @author Administrator
 *
 */
public class Consumer {

	private static final String EXCHANGE_NAME = "logs";

	  public static void main(String[] argv) throws Exception {
	    ConnectionFactory factory = new ConnectionFactory();
	    factory.setHost("localhost");
	    Connection connection = factory.newConnection();
	    Channel channel = connection.createChannel();

	    channel.exchangeDeclare(EXCHANGE_NAME, "fanout");
	    String queueName = channel.queueDeclare().getQueue();
	    channel.queueBind(queueName, EXCHANGE_NAME, "");

	    System.out.println(" [*] Waiting for messages. To exit press CTRL+C");

	    DeliverCallback deliverCallback = (consumerTag, delivery) -> {
	        String message = new String(delivery.getBody(), "UTF-8");
	        System.out.println(" [x] Received '" + message + "'");
	    };
	    channel.basicConsume(queueName, true, deliverCallback, consumerTag -> { });
	  }
	
}

转载于:https://my.oschina.net/u/3984985/blog/3035149

表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符
相关推荐
©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页