openstack中的rpc远程调用的方法


Posted in Python onJuly 09, 2021

众所周知,OpenStack的通信方式有两种,一种是基于HTTP协议的RESTFul API方式,另一种则是RPC调用。两种通信方式的应用场景有所不同,在OpenStack中,前者主要用于各组件之间的通信(如nova与glance的通信),而后者则用于同一组件中各个不同模块之间的通信(如nova组件中nova-compute与nova-scheduler的通信)。

nova中rpc调用非常多,用pycharm点点点跟函数的时候遇到rpc就会点不下去了,不解决直接就看不下去了那种多法

什么是 RPC

openstack中的rpc远程调用的方法

看不明白这个图对于看nova代码,其实不是很重要,直接忽略以后再看也可以,当务之急是解决一下看openstack代码遇到rpc就跟丢了的问题

RPC、消息队列、RESTful

这三个其实不是一个层面的东西,本质上不应该放在一起比,但是因为都用来通信,比较容易混淆就还是解释一下

  • RESTful:主要用于各组件之间的通信(比如nova与glance的通信),或者说用于组件对外提供调用接口
  • RPC:则用于同一组件中各个不同模块之间的通信(比如nova组件中nova-compute与-nova-scheduler的通信)
  • 消息队列:用于解耦组件,也是组件间通信用的,而且会有一个队列用来暂存消息

在nova中的典型rpc

nova/nova/nova/conductor/tasks/live_migrate.py

class LiveMigrationTask(base.TaskBase):
    def __init__(self, context, instance, destination,
                 block_migration, disk_over_commit, migration, compute_rpcapi,
                 servicegroup_api, scheduler_client):
        super(LiveMigrationTask, self).__init__(context, instance)
    ... 

    def _execute(self):
        self._check_instance_is_active()
        self._check_host_is_up(self.source)

        if not self.destination:
            self.destination = self._find_destination()
            self.migration.dest_compute = self.destination
            self.migration.save()
        else:
            self._check_requested_destination()

        # TODO(johngarbutt) need to move complexity out of compute manager
        # TODO(johngarbutt) disk_over_commit?

        #调用 ComputeAPI 类中的 live_migration() RPC接口
        return self.compute_rpcapi.live_migration(self.context,
                host=self.source,
                instance=self.instance,
                dest=self.destination,
                block_migration=self.block_migration,
                migration=self.migration,
                migrate_data=self.migrate_data)

conductorcompute_rpcapi.live_migration的方式远程调用computelive_migration,过程就是, conductorRPC的方式发出一个请求到Queue再被nova-compute接收

nova/nova/nova/compute/rpcapi.py

class ComputeAPI(object):

    # 这是一个RPC远程调用的方法
    def live_migration(self, ctxt, instance, dest, block_migration, host,
                       migration, migrate_data=None):
        args = {'migration': migration}
        version = '4.2'
        if not self.client.can_send_version(version):
            version = '4.0'

        # 获取目标 compute 主机(DEST HOST)的RPC client,即被调用的服务进程的HostIP
        cctxt = self.client.prepare(server=host, version=version)

        # 通过目标主机对象的 RPC cliient 来调用远程过程方法 cast() ,以此来实现远程调用
        cctxt.cast(ctxt, 'live_migration', instance=instance,
                   dest=dest, block_migration=block_migration,
                   migrate_data=migrate_data, **args)
        # cast()异步远程调用,不会阻塞别的进程,适合于需要长时间进行的执行过程
        # cast()的第二个参数是RPC client调用的函数名,case()后面的参数会继续作为参数传入该调用函数
        # cast()函数内的live_migration()函数是 manager.live_migration() 视具体实现迁移功能的函数,在manager.py内实现。

调用的时候是从nova/nova/conductor/tasks/live_migrate.pynova/nova/compute/rpcapi.py,但是实际上是compute服务首先得在rpcapi.py提供出接口函数,然后使用者通过
- 1. import导入的方式去使用rpc调用
- 2. 类实例化传参的方式去引入

热迁移这里用的就是类实例化传参

tip: call()表示同步调用 和 cast()表示异步调用

openstack中的rpc远程调用的方法

根据在rpc.py或者rpcapi.py中的cast()的第二个参数,去该服务下的manager.py中找和这个参数同名的函数(这个就是rpc最终想要调用的函数),我们这里是compute_rpcapi,所以要去找compute下的mannager.py

为什么要去找mannager,是因为nova.compute.manager 会一直监听 Queue ,当Queue中存在相关的 RPC 请求时,就去完成这个请求

nova/nova/nova/compute/manager.py

@wrap_exception()
    @wrap_instance_event(prefix='compute')
    @wrap_instance_fault
    def live_migration(self, context, dest, instance, block_migration,
                       migration, migrate_data):
        """执行实时迁移。

        :param context: security context
        :param dest: destination host
        :param instance: a nova.objects.instance.Instance object
        :param block_migration: if true, prepare for block migration
        :param migration: an nova.objects.Migration object
        :param migrate_data: implementation specific params

        """
        self._set_migration_status(migration, 'queued')

        def dispatch_live_migration(*args, **kwargs):
            with self._live_migration_semaphore:
                # 调用_do_live_migration执行迁移
                self._do_live_migration(*args, **kwargs)

        # NOTE(danms): We spawn here to return the RPC worker thread back to
        # the pool. Since what follows could take a really long time, we don't
        # want to tie up RPC workers.
        utils.spawn_n(dispatch_live_migration,
                      context, dest, instance,
                      block_migration, migration,
                      migrate_data)

