messaging.get_rpc_server对应的代码为oslo_messaging/rpc/server.py中的get_rpc_server方法,该方法返回RPCServer类对象实例。
RPCServer的类定义如下:
class RPCServer(msg_server.MessageHandlingServer)而msg_server.MessageHandlingServer对应的类为oslo_messaging/server.py中的MessageHandlingServe类,所有消息的处理都会走_on_incoming这个方法,这个方法会调用self._work_executor.submit方法,
而self._work_executor是在MessageHandlingServe类的__init__方法中初始化的,存在如下语句:mgr = driver.DriverManager('oslo.messaging.executors', self.executor_type)
那么oslo.messaging.executors这个namespace又对应到哪里呢??发现oslo_messaging目录下根本就不存在executors这个目录或者文件(之前版本的oslo.messaging是存在这个目录的,比如1.4.1版本),再次查找,在/usr/lib/python2.7/site-packages/oslo.messaging-5.17.1.dist-info/的entry_points.txt中存在如下内容:
[oslo.messaging.executors] blocking = futurist:SynchronousExecutor eventlet = futurist:GreenThreadPoolExecutor threading = futurist:ThreadPoolExecutor
那么对于上面不同的self.executor_type,就对应到futurist这个模块的不同类。。因为我的server端代码中messaging.get_rpc_server传入的参数executor值为eventlet,所以就走到了futurist/_futures.py中的GreenThreadPoolExecutor类。该类的submit方法最终会调用到_spin_up这个方法,而这个方法最终走到self._pool.spawn_n(_green.GreenWorker(work, self._delayed_work))这条语句。
这里的self._pool为eventlet.greenpool.GreenPool类实例对象,而_green.GreenWorker即为futurist/_green.py中的GreenWorker类,该类实现了__call__方法,可直接调用。但是self._pool.spawn_n(_green.GreenWorker(work, self._delayed_work))中GreenWorker类的__call__方法无法被调用,应该改成如下:
self._pool.spawn_n(_green.GreenWorker(work, self._delayed_work)())
改成这个样子后,rpc server就可正常处理消息了。。
但是不明白的事是openstack M/N这些版本中为啥没有出问题呢。。。
以下是相关模块版本及环境信息:
oslo.concurrency (3.18.0) oslo.config (3.22.0) oslo.context (2.12.1) oslo.i18n (3.12.0) oslo.log (3.20.1) oslo.messaging (5.17.1) oslo.middleware (3.23.1) oslo.serialization (2.16.0) oslo.service (1.19.0) oslo.utils (3.22.0)
futurist (0.20.0)
eventlet (0.20.1)
所有的模块都是通过pip安装的。
操作系统为centos7,python为2.7.5,rabbitmq-server版本为rabbitmq-server-3.5.6-1.noarch