nova中的rpc模块并没有直接使用kombu,而是又对它进行了一次封装,封装的主要是发送者和接收者,在nova中,封装成了两个 类:Publisher和ConsumerBase,并且根据这两个类派生出了DirectPublisher, DirectConsumer, TopicPublisher, TopicConsumer等子类,使操作更加的方便。
一直就觉得Exchange和发送者的关系很密切,或者说发送者只需要和Exchange打交道,而接收者和Queue的关系很密切,在这里证实了 这一点:Publisher中封装了一个Exchange对象,而ConsumerBase中封装了Queue对象。看下面两个类图:
接收者派生系:
发送者派生系:
根据类图可以看到,根据Exchange的类型不同,将发送者和接收者分别分为了三类:Direct, Topic, Fanout
再来看一下Connection类:
amqp模块的Pool类是一个连接池,存放Connection对象,ConnectionContext是从连接池中取出Connection 对象,然后进行一下封装,添加上__enter__()和__exit()__方法,可以使用with来安全的创建和释放连接。
基本上使用这些就可以实现消息的发送和接收了,用这些基本的类来看一个简单的例子:
#! -*- coding:cp936 -*-
”’send.py”’
from impl_kombu import *
connection=Connection(None)#创建了一个BrokerConnection对象
channel=connection.get_channel()#得到这个连接的channel
# 生成了一个Exchange对象,name==’nova’,type=’topic’
# 生成了一个Producer对象,exchange==self.exchange,channel==channel,topic==’compute’
publisher=TopicPublisher(None,channel,’compute’)
publisher.send(‘hello nova’)
#! -*- coding:cp936 -*-
”’recv.py”’
from impl_kombu import *
connection=Connection(None)#创建了一个BrokerConnection对象
channel=connection.get_channel()#得到这个连接的channel
def callback(message):
print message
consumer=TopicConsumer(None,channel,’compute’,callback,”)
consumer.consume()
while True:
connection.connection.drain_events()
当然,nova中不是直接这样使用的,而是对这些基本的类用模块中的方法(上面类图中蓝色的字体)又进行了一次封装,在外部直接调用这些方法就可以了。