当然实际干活的还不是manager.pydef live_migration,而是live_migration函数去调用_do_live_migration,但是之后的就是热迁移的流程,在之前的文档里写了就不展开了,反正rpc的体现就只到这里

冷迁移中还有很多例子,不一一列举了,有兴趣可以去看冷迁移源码分析这篇博客

看完例子会发现,既然原生的代码既然已经写了rpc调用,那么对应的服务肯定已经提供了rpc接口,所以实际上看到compute_rpcapi,可以不去compute下的rpc文件中找了,直接去compute下的manager看具体实现(不止compute,其他服务也一样),当然,如果需要雪确定是同步还是异步调用那还是不要偷这一步的懒。

总结

完整的rpc应该具有

  • 组件A提供出rpc调用接口(rpc.py或者rpcapi.py文件)
  • 组件B引入组件A的rpc (import或者类实例化传参)
  • 组件B调用组件A的rpc(以rpc方式发送一个请求到消息队列)
  • 组件A处理请求(组件A监听到发给自己的rpc请求会通过manager处理请求)

如果只是看代码,那么去对应的manager下面找实现就可以了,但是如果自己要加就还是的明白从哪里提供的、怎样导入,何种途径接收,这样想在代码里添加自己的rpc调用才心里有数

参考文献:

https://zhuanlan.zhihu.com/p/36427583
https://blog.csdn.net/Jmilk/article/details/52655645
https://www.cnblogs.com/wongbingming/p/11086773.html
https://blog.csdn.net/qq_33909098/article/details/118578133

到此这篇关于openstack中的rpc远程调用的文章就介绍到这了,更多相关openstack rpc调用内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python 实现文件的全备份和差异备份详解
Dec 27 Python
Python使用MD5加密算法对字符串进行加密操作示例
Mar 30 Python
python通过微信发送邮件实现电脑关机
Jun 20 Python
Python爬虫框架scrapy实现的文件下载功能示例
Aug 04 Python
python之super的使用小结
Aug 13 Python
用Python识别人脸,人种等各种信息
Jul 15 Python
Django框架中序列化和反序列化的例子
Aug 06 Python
Python timer定时器两种常用方法解析
Jan 20 Python
Python关于__name__属性的含义和作用详解
Feb 19 Python
基于python实现判断字符串是否数字算法
Jul 10 Python
Python爬虫之爬取哔哩哔哩热门视频排行榜
Apr 28 Python
解决python3安装pandas出错的问题
May 20 Python
Python实现查询剪贴板自动匹配信息的思路详解
如何利用Python实现一个论文降重工具
python实现MD5进行文件去重的示例代码
深入浅析python3 依赖倒置原则(示例代码)
Jul 09 #Python
Python中Selenium对Cookie的操作方法
Python常用配置文件ini、json、yaml读写总结
图文详解matlab原始处理图像几何变换
You might like
PHP 5.3.1 安装包 VC9 VC6不同版本的区别是什么
2010/07/04 PHP
Laravel中使用阿里云OSS Composer包分享
2015/02/10 PHP
php自定义hash函数实例
2015/05/05 PHP
Zend Framework上传文件重命名的实现方法
2016/11/25 PHP
又一个小巧的图片预加载类
2007/05/05 Javascript
JavaScript高级程序设计 阅读笔记(十二) js内置对象Math
2012/08/14 Javascript
js中typeof的用法汇总
2013/12/12 Javascript
javascript日期对象格式化为字符串的实现方法
2014/01/14 Javascript
js 本地预览的简单实现方法
2014/02/18 Javascript
js操作滚动条事件实例
2015/01/29 Javascript
浅谈javascript属性onresize
2015/04/20 Javascript
js获取css的各种样式并且设置他们的方法
2017/08/22 Javascript
微信小程序实现点击按钮移动view标签的位置功能示例【附demo源码下载】
2017/12/06 Javascript
node版本管理工具n包使用教程详解
2018/11/09 Javascript
详解Vue项目部署遇到的问题及解决方案
2019/01/11 Javascript
JavaScript面向对象编程小游戏---贪吃蛇代码实例
2019/05/15 Javascript
原理深度解析Vue的响应式更新比React快
2020/04/04 Javascript
JS指定音频audio在某个时间点进行播放
2020/11/28 Javascript
[01:07]2015国际邀请赛 中国区预选赛精彩回顾
2015/06/15 DOTA
[47:18]完美世界DOTA2联赛循环赛 IO vs FTD BO2第一场 11.05
2020/11/06 DOTA
[02:50]【扭转乾坤,只此一招】DOTA2永雾林渊版本开启新篇章
2020/12/22 DOTA
使用Python脚本来获取Cisco设备信息的示例
2015/05/04 Python
python之PyMongo使用总结
2017/05/26 Python
Python实现pdf文档转txt的方法示例
2018/01/19 Python
pyqt 多窗口之间的相互调用方法
2019/06/19 Python
基于python实现的百度新歌榜、热歌榜下载器(附代码)
2019/08/05 Python
基于django ManyToMany 使用的注意事项详解
2019/08/09 Python
浅谈keras中Dropout在预测过程中是否仍要起作用
2020/07/09 Python
html5响应式开发自动计算fontSize的方法
2020/01/13 HTML / CSS
人力资源总监工作说明
2014/03/03 职场文书
库房保管员岗位职责
2014/04/07 职场文书
中学生操行评语
2014/04/24 职场文书
考生诚信考试承诺书
2014/05/23 职场文书
合唱兴趣小组活动总结
2014/07/10 职场文书
校园主题婚礼活动策划方案
2014/09/15 职场文书
防卫过当辩护词
2015/05/21 职场文书