RabbitMQ使用笔记

官网     http://www.rabbitmq.com/
客户端     https://pika.readthedocs.org/en/latest/


RabbitMQ安装见另外一篇文章python rpc framework ---- callme/multiprocessing.managers

分享 http://download.csdn.net/detail/xiarendeniao/5781457


1.概念:

channel        我理解就是每个连接对应的一个操作标识(A Channel is the primary communication method for interacting with RabbitMQ. It is recommended that you do not directly invokethe creation of a channel object in your application code but ratherconstruct the a channel by calling the active connection’s channel()method.)
exchange    交换区,一个用于分发数据的虚拟的概念(将queue与exchange绑定后,往exchange发送的消息会根据路由规则进入相应的已绑定的queue)
queue        数据队列

exchange和queue的关系:
    In RabbitMQ a message can never be sent directly to the queue, it always needs to go through an exchange.
    A default exchange identified by an empty string: This exchange is special ? it allows us to specify exactly to which queue the message should go. The queue name needs to be specified in the routing_key parameter.
    当exchange为空字符串时,basic_publish发出的消息会发往以routing_key为名字的queue里面去。(此时,routing_key不再是普通路由过滤条件,而是queue的名字)

2.六种使用模式 见图“rabbitmq-1.jpg”


    当多个消费者连接到同一个queue时,queue里面同一个消息只会被一个消费者拿到
    如需要一个消息被多个消费者拿到,可用exchange绑定多个queue,消费者跟这些queue一一对应,那么生产者往这个exchange发送的消息会被路由到多个queue里面、接着被多个消费者都拿到(模式3)。
    消费者获取消息时可指定是否需要ack(channel.basic_consume(callback,queue=queue_name,no_ack=True)):
          是,当消费者ack以后消息才会从queue里面删除,如果在ack之前消费者挂掉了,该消息会被其他消费者拿到;
          否,当消费者一拿到消息,消息就会从queue里面删除
    当使用六种模式中的第二种时,可能会出现负载不均衡的情况:默认分发策略是一个消费者发一个任务,不管它有多少没处理完;当消费者拿到比较耗时的任务时就不合理了。
    解决办法:channel.basic_qos(prefetch_count=1) This tells RabbitMQ not to give more than one message to a worker at a time. Or, in other words, don't dispatch a new message to a worker until it has processed and acknowledged the previous one.

     擦,去年在互动百科做那个相关性分析项目时就有这个问题,一直以为无解呢!当时用的是activemq(见另一篇文章python--memcached---activemq),当一个消费者程序启动比较快,另几个启动晚一些的时候,queue里面的几个任务就都被先报到的消费者预订了。结果是先到的消费者累死累活,后到的消费者闲着没事干。

     对于模式6,不明白correlation_id和reply_to有什么必要性,返回结果的queue和message的标识由业务逻辑控制打入message内部完全没问题嘛...这两个参数反正是由服务端(姑且这样称呼吧,其实也是一个从queue中取message做计算并往另一个queue塞结果message的程序)的业务逻辑解析的,又不是RabbitMQ内部针对这两个属性会做什么处理!相比而言,我觉得delivery_mode才有意义,RabbitMQ会把指定该属性为2的message持久化到硬盘上。


3.exchange的类型:
    fanout    简单分发,message直接输出到已经绑定的queue
    direct    定向分发,根据routing_key选择性输出到已绑定的(指定了相同routing_key的所有)queue
    topic    多重选择输出,和direct类似,只是routing_key由.连接单词组成、并可用*和#作匹配
    可由topic实现前两种类型
 
4.数据持久化:
    queue持久化        channel.queue_declare(queue='task_queue', durable=True)
    message持久化    channel.basic_publish(exchange='',
                      routing_key="task_queue",
                      body=message,
                      properties=pika.BasicProperties(
                         delivery_mode = 2, # make message persistent
                      ))
    如上操作还是可能会丢数据:服务器在rabbitmq收到数据和写盘结束的时间区间内挂掉时( http://www.rabbitmq.com/tutorials/tutorial-two-python.html)

    官网说的解决办法是对于发数据的程序(生产者)需要做事务处理(channel使用transaction模式),或者使用确认机制(confirm mode)。且,两者不可同时使用(http://www.rabbitmq.com/confirms.html


客户端

1.AMQP客户端如何获取Queue中消息的数量?

import pika

def on_callback(msg):
    print msg

params = pika.ConnectionParameters(
        host='localhost',
        port=5672,
        credentials=pika.credentials.PlainCredentials('guest', 'guest'),
    )

# Open a connection to RabbitMQ on localhost using all default parameters
connection = pika.BlockingConnection(parameters=params)

# Open the channel
channel = connection.channel()

# Declare the queue
channel.queue_declare(
        callback=on_callback,
        queue="test",
        durable=True,
        exclusive=False,
        auto_delete=False
    )

# ...

# Re-declare the queue with passive flag
channel.queue_declare(
        callback=on_callback,
        queue="test",
        durable=True,
        exclusive=False,
        auto_delete=False,
        passive=True
    )
<Method(['frame_type=1', 'channel_number=1', "method=<Queue.DeclareOk(['queue=test', 'message_count=0', 'consumer_count=0'])>"])>
<Method(['frame_type=1', 'channel_number=1', "method=<Queue.DeclareOk(['queue=test', 'message_count=0', 'consumer_count=0'])>"])>
http://stackoverflow.com/questions/8192584/get-queue-size-in-pika-amqp-python

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值