oslo openstack

英文原文:http://docs.OpenStack.org/developer/oslo.messaging/index.html
https://wiki.openstack.org/wiki/Oslo/Messaging

目录

1.Transport
2.Executors
3.Target
4.RPC Server
5.RPC Client
6.Notifier
7.Notification Driver
8.Notification Listener
9.Serializer
10.Exceptions
11.Configuration Options
12.Testing Configurations
13.Available Drivers
14.Supported Messaging Drivers
15.AMQP 1.0 Protocol Driver Deployment Guide
16.Pika Driver Deployment Guide
17.ZeroMQ Driver Deployment Guide
18.Guide for Transport Driver Implementors
19.Frequently Asked Questions
20.Contributing

写在前面的话:

1.关于oslo库:
主要两种独立的API: 1, oslo.messaging.rpc(实现了客户端-服务器远程过程调用; 2,oslo.messaging.notify(实现了事件的通知机制)

另外,oslo.messaging.notify中的通用的transport采用的oslo.messaging.rpc中的。

2.olso的目标:
先说在olso之前的问题:
(1)版本兼容性问题
(2)之前openstack的消息机制基于AMQP的,这对不懂AMQP的开发者困难。
(3)基于AMQP的不同实现如rabbitMQ,Qpid的接口问题(我的理解是可能不同的实现的一些小的接口不同,在使用时,会造成问题?)
(4)为了支持非AMQP协议,需要一个抽象,将AMQP和非AMQP综合起来,形成一个统一的接口,屏蔽这些协议问题。

目标就是解决上面的问题,提供一个消息通信的抽象接口,屏蔽底层的具体通信的实现细节,不管是AMQP还是非AMQP,还是AMQP的不同的实现的库等等这些问题,具体的olso API语句的具体后端称为 transport drivers。

3.一些基本概念
(1)Server:提供RPC服务
(2)client : 激活Server 方法的
(3)exchagne: 交换器
(4)topic: RPC 接口标识;
(5)Namespace :服务器针对某个topic暴露出一系列的方法,这些方法都处于一个namespace中。
(6)method: 有名字的方法,有一系列的命名参数。
(7)transport : 底层的消息系统,可将RPC请求传递到server中,并将返回数据传递给client.

一、Transport

1. oslo_messaging.get_transport(conf, url=None, allowed_remote_exmods=None, aliases=None)

参数意义:

conf (cfg.ConfigOpts) –用户配置

url (str or TransportURL) – a transport URL

allowed_remote_exmods (list) – a list of modules which a client using this transport will deserialize remote exceptions from(会引起exception的模块列表)

aliases (dict) – DEPRECATED: A map of transport alias to transport name

工厂方法,获取Transport对象。该方法会根据从用户配置文件中获取transport配置信息+transport URL(可选)构造Transport 对象。
如果提供了transport URL(该URL优先级最高),构造时会采用该URL。如果没有提供URL,但是用户配置文件中提供了URL,则该URL成为该方法中的url实参。如果两者都没有,则会从独立的配置文件中获取该URL值。

一个transport URL的例子:

rabbit://me:passwd@host:5672/virtual_host

transport URL可为string类型或是一个TransportURL 对象

2.class oslo_messaging.Transport(driver)

messaging transport类。该类为操作底层messaging transport driver的句柄(和driver的关系就像 文件句柄和文件的关系,使用文件句柄来操作文件,而将文件的具体实现封装起来)。该类只有一个conf成员变量,该变量类型为cfg.ConfigOpts,用来构造具体的transport对象。

3.class oslo_messaging.TransportURL(conf, transport=None, virtual_host=None, hosts=None, aliases=None, query=None)

一个经过解析的transport URL,具体形式如下:

transport://user:pass@host:port[,userN:passN@hostN:portN]/virtual_host?query


Parameters:
conf (oslo.config.cfg.ConfigOpts) – a ConfigOpts instance
transport (str) – a transport name for example ‘rabbit’
virtual_host (str) – a virtual host path for example ‘/’
hosts (list) – a list of TransportHost objects
aliases (dict) – DEPRECATED: a map of transport alias to transport name
query (dict) – a dictionary of URL query parameters

TransportURL的类方法parse(conf, url=None, aliases=None)可以解析url然后返回一个TranportURL对象。


Parameters: 
conf (oslo.config.cfg.ConfigOpts) – a ConfigOpts instance
url (str) – The URL to parse
aliases (dict) – A map of transport alias to transport name
Returns:    
A TransportURL

假如URL为:

transport://user:pass@host:port[,userN:passN@hostN:portN]/virtual_host?query

解析步骤如下:

  1. 首先,使用‘,’分割字符串(为了支持多主机)
  2. 所有的主机都应该指定username/password。如果没有指定,则相应的值会被忽略
如:user:pass@host1:port1,host2:port2
解析成如下样子:
[
  {"username": "user", "password": "pass", "host": "host1:port1"},
  {"host": "host2:port2"}
]

4.class oslo_messaging.TransportHost(hostname=None, port=None, username=None, password=None)

代表解析过的transport URL中的主机元素

5.oslo_messaging.set_transport_defaults(control_exchange)


Parameters: control_exchange (str) – the default exchange under which topics are scoped

设置默认的messaging transport配置

二、Executors

Executors控制Server在收到message后如何调度处理,这种调度可以是同步的也可以是异步的。

一个同步的executors会在server线程中处理message,这意味着sever一次只能处理一个message。在当前消息处理完后,才会接着处理其他的收到的message。例如,对于一个RPCServer,一次只能激活一次调用。同步的executors保证了消息的处理顺序和它们的到达顺序相同。

异步的executor会并发的处理收到的message,server不会被当前正在处理的message阻塞,依然能够响应收到的消息。但是各个消息的处理顺序没有保证。该executor可配置一次可以处理的消息的最大个数。

下面主要说几种可用的executor:

1.blocking

executor使用caller同步执行调用。该executor为调用者提供了一个接口(方法的执行会在调用者所在的线程中)

2.eventlet

使用绿色线程池(协程)来异步执行调用。
关于绿色线程池:见https://docs.python.org/dev/library/concurrent.futures.html and http://eventlet.net/doc/modules/greenpool.html

3.threading

使用普通的线程池来异步执行调用。
https://docs.python.org/dev/library/concurrent.futures.html

三、Target

指定消息的目的地。Target封装了一个消息目的地的相关信息,或是对于server而言,描述了该server所监听的消息类型。

1.class oslo_messaging.Target(exchange=None, topic=None, namespace=None, version=None, server=None, fanout=None, legacy_namespaces=None)

Parameters:
exchange (str) – A scope for topics. Leave unspecified to default to the control_exchange configuration option.
topic (str) – A name which identifies the set of interfaces exposed by a server. Multiple servers may listen on a topic and messages will be dispatched to one of the servers selected in a best-effort round-robin fashion (unless fanout is True).
namespace (str) – Identifies a particular RPC interface (i.e. set of methods) exposed by a server. The default interface has no namespace identifier and is referred to as the null namespace.
version (str) – RPC interfaces have a major.minor version number associated with them. A minor number increment indicates a backwards compatible change and an incompatible change is indicated by a major number bump. Servers may implement multiple major versions and clients may require indicate that their message requires a particular minimum minor version.
server (str) – RPC Clients can request that a message be directed to a specific server, rather than just one of a pool of servers listening on the topic.
fanout (bool) – Clients may request that a copy of the message be delivered to all servers listening on a topic by setting fanout to True, rather than just one of them.
legacy_namespaces (list of strings) – A server always accepts messages specified via the ‘namespace’ parameter, and may also accept messages defined via this parameter. This option should be used to switch namespaces safely during rolling upgrades.

2.Target Versions

Target 版本号使用Major.Minor的形式。对于特定版本号为X.Y的消息,能出来还消息的Server的版本号为A.B,则A==X,并且B>Y.

四、RPC Server

RPC服务器暴露出一些endpoint,每个endpoint包涵一系列的可被远程客户端通过transport调用的方法。

创建RPC服务器,你需要提供transport,target和endpoints列表。其中transport可通过get_transport方法获取,如下:

transport = messaging.get_transport(conf)
根据用户messaging配置,装载合适额transport driver.

target用来表述RPC 服务器监听的topic,server名称和server监听的exchange。
可能有多个server同时监听相同的topic(和exchange)。参见RPC Client,了解RPC 请求在多个server中的分配。

每个endpoint对象有target属性,该target可能有namespace和version域,默认情况下,namespace为null,version=1.0。接收到的方法调用将会分配给第一个匹配到的endpoint。

在RPC方法调用时,第一个参数总是请求的上下文,由RPC客户端提供。其他的参数是被调用方法的参数,由客户端提供。Endpoint方法可能有返回值,该种情况下,RPC服务器通过transport返回返回值给该RPC客户端。

executor控制RPC server接受到message后的处理调度方式。默认情况下,使用最简单的executor,即blocking exector.

Note: If the “eventlet” executor is used, the threading and time library need to be monkeypatched.(不知道怎么翻译)

RPC回复操作是best-effor方式,即尽力交付。当reply被messaging transport接收到的时候,server就认为reply已经成功发送出去了。Server不保证RPC客户端一定会处理reply.如果reply 发送失败,则将此记录在日志中,server继续处理接受到的消息(即,server不解决发送失败问题,出现问题,管理员查看日志,解决问题)

RPC调用传入的方法参数和方法返回的返回值都是python primitive类型。但是,message中的数据编码方式可能不是primitvie形式,例如,message中的payload可能是一个ASCII编码的String的JSON数据,而本来应该是一个字典类型。serializer对象用来将message转化成primitive类型,或是将primitive类型转换成标准的message payload形式。

RPC 服务器主要方法:start,stop,wait方法,用法启动、停止服务,或是在server停止后,等待所有进行中的请求完成。

1.一个简单的PRC Server的例子

from oslo_config import cfg
import oslo_messaging
import time

class ServerControlEndpoint(object):

    target = oslo_messaging.Target(namespace='control',
                                   version='2.0')

    def __init__(self, server):
        self.server = server

    def stop(self, ctx):
        if self.server:
            self.server.stop()

class TestEndpoint(object):

    def test(self, ctx, arg):
        return arg

transport = oslo_messaging.get_transport(cfg.CONF)
target = oslo_messaging.Target(topic='test', server='server1')
endpoints = [
    ServerControlEndpoint(None),
    TestEndpoint(),
]
server = oslo_messaging.get_rpc_server(transport, target, endpoints,
                                       executor='blocking')
try:
    server.start()
    while True:
        time.sleep(1)
except KeyboardInterrupt:
    print("Stopping server")

server.stop()
server.wait()

方法说明:

oslo_messaging.get_rpc_server(transport, target, endpoints, executor='blocking', serializer=None, access_policy=None)
Construct an RPC server.

Parameters: 
transport (Transport) – the messaging transport
target (Target) – the exchange, topic and server to listen on
endpoints (list) – a list of endpoint objects
executor (str) – name of message executor - available values are ‘eventlet’, ‘blocking’ and ‘threading’
serializer (Serializer) – an optional entity serializer
access_policy (RPCAccessPolicyBase) – an optional access policy. Defaults to LegacyRPCAccessPolicy

2.关于access_policy(RPCAccessPolicyBase)

RPCAccessPolicyBase access_policy:决定endpont的那个方法会通过RPC调用。有如下几种:
(1)class oslo_messaging.LegacyRPCAccessPolicy : 允许RPC调用endpoint的所有的可调用的方法,包括priviate方法(使用__前缀的方法)
(2)class oslo_messaging.DefaultRPCAccessPolicy:默认的access policy,可防止调用private方法。
(3)class oslo_messaging.ExplicitRPCAccessPolicy:Policy which requires decorated endpoint methods to allow dispatch(不知道什么意思)

3.RPCDispatcher

class oslo_messaging.RPCDispatcher(endpoints, serializer, access_policy=None) :

了解RPC消息的message dispatcher。RPCDispatcher 查看message的namespace,version , method value,并在server的endpoints列表中找到和该message匹配的endpoint。

4. MessageHandlingServer

class oslo_messaging.MessageHandlingServer(transport, dispatcher, executor=’blocking’) : 处理message的服务器。

方法:

reset():Reset service.

start(*args, **kwargs):该方法调用后,server开始poll,从transport中接收message,然后转发给dispatcher.该message处理过程一直进行,直到stop方法被调用。executor决定server的IO处理策略。可能会是用一个新进程、新协程来做poll操作,或是直接简单的在一个循环中注册一个回调。同样,executor也决定分配message的方式,是在一个新线程中dispatch或是..... 

stop(*args, **kwargs):当调用stop之后,新的message不会被处理。但是,server可能还在处理一些之前没有处理完的message,并且底层driver资源也还一直没有释放。

wait(*args, **kwargs):在stop调用之后,可能还有message正在被处理,使用wait方法来阻塞当前进程,直到所有的message都处理完成。之后,底层的driver资源会释放。

5.oslo_messaging.expected_exceptions(*exceptions)

用来修饰endpoint的方法,用来说明该方法可能抛出某种异常,而该异常属于正常情况。

Decorator for RPC endpoint methods that raise expected exceptions.

Decorator for RPC endpoint methods that raise expected exceptions.

Marking an endpoint method with this decorator allows the declaration of expected exceptions that the RPC server should not consider fatal, and not log as if they were generated in a real error scenario.

Note that this will cause listed exceptions to be wrapped in an ExpectedException, which is used internally by the RPC sever. The RPC client will see the original exception type.

6.oslo_messaging.expose(func)

用来修饰endpont的方法,表明RPC客户端能够调用该方法。如果dispatcher的access_policy设置为 ExplicitRPCAccessPolicy,则endpoint的方法必须显示的声明可被访问,例如:

# foo() cannot be invoked by an RPC client
def foo(self):
    pass

# bar() can be invoked by an RPC client
@rpc.expose
def bar(self):
    pass

7. exception oslo_messaging.ExpectedException

封装了RPC endpoint抛出的expected exception。

五、RPC Client

1.class oslo_messaging.RPCClient

oslo_messaging.RPCClient(transport, target, timeout=None, version_cap=None, serializer=None, retry=None)
该类用来调用远程RPC服务器上的方法。该类用来发送方法调用请求,并接收方法的返回值。

RPC client支持两种模式:RPC call (有返回值)和RPC cast(无返回值)

RPC client使用target来声明RPC请求如何传输到RPC server.如果设置了target的topic(或是exchange),则任何监听了该topic(或是exchange的)的server都可提供服务。如果多个server同时监听了该topic(或是exchange),则根据best-effort round-robin算法选择一个server来提供服务。同时,client可以设置target的server属性,指定特定的server来提供服务。当在cast模式时,RPC请求会被广播到所有监听给topic或是exchange的server(当target的fanout属性值为true时).

在client构造时,可设置默认的target。当在某些方法调用时,可能需要修改某些属性,可使用prepare方法来修改target的属性。

在方法调用时,需要传入的参数包括:请求上下文字典,方法名字,参数字典。

2.一个简单的使用client调用RPC的例子:

transport = messaging.get_transport(cfg.CONF)
target = messaging.Target(topic='test', version='2.0')
client = messaging.RPCClient(transport, target)
client.call(ctxt, 'test', arg=arg)

一般情况下,会将RPC client功能的代码包装起来会更好。如下面的例子:

class TestClient(object):

    def __init__(self, transport):
        target = messaging.Target(topic='test', version='2.0')
        self._client = messaging.RPCClient(transport, target)

    def test(self, ctxt, arg):
        return self._client.call(ctxt, 'test', arg=arg)

使用prepare 修改target的例子:

def test(self, ctxt, arg):
    cctxt = self._client.prepare(version='2.5')
    return cctxt.call(ctxt, 'test', arg=arg)

3.与server的连接说明

如果与messaging 服务的连接失效,则client会阻塞(知道连接建立)。如果与messaging 服务之间的连接无法建立,则client会重试。默认情况下,client会不停的去尝试建立连接。可以通过设置retry参数来控制该过程。

client = messaging.RPCClient(transport, target, retry=None)
client.call(ctxt, 'sync')
try:
    client.prepare(retry=0).cast(ctxt, 'ping')
except messaging.MessageDeliveryFailure:
    LOG.error("Failed to send ping message")

4.方法说明

(1)call(ctxt, method, **kwargs) : 调用method,并等待返回值。

5.exception oslo_messaging.RemoteError(exc_type=None, value=None, traceback=None)

表明远程endpoint抛出异常,包含:string(表示原始异常类型),原始异常值,traceback信息。


Parameters: 
ctxt (dict) – a request context dict
method (str)the method name
kwargs (dict)a dict of method arguments
Raises: 
MessagingTimeout, RemoteError, MessageDeliveryFailure

(2)can_send_version(version=):
(3)cast(ctxt, method, **kwargs):

Parameters: 
ctxt (dict) – a request context dict
method (str)the method name
kwargs (dict)a dict of method arguments
Raises: 
MessageDeliveryFailure if the messaging transport fails to accept the request.

(4)prepare(exchange=, topic=, namespace=, version=, server=, fanout=, timeout=, version_cap=, retry=):

Parameters: 
exchange (str) – see Target.exchange
topic (str) – see Target.topic
namespace (str) – see Target.namespace
version (str) – requirement the server must support, see Target.version
server (str) – send to a specific server, see Target.server
fanout (bool) – send to all servers on topic, see Target.fanout
timeout (int or float) – an optional default timeout (in seconds) for call()s
version_cap (str) – raise a RPCVersionCapError version exceeds this cap
retry (int) – an optional connection retries configuration: None or -1 means to retry forever. 0 means no retry is attempted. N means attempt at most N retries.

六、Notifier

1.class oslo_messaging.Notifier(transport, publisher_id=None, driver=None, serializer=None, retry=None, topics=None)

通过messaging transport或是其他方式,发送notification messages.

Notification消息格式:

{'message_id': six.text_type(uuid.uuid4()),
 'publisher_id': 'compute.host1',
 'timestamp': timeutils.utcnow(),
 'priority': 'WARN',
 'event_type': 'compute.create_instance',
 'payload': {'instance_id': 12, ... }}

Notifier对象可通过如下方式获取:

notifier = messaging.Notifier(get_notification_transport(CONF),
‘compute’)

notification通过drivers(具体根据driver config选项确定,主题根据topics config 选项确定)。

另外,Nofifier对象还可以根据特定的driver、topic创建,方式如下所示:

transport = notifier.get_notification_transport(CONF)
notifier = notifier.Notifier(transport,
                             'compute.host',
                             driver='messaging',
                             topics=['notifications'])

一般来说,Nofifier对象实例化花销很大(主要开销在装载driver上),所以,为了减少开销,可以通过如下方式来重用:

notifier = notifier.prepare(publisher_id='compute')
notifier.info(ctxt, event_type, payload)

2.主要方法说明

(1)audit(ctxt, event_type, payload):发送audit notification。

Parameters: 
ctxt (dict) – a request context dict
event_type (str) – describes the event, for example ‘compute.create_instance’
payload (dict) – the notification payload
Raises: 
MessageDeliveryFailure

(2)critical(ctxt, event_type, payload):同audit,只是level 不同。
(3)debug(ctxt, event_type, payload):同audit,只是level 不同。
(4)error(ctxt, event_type, payload):同audit,只是level 不同。
(5)info(ctxt, event_type, payload):同audit,只是level 不同。
(6)is_enabled():检查notifier是否可以将notification发送出去。如果notifier的dirver设置成 only to noop,则返回false。其他情况都返回true.
(7)prepare(publisher_id=, retry=):返回特定的Notifer实例。返回一个新的publisher_id为参数指定的Notifier实例。该方法允许发送多个publisher_id的notification,而无notification driver加载开销。

(8)sample(ctxt, event_type, payload):同audit,只是level 不同。
(9)warn(ctxt, event_type, payload):同audit,只是level 不同。
(10)warning(ctxt, event_type, payload):同audit,只是level 不同。

3.LoggingNotificationHandler

class oslo_messaging.LoggingNotificationHandler(url, publisher_id=None, driver=None, topic=None, serializer=None)
当应用使用logging 模块记录日志时,实际上它是通过发送一条notification来完成的,该notification的level和日志记录的level是一样的。

4.可用的Notifier Drivers

(1)log:通过python logging机制发布notification
(2)messaging:使用1.0 message格式发送notification。使用配置的messaging tranport来发送notification。(这是当consumer不支持2.0 message格式时,才使用的driver)
(3)messagingV2:使用2.0 message格式发送notification。
(4)Noop:
(5)routing:
(6)test:将notification发送到内存中,供测试使用。

七、Notification Driver

notification driver通过messaging将notifications发送给notification listener. driver会阻塞notifier线程,知道notification已经传送到messaging transport。notification driver不保证notification一定会被notification listener处理。

notification messages发送时最多发送一次,保证notification不会重复。
当给driver发送notification时,如果还没有和messaging service建立有效的连接,则该发送过程会阻塞,知道连接建立(和RPC client 发送message一样)。如果连接过程建立失败,则driver会重试。默认情况下,driver会一直尝试,知道建立连接。可以设置retry产生来改变该行为。

1.MessagingDriver

class oslo_messaging.notify.messaging.MessagingDriver(conf, topics, transport, version=1.0)
使用1.0 message格式发送notification(见Notification一节)

2.MessagingV2Driver

class oslo_messaging.notify.messaging.MessagingV2Driver(conf, **kwargs)
使用2.0 message格式发送notification(见Notification一节)

3.Driver

class oslo_messaging.notify.notifier.Driver(conf, topics, transport)

Notification driver基类。
主要方法:
(1)notify(ctxt, msg, priority, retry):


Parameters: 
ctxt – current request context
msg (str) – message to be sent
priority (str) – priority of the message
retry (int) – connection retries configuration (used by the messaging driver): None or -1 means to retry forever. 0 means no retry is attempted. N means attempt at most N retries.

八、Notification Listener

notification listener 用来处理通过messaging driver方式notification。notification listener通过target 订阅topic(和exchange,可选).notification 消息通过notifier client 发送,最后由notification listener接收。如果多个listeners 订阅了相同的target,则只有一个listener会收到该notification。多个listeners的选择通过 best-effort round-robin选择。

notification的传送模式可通过指定pool的方式来改变。对于订阅了相同的target(或是exchange)的listener的集合,具有同一个pool属性的 listener可成为一个子集。每个子集会收到一个notification的拷贝,该拷贝会被该子集中的某个listener处理。因此,总体来说,会发送出去多个notification的拷贝。例如,一个发送到默认的listener中(这些listener没有pool name),然后,每个子集都会收到一个。

需要主要的是,不是每种transport driver都实现了listener pool机制。如果driver没有实现pool name,则在调用 get_notification_listener()方法时,会抛出NotImplementedError 异常。

notification listener可以暴露出多个endpoints,每个endpoint包含多个方法。每个方法的名字和notification优先级对应。当收到notification时,会将notification交给对应的具有相同优先级的方法。例如,info notification会分配到info()方法。

notification endpoint可定义NotificationFilter,不符合NotificationFilter规则的notification可忽略。

endpoint方法的参数包括:客户端请求的上下文、publisher_id、event_type、payload和元数据。元数据是一个map,包涵了message_id和time stamp。

endpoint方法可显示的返回一个oslo_messaging.NotificationResult.HANDLED对象,用来声明一条消息或是oslo_messaging.NotificationResult.REQUEUE 将重新入队了。需要注意的是并不是所有的transport driver都支持requeueing.为了能够使用该特性,应用应该使用断言测试该特性是否可用(在调用get_notification_listener()方法时,传入参数allow_requeue=True)。如果不支持requeueing,则会抛出NotImplementedError 异常。

每个notification listener都和一个executor绑定,来控制收到的notification如何分配。默认情况下,使用的是blocking executor(具体特性参加executor一节)

notification listener的方法start,stop,wait方法和RPC Server的方法作用大致相同。

1.notification listener创建

创建notification listener实例时,需要指定transport,target列表,endpoint列表。
(1)transport的获取:

transport = messaging.get_notification_transport(conf)

(2)一个简单的notification listener例子如下:

from oslo_config import cfg
import oslo_messaging


class NotificationEndpoint(object):
    filter_rule = oslo_messaging.NotificationFilter(
        publisher_id='^compute.*')

    def warn(self, ctxt, publisher_id, event_type, payload, metadata):
        do_something(payload)


class ErrorEndpoint(object):
    filter_rule = oslo_messaging.NotificationFilter(
        event_type='^instance\..*\.start$',
        context={'ctxt_key': 'regexp'})

    def error(self, ctxt, publisher_id, event_type, payload, metadata):
        do_something(payload)

transport = oslo_messaging.get_notification_transport(cfg.CONF)
targets = [
    oslo_messaging.Target(topic='notifications'),
    oslo_messaging.Target(topic='notifications_bis')
]
endpoints = [
    NotificationEndpoint(),
    ErrorEndpoint(),
]
pool = "listener-workers"
server = oslo_messaging.get_notification_listener(transport, targets,
                                                  endpoints, pool=pool)
server.start()
server.wait()

2.相关方法

(1)oslo_messaging.get_notification_listener(transport, targets, endpoints, executor=’blocking’, serializer=None, allow_requeue=False, pool=None):构造一个notification listener.


Parameters: 
transport (Transport) – the messaging transport
targets (list of Target) – the exchanges and topics to listen on
endpoints (list) – a list of endpoint objects
executor (str) – name of message executor - available values are ‘eventlet’, ‘blocking’ and ‘threading’
serializer (Serializer) – an optional entity serializer
allow_requeue (bool) – whether NotificationResult.REQUEUE support is needed
pool (str) – the pool name
Raises: 
NotImplementedError

(2) oslo_messaging.get_batch_notification_listener(transport, targets, endpoints, executor=’blocking’, serializer=None, allow_requeue=False, pool=None, batch_size=None, batch_timeout=None):构造一个batch notification listener.


Parameters: 
transport (Transport) – the messaging transport
targets (list of Target) – the exchanges and topics to listen on
endpoints (list) – a list of endpoint objects
executor (str) – name of message executor - available values are ‘eventlet’, ‘blocking’ and ‘threading’
serializer (Serializer) – an optional entity serializer
allow_requeue (bool) – whether NotificationResult.REQUEUE support is needed
pool (str) – the pool name
batch_size (int) – number of messages to wait before calling endpoints callacks
batch_timeout (int) – number of seconds to wait before calling endpoints callacks
Raises: 
NotImplementedError

九、Serializer

在python 对象和message(notification)数据做序列化或是反序列化的基类。

1.class oslo_messaging.Serializer

主要方法:
(1)deserialize_context(ctxt) :对字典变成 request contenxt.
(2)deserialize_entity(ctxt, entity) :对entity做反序列化,其中ctxt是已经deserialize过的,entity是要处理的。
(3)serialize_context(ctxt) :将Request context变成字典类型
(4)serialize_entity(ctxt, entity) :对entity做序列化,其中ctxt是已经deserialize过的,entity是要处理的。
(5)

2.class oslo_messaging.NoOpSerializer

空类,什么都不做。

十、Exceptions

  1. oslo_messaging.ClientSendError(target, ex) :当发送message失败时抛出。
  2. oslo_messaging.DriverLoadFailure(driver, ex):当transport driver加载失败时抛出。
  3. oslo_messaging.ExecutorLoadFailure(executor, ex):executor加载失败时抛出。
  4. oslo_messaging.InvalidTransportURL(url, msg) :tranport URL 无效
  5. oslo_messaging.MessagingException:exception记录
  6. oslo_messaging.MessagingTimeout
  7. oslo_messaging.MessagingServerError :MessageHandlingServer 异常基类。
  8. oslo_messaging.NoSuchMethod(method):
  9. oslo_messaging.RPCDispatcherError:RPC dispatcher 异常基类。
  10. oslo_messaging.RPCVersionCapError(version, version_cap)
  11. oslo_messaging.ServerListenError(target, ex)
  12. oslo_messaging.UnsupportedVersion(version, method=None)

十一、Configuration Options

默认的参数:
1. rpc_conn_pool_size :integer,default=30
2.

matchmaker_redis相关的参数:
1. host :Type=string,Host to locate redis.
2. port: port number
3. password :Password for Redis server (optional).

oslo_messaging_amqp 相关的参数:
1. container_name: Type=string,Name for the AMQP container. must be globally unique. Defaults to a generated UUID
2. idle_timeout :Type= integer,Timeout for inactive connections (in seconds)

oslo_messaging_kafka 相关的参数:
1. kafka_default_host :Type= string,Default Kafka broker Host
2. kafka_default_port: Type=port number

oslo_messaging_notifications 相关的参数:
1. driver :Type=multi-valued
2. transport_url: Type=string
3. topics : Type= list
4. retry :Type=integer

oslo_messaging_rabbit 相关的参数:
1. amqp_durable_queues
2. amqp_auto_delete

oslo_messaging_zmq 相关的参数:
1. rpc_zmq_bind_address:
2. rpc_zmq_matchmaker:

参数相关的API:
1. oslo_messaging.opts.list_opts() :Return a list of oslo.config options available in the library.

十二、Testing Configurations

1.class oslo_messaging.conffixture.ConfFixture(conf)

oslo.messaging注册了一系列的配置选择。用户应用使用API来查询、修改具体的参数配置。
用法示例:

self.messaging_conf = self.useFixture(messaging.ConfFixture(cfg.CONF))
self.messaging_conf.transport_driver = 'fake'

Parameters: conf (oslo.config.cfg.ConfigOpts) – a ConfigOpts instance

十三、Available Drivers

transport的driver有如下几种:

  1. amqp :https://docs.openstack.org/developer/oslo.messaging/AMQP1.0.html
  2. fake :测试使用,该driver将消息发送到内存中。
  3. kafka :experimental
  4. kombu :RabbitMQ Driver。openstack默认的。
  5. pika :successor to the existing rabbit/kombu driver。 https://docs.openstack.org/developer/oslo.messaging/pika_driver.html
  6. rabbit :RabbitMQ Driver
  7. zmq :通过ZeroMQ 实现了RPC和Notifer API.详见:https://docs.openstack.org/developer/oslo.messaging/zmq_driver.html

十四、Available message driver

讲述driver的要求,不符合的就从olso.message库中移除。

十五、AMQP 1.0 Protocol Driver Deployment Guide

原文地址 :https://docs.openstack.org/developer/oslo.messaging/AMQP1.0.html
翻译地址:

十六、Pika Driver Deployment Guide

原文地址 :https://docs.openstack.org/developer/oslo.messaging/pika_driver.html
翻译地址:

十七、ZeroMQ Driver Deployment Guide

原文地址 :https://docs.openstack.org/developer/oslo.messaging/zmq_driver.html
翻译地址:

十八、Guide for Transport Driver Implementors

原文地址 :https://docs.openstack.org/developer/oslo.messaging/driver-dev-guide.html
翻译地址: http://blog.csdn.net/youyou1543724847/article/details/71173439

十九、Frequently Asked Questions

原文地址 :https://docs.openstack.org/developer/oslo.messaging/FAQ.html
翻译地址:

二十、Contributing

省略

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值