rabbitMq学习笔记(未完)

连接

AMQP支持在一个TCP连接上启用多个MQ通信channel,每个channel都可以被应用作为通信流。每个AMQP程序至少要有一个连接和一个channel。

        ConnectionFactory factory = new ConnectionFactory();
        Address[] addrs = new Address[] { new Address("192.168.1.10"),new Address("192.168.1.11"), new  Address("192.168.1.12") };
        factory = new ConnectionFactory();
        factory.setUsername("admin");
        factory.setPassword("admin");
        factory.setVirtualHost("/myvhost");
        factory.setConnectionTimeout(10);

        try {
            Connection connection =factory.newConnection(addrs);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        Channel channel = connection.createChannel();  

每个channel都被分配了一个整数标识,自动由Connection()类的.createChannel()方法维护。或者,你可以使用.createChannel(x)来指定channel标识,其中x是你想要使用的channel标识。通常情况下,推荐使用.createChannel()方法来自动分配channel标识,以便防止冲突。

队列声明

现在我们已经有了一个可以用的连接和channel。现在,我们的代码将分成两个应用,生产者(producer)和消费者(consumer)。我们先创建一个消费者程序,他会创建一个叫做“test_push”的队列和一个叫“sorting_room”的交换机:

String queue = "test_push";
boolean durable = true;
boolean exclusive = false;
boolean autoDelete = false;
Map<java.lang.String,java.lang.Object> arguments = null;
channel.queueDeclare(queue, durable, exclusive, autoDelete, arguments);

String exchange="sorting_room";
String type="direct";
//boolean durable=true;
boolean auto_delete=false;
//Map<java.lang.String,java.lang.Object> arguments = null;
channel.exchangeDeclare(exchange, type, durable,auto_delete, arguments);

这段代码首先,它创建了一个名叫“test_push”的队列,它是durable的(重启之后会重新建立),并且最后一个消费者断开的时候不会自动删除(auto_delete=False)。在创建durable的队列(或者交换机)的时候,将auto_delete设置成false是很重要的,否则队列将会在最后一个消费者断开的时候消失,与durable与否无关。如果将durable和auto_delete都设置成True,只有尚有消费者活动的队列可以在RabbitMQ意外崩溃的时候自动恢复。

(你可以注意到了另一个标志,称为“exclusive”。如果设置成True,只有创建这个队列的消费者程序才允许连接到该队列。这种队列对于这个消费者程序是私有的)。

还有另一个交换机声明,创建了一个名字叫“sorting_room”的交换机。auto_delete和durable的含义和队列是一样的。但是,.exchangeDeclare() 还有另外一个参数叫做type,用来指定要创建的交换机的类型(如前面列出的): fanout, direct 和 topic.

绑定

到此为止,你已经有了一个可以接收消息的队列和一个可以发送消息的交换机。不过我们需要创建一个绑定,把它们连接起来。

//String queue="test_push";
//String exchange="sorting_room";
String routing_key="jason";
channel.queueBind(queue, exchange, routing_key);

这个绑定的过程非常直接。任何送到交换机“sorting_room”的具有路由键“jason” 的消息都被路由到名为“test_push” 的队列。

接收消息调用

现在,你有两种方法从队列当中取出消息。
第一个是调用chan.basic_get(),主动从队列当中拉出下一个消息(如果队列当中没有消息,channel.basicGet()会返回None, 因此下面代码当中response.getBody() 会在没有消息的时候崩掉):

boolean autoAck = false;
GetResponse response = channel.basicGet(queue, autoAck);
String message = new String(response.getBody(), "UTF-8");
System.out.println(message);
boolean ack = true;
channel.basicAck(response.getEnvelope().getDeliveryTag(), ack);  

但是如果你想要应用程序在消息到达的时候立即得到通知怎么办?这种情况下不能使用channel.basicGet(),你需要用chan.basic_consume()注册一个新消息到达的回调。

def recv_callback(msg):
    print 'Received: ' + msg.body
chan.basic_consume(queue='po_box', no_ack=True,
callback=recv_callback, consumer_tag="testtag")
while True:
    chan.wait()
chan.basic_cancel("testtag")

chan.wait() 放在一个无限循环里面,这个函数会等待在队列上,直到下一个消息到达队列。chan.basic_cancel() 用来注销该回调函数。参数consumer_tag 当中指定的字符串和chan.basic_consume() 注册的一直。在这个例子当中chan.basic_cancel() 不会被调用到,因为上面是个无限循环…… 不过你需要知道这个调用,所以我把它放在了代码里。

需要注意的另一个东西是no_ack参数。这个参数可以传给chan.basic_get()和chan.basic_consume(),默认是false。当从队列当中取出一个消息的时候,RabbitMQ需要应用显式地回馈说已经获取到了该消息。如果一段时间内不回馈,RabbitMQ会将该消息重新分配给另外一个绑定在该队列上的消费者。另一种情况是消费者断开连接,但是获取到的消息没有回馈,则RabbitMQ同样重新分配。如果将no_ack 参数设置为true,则py-amqplib会为下一个AMQP请求添加一个no_ack属性,告诉AMQP服务器不需要等待回馈。但是,大多数时候,你也许想要自己手工发送回馈,例如,需要在回馈之前将消息存入数据库。回馈通常是通过调用chan.basic_ack()方法,使用消息的delivery_tag属性作为参数。参见chan.basic_get() 的实例代码。

发送调用

个生产者。下面的代码示例表明如何将一个简单消息发送到交换区“sorting_room”,并且标记为路由键“jason” :

msg = amqp.Message("Test message!")
msg.properties["delivery_mode"] = 2
chan.basic_publish(msg,exchange="sorting_room",routing_key="jason")

你也许注意到我们设置消息的delivery_mode属性为2,因为队列和交换机都设置为durable的,这个设置将保证消息能够持久化,也就是说,当它还没有送达消费者之前如果RabbitMQ重启则它能够被恢复。

关闭

剩下的最后一件事情(生产者和消费者都需要调用的)是关闭channel和连接:

chan.close()
conn.close()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值