python使用rabbitmq例項五,路由鍵模糊匹配
上一篇說了路由鍵的功能,通過設定路由鍵,可以將訊息傳送到相應的佇列,這裡的路由鍵是要完全匹配,比如info訊息的只能發到路由鍵為info的訊息佇列。
路由鍵模糊匹配,就是可以使用正則表示式,和常用的正則表示式不同,這裡的話“#”表示所有、全部的意思;“*”只匹配到一個詞。看完示例就能明白了。
這邊繼上一篇,還是用send.py和receive.py來實現路由鍵模糊匹配的功能。send.py表示傳送端,receive.py表示接收端。例項的功能大概是這樣:比如你有個知心好朋友,不管開心、傷心、工作上的還是生活上的事情都可以和她說;還有一些朋友可以分享開心的事情;還有一些朋友,你可以把不開心的事情和她說。
send.py程式碼分析
因為要進行路由鍵模糊匹配,所以交換機的型別要設定為topic,設定為topic,就可以使用#,*的匹配符號了。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
#!/usr/bin/env python
#coding=utf8
import
pika
connection
= pika.BlockingConnection(pika.ConnectionParameters(
'localhost' ))
channel =
connection.channel()
#定義交換機,設定型別為topic channel.exchange_declare(exchange = 'messages' ,
type = 'topic' )
#定義路由鍵
routings
= [ 'happy.work' ,
'happy.life' ,
'sad.work' ,
'sad.life' ]
#將訊息依次傳送到交換機,並設定路由鍵
for
routing in
routings:
message
= '%s message.'
% routing
channel.basic_publish(exchange = 'messages' ,
routing_key = routing,
body = message)
print message
connection.close()
|
上例中定義了四種類型的訊息,容易理解,就不解釋了,然後依次傳送出去。
receive.py程式碼分析
同樣,交換機的型別要設定為topic就可以了。從命令列接收引數的功能稍微調整了一下,就是沒有引數時報錯退出。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
#!/usr/bin/env python
#coding=utf8
import
pika, sys
connection
= pika.BlockingConnection(pika.ConnectionParameters(
'localhost' ))
channel =
connection.channel()
#定義交換機,設定型別為topic
channel.exchange_declare(exchange = 'messages' ,
type = 'topic' )
#從命令列獲取路由引數,如果沒有,則報錯退出
routings
= sys.argv[ 1 :]
if
not routings:
print
>> sys.stderr, "Usage: %s [routing_key]..."
% (sys.argv[ 0 ],)
exit()
#生成臨時佇列,並繫結到交換機上,設定路由鍵
result
= channel.queue_declare(exclusive = True )
queue_name
= result.method.queue
for
routing in
routings:
channel.queue_bind(exchange = 'messages' ,
queue = queue_name,
routing_key = routing)
def
callback(ch, method, properties, body):
print
" [x] Received %r"
% (body,)
channel.basic_consume(callback, queue = queue_name, no_ack = True )
print
' [*] Waiting for messages. To exit press CTRL+C'
channel.start_consuming()
|
開啟四個終端,一個執行如下,表示任何事情都可以和她說:
python receive.py "#"
另外一個終端 執行如下,表示可以和她分享開心的事:
python receive.py "happy.*"
第三個執行如下,表示工作上的事情可以和她分享:
python receive.py "*.work"
最後一個執行python send.py。結果不難想象出來,就不貼出來了。
在參考文章的最後面有提到幾個難點,筆者自己做了測試,供大家參考:
1、傳送資訊時,如果不設定路由鍵,那麼路由鍵設定為”*”的接收端是否能接收到訊息?
傳送資訊時,如果不設定路由鍵,預設是表示廣播出去,理論上所有接收端都可以收到訊息,但是筆者試了下,路由鍵設定為"*"的接收端收不到任何訊息。 只有傳送訊息時,設定路由鍵為一個詞,路由鍵設定為"*"的接收端才能收到訊息。在這裡,每個詞使用"."符號分開的。
2、傳送訊息時,如果路由鍵設定為”..”,那麼路由鍵設定為”#.*”的接收端是否能接收到訊息?如果傳送訊息時,路由鍵設定為一個詞呢?
兩種情況,筆者都測試過了,可以的。
3、”a.*.#” 和”a.#”的區別
"a.#"只要字串開頭的一個詞是a就可以了,比如a、a.haha、a.haha.haha。而這樣的詞是不行的,如abs、abc、abc.haha。 "a.*.#"必須要滿足a.*的字串才可以,比如a.、a.haha、a.haha.haha。而這樣的詞是不行的,如a。
弄完上面的這些個問題,筆者覺著有些鑽牛角尖了,不過既然官方有提出來,就鑽一回吧。