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

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