五、rabbitMQ fanout exchange Publish/Subscribe

来源:互联网 发布:autodesk绘图软件 编辑:程序博客网 时间:2024/05/07 22:27

前面的我们的消息只发到一条队列中,最终被一个消费者处理。现在我们的的需求是一条消息能发到多个队列里,从而被多个消费者处理,这种模型称为“发布/订阅”。

rabbitMQ中其实生产者不是将信息直接送入队列,而是叫给了exchange 由exchange完成信息的交换转发。交换是一件很简单的事。一方面,它接收来自生产者的信息,另一边则推他们排队。Exchange必须知道如何处理接收到的消息。



消费者:

运行2个实例

package test1;import com.rabbitmq.client.*;import java.io.IOException;public class consumer {    private final static String EXCHANGE_NAME = "logs_exchange";    public static void main(String[] args) {        ConnectionFactory factory = new ConnectionFactory();        factory.setUsername("guest");        factory.setPassword("guest");        factory.setHost("127.0.0.1");        factory.setVirtualHost("/");        factory.setPort(5672);        try {            final Connection connection = factory.newConnection();            final Channel channel = connection.createChannel();            channel.exchangeDeclare(EXCHANGE_NAME, "fanout");//不存在,创建exchange            String queueName = channel.queueDeclare().getQueue();//创建队列            channel.queueBind(queueName, EXCHANGE_NAME, "");//队列绑定到exchange            Consumer consumer = new DefaultConsumer(channel) {                @Override                public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body)                        throws IOException {                    String message = new String(body, "UTF-8");                    System.out.println(message);                }            };            boolean autoAck = true;//自动返回设置为false            channel.basicConsume(queueName, autoAck, consumer);            Thread.sleep(600 * 1000);            channel.close();            connection.close();        } catch (Exception e) {            e.printStackTrace();        }    }}

生产者

package test1;import com.rabbitmq.client.*;public class producter{    private final static String QUEUE_NAME = "hello";    private final static String EXCHANGE_NAME = "logs_exchange";    public static void main( String[] args )    {        ConnectionFactory factory = new ConnectionFactory();        factory.setUsername("guest");        factory.setPassword("guest");        factory.setHost("127.0.0.1");        factory.setVirtualHost("/");        factory.setPort(5672);        try {            Connection connection = factory.newConnection();            Channel channel =  connection.createChannel();            channel.exchangeDeclare(EXCHANGE_NAME, "fanout");//不存在,创建exchange            channel.basicPublish(EXCHANGE_NAME, "", null, ("Hello World").getBytes());//消息发布到exchange            channel.close();            connection.close();        }  catch (Exception e) {            e.printStackTrace();        }    }}

运算时截图:




注:


一、我们对交换一无所知,但仍然能够向队列发送消息。这是可能的,因为使用的是默认的交换,通过空字符串(“”)来标识它们。
回想一下我们之前如何发布消息:channel.basicPublish("", "hello", null, message.getBytes());

第一个参数是交换的名称。空字符串表示默认或无名的交换。





二、channel.exchangeDeclare(EXCHANGE_NAME, "fanout");中的fanout是一种交换的类型,exchange交换类型有:direct, topic, headers 和fanout.