在OpenStack的各个服务之间有些数据库对象是远程操作的,远程对象所实现的效果是:一个 A 服务中的远程对象实例,可以由消息队列传送到B 服务,B 服务能够使用这个实例,当调用实例的方法时,实际执行这个方法却是在A 服务中。
以Instance类的实例为例,nova-conductor在收到创建虚拟机请求时生成了实例instance=Instance(),之后将instance这个数据库对象通过消息队列发送到了nova-compute,在nova-compute进行虚拟机创建的过程中,经常性地需要更改虚拟机的状态,所以经常出现类似这样的语句:
nova-compute不直接访问数据库,这个save() 方法,就是由nova-conductor来执行的。
具体原理
以instance的save()方法为例,有一个@base.remotable修饰
(objects/instance.py ),
remotable的定义如下,根据indirection_api的定义情况:如果有定义indirection_api,则把save()方法作为一个参数fn来运行indirection_api.object_action,如果没有定义则运行save()。
(dist-packages/oslo_versionedobjects/base.py),
indirection_api在nova-compute服务中有赋值,而其他服务中没有:
(cmd/compute.py )
所以:
nova-compute运行instance.save()时是把save方法以及save的参数作为参数去运行indirection_api.object_action,而其他服务则是直接运行save()。
而indirection_api.object_action的具体实现就是消息队列的call方法。
领取专属 10元无门槛券
私享最新 技术干货