1,簡介
RabbitMQ(Rabbit Message Queue)是流行的開源消息隊列系統,用erlang語言開發。
1.1關鍵詞說明:
Broker:消息隊列服務器實體。
Exchange:消息交換機,它指定消息按什么規則,路由到哪個隊列。
Queue:消息隊列載體,每個消息都會被投入到一個或多個隊列。
Binding:綁定,它的作用就是把exchange和queue按照路由規則綁定起來。
Routing Key:路由關鍵字,exchange根據這個關鍵字進行消息投遞。
vhost:虛擬主機,一個broker里可以開設多個vhost,用作不同用戶的權限分離。
producer:消息生產者,就是投遞消息的程序。
consumer:消息消費者,就是接受消息的程序。
channel:消息通道,在客戶端的每個連接里,可建立多個channel,每個channel代表一個會話任務。
Exchange:消息交換機,它指定消息按什么規則,路由到哪個隊列。
Queue:消息隊列載體,每個消息都會被投入到一個或多個隊列。
Binding:綁定,它的作用就是把exchange和queue按照路由規則綁定起來。
Routing Key:路由關鍵字,exchange根據這個關鍵字進行消息投遞。
vhost:虛擬主機,一個broker里可以開設多個vhost,用作不同用戶的權限分離。
producer:消息生產者,就是投遞消息的程序。
consumer:消息消費者,就是接受消息的程序。
channel:消息通道,在客戶端的每個連接里,可建立多個channel,每個channel代表一個會話任務。
1.2消息隊列運行機制:
(1)客戶端連接到消息隊列服務器,打開一個channel。
(2)客戶端聲明一個exchange,並設置相關屬性。
(3)客戶端聲明一個queue,並設置相關屬性。
(4)客戶端使用routing key,在exchange和queue之間建立好綁定關系。
(5)客戶端投遞消息到exchange。
(2)客戶端聲明一個exchange,並設置相關屬性。
(3)客戶端聲明一個queue,並設置相關屬性。
(4)客戶端使用routing key,在exchange和queue之間建立好綁定關系。
(5)客戶端投遞消息到exchange。
(6)exchange接收到消息后,就根據消息的key和已經設置的binding,將消息投遞到一個或多個隊列里。
注:在聲明一個隊列后,如果將其持久化,則下次不需要進行聲明,因為該隊列已經在rabbitMQ中了!!!
例如下面的例子中都為首次聲明一個隊列!!!
1.3exchange類型:
1.Direct交換機
特點:依據key進行投遞
例如綁定時設置了routing key為”hello”,那么客戶端提交的消息,只有設置了key為”hello”的才會投遞到隊列。
2.Topic交換機
特點:對key模式匹配后進行投遞,符號”#”匹配一個或多個詞,符號”*”匹配一個詞
例如”abc.#”匹配”abc.def.ghi”,”abc.*”只匹配”abc.def”。
3.Fanout交換機
特點:不需要key,采取廣播模式,一個消息進來時,投遞到與該交換機綁定的所有隊列
2.構建環境
2.1在windows環境下安裝rabbitmq,教程如下:
2.2安裝pika模塊
python使用rabbitmq服務,可以使用現成的類庫pika、txAMQP或者py-amqplib,這里選擇了pika。
在命令行中直接使用pip命令:
pip install pika
3.示例測試
實例的內容就是從send.py發送消息到rabbitmq,receive.py從rabbitmq接收send.py發送的信息。
P表示produce,生產者的意思,也可以稱為發送者,實例中表現為send.py;
C表示consumer,消費者的意思,也可以稱為接收者,實例中表現為receive.py;
中間紅色的表示隊列的意思,實例中表現為hello隊列。
send.py
1 #!/usr/bin/env python3 2 # -*- coding: utf-8 -*- 3 4 import pika 5 import random 6 7 # 新建連接,rabbitmq安裝在本地則hostname為'localhost' 8 hostname = '192.168.1.133' 9 parameters = pika.ConnectionParameters(hostname) 10 connection = pika.BlockingConnection(parameters) 11 12 # 創建通道 13 channel = connection.channel() 14 # 聲明一個隊列,生產者和消費者都要聲明一個相同的隊列,用來防止萬一某一方掛了,另一方能正常運行 15 channel.queue_declare(queue='hello') 16 17 number = random.randint(1, 1000) 18 body = 'hello world:%s' % number 19 # 交換機; 隊列名,寫明將消息發往哪個隊列; 消息內容 20 # routing_key在使用匿名交換機的時候才需要指定,表示發送到哪個隊列 21 channel.basic_publish(exchange='', routing_key='hello', body=body) 22 print " [x] Sent %s" % body 23 connection.close()
receive.py
1 #!/usr/bin/env python3 2 # -*- coding: utf-8 -*- 3 4 import pika 5 6 hostname = '192.168.1.133' 7 parameters = pika.ConnectionParameters(hostname) 8 connection = pika.BlockingConnection(parameters) 9 10 # 創建通道 11 channel = connection.channel() 12 channel.queue_declare(queue='hello') 13 14 15 def callback(ch, method, properties, body): 16 print " [x] Received %r" % (body,) 17 18 # 告訴rabbitmq使用callback來接收信息 19 channel.basic_consume(callback, queue='hello', no_ack=True) 20 21 # 開始接收信息,並進入阻塞狀態,隊列里有信息才會調用callback進行處理,按ctrl+c退出 22 print ' [*] Waiting for messages. To exit press CTRL+C' 23 channel.start_consuming()
我們先運行send.py發送消息:
再運行receive.py接收消息: