OpenStack的oslo_messaging组件使用

来源:互联网 发布:广西广电网络上不了网 编辑:程序博客网 时间:2024/03/29 14:41

        首先给出OpenStack的RPC通信的代码调用架构。


OpenStack消息通信架构图

        OpenStack层封装callcast接口用于远程调用RPCserver上的方法,这些方法都是构造RPCserverendpoints内的方法。远程调用时,需要提供一个字典对象来指明调用的上下文,调用方法的名字和传递给调用方法的参数(用字典表示)。如:

cctxt =self.client.prepare(vesion=’2.0’)

cctxt.cast(context,‘build_instances’, **kw)

        通过cast方式的远程调用,请求发送后就直接返回了;通过call方式远程调用,需要等响应从服务器返回。

        下面我们介绍RPC-server和PRC-client的创建,以及对cast和call的远程调用。

-------------------------------------------------- RPC-server.py-----------------------------------------

fromoslo_config import cfg

importoslo_messaging

importtime

classServerControlEndpoint(object):

 

    target =oslo_messaging.Target(namespace='control',

                                  version='2.0')

    def __init__(self, server):

        self.server = server

    def stop(self, ctx):

        print“------ServerControlEndpoint. stop --------”

        if self.server:

            self.server.stop()

 

classTestEndpoint(object):

    def test(self, ctx, arg):

        print“------ TestEndpoint.test --------”

        return arg

 

transport= oslo_messaging.get_transport(cfg.CONF)

#cfg对象中,读取transport_url,rpc_backendcontrol_exchange信息构

#Transport对象,其中rpc_backendcontrol_exchange的默认值分别为:

#’rabbit’’openstack’

target= oslo_messaging.Target(topic='test', server='server1')

#在构造RPC-servertarget时,需要topicserver参数,exchange参数可

#选。

endpoints= [

    ServerControlEndpoint(None),

    TestEndpoint(),

]

#一个RPC-server可以暴露多个endpoint,每个endpoint包含一组方法,这组

#方法可以被RPC-client通过某种Transport对象远程调用。

server= oslo_messaging.get_rpc_server(transport, target, endpoints,

                                      executor='blocking')

#构造RPC-server对象,其中executor有两种方式:blockingeventlet

#blocking:用户调用start函数后,在start函数中开始请求处理循环,用户线程

#阻塞,处理下一个请求。直到用户调用了stop函数后,这个处理循环才退出。

#消息的接受和分发处理都在调用start函数的线程中完成的。

#eventlet:在这种方式中,会有一个协程GreenThread来处理消息的接收,然后

#有其他不同二屌GreenThread来处理不同消息的分发处理。调用start的用户

#线程不会被阻塞。

#在这里我们使用blocking方式。

try:

    server.start()

    while True:

        time.sleep(1)

exceptKeyboardInterrupt:

   print("Stopping server")

 

server.stop()

server.wait()

 

------------------------------------------------------------ RPC-client.py --------------------------------------------

fromoslo_config import cfg

importoslo_messaging as messaging

 

transport= messaging.get_transport(cfg.CONF)

target= messaging.Target(topic='test')

#在构造RPC-clienttarget时,需要topic参数,其他可选。

client= messaging.RPCClient(transport, target)

ret= client.call(ctxt = {},

                  method = 'test',

                  arg = 'myarg')

#远程调用时,需要提供一个字典对象来指明调用的上下文,调用方法的名字和传

#递给调用方法的参数(用字典表示)

cctxt= client.prepare(namespace='control', version='2.0')

#prepare函数用于修改RPC-client对象的Target对象的属性。

cctxt.cast({},'stop')

 

[root@jun python]# python oslo_server.py

        由于这里Transport采用rabbit的方式,所以可使用rabbitmqctl命令查询相关信息。此时执行oslo_server.py的进程处于阻塞状态等待消息的到来。

[root@jun python]# rabbitmqctl list_consumers | grep test

test   <rabbit@jun.2.1231.0>  1       true    0      []

test.server1   <rabbit@jun.2.1231.0>  2       true    0      []

test_fanout_1064b7923baf4d4b9e4e56329f079c12    <rabbit@jun.2.1231.0>   3      true    0       []

        执行pythonoslo_client.py后,处于阻塞的oslo_server.py的进程打印信息。

[root@jun python]# python oslo_server.py

------ TestEndpoint.test --------

------ ServerControlEndpoint. stop --------

        总结:今天主要介绍了RPC-server和RPC-client的构建,其中涉及call和cast接口的使用。OpenStack正是主要通过这两个接口进行远程调用RPC-server上的方法的。后面几篇文章我们将结合OpenStack源码具体分析RPC-server和RPC-client的使用。

0 0