zl程序教程

您现在的位置是:首页 >  工具

当前栏目

Openstack Nova 源码分析 — RPC 远程调用过程

源码 远程 分析 过程 调用 Openstack RPC Nova
2023-09-27 14:28:47 时间
nova-api:捕获novaclient发送过来的HTTP请求,并且将它转换为AMQP消息,通过Queue来与别的services通信。

nova-api:捕获novaclient发送过来的HTTP请求,并且将它转换为AMQP消息,通过Queue来与别的services通信。

nova-conductor:为数据库访问提供了一层安全保障。
NOTE:除了nova-conductor可以访问数据库之外,因为nova-scheduler是只读数据库,而nova-api对数据库的操作有Policy保护,所以它们也都是可以访问数据库的。但是最好还是仅通过nova-conductor来访问数据库。

nova-scheduler:从可用资源池中选择最合适的Compute Node来创建虚拟机实例。

novaclient:是为了简化用户使用而将Restful API封装起来,负责将用户的请求转换为标准的HTTP请求。

nova-compute:负责虚拟机的生命周期管理

Project 的程序入口( setup.py )

每个 Openstack Project 的 setup.cfg(nova/setup.cfg) 文件,也被称之为 Openstack Project 的源码地图。其中 [entry_points] 是该文件最重要的 Section ,它包含了几个相对特殊的组或称之为命名空间,其中下列两个是非常重要的:


console_scripts = :其中的每一项都表示一个可执行的脚本,这些脚本在 Openstack Project 部署时候就会被安装到 lib 目录中,是 Openstack Projec 所提供的各个服务的入口点,在系统希望运行这些进程时,需要找到的位置。 EG. nova-api = nova.cmd.api:main (是 nove-api services或守护进程的程序入口)
从console_scripts命名空间我们可以看见Nova所提供的许多服务,而这些选项的值就是对应服务的程序入口。
console_scripts =

 nova-all = nova.cmd.all:main #启动所有Nova服务的辅助脚本

 nova-api = nova.cmd.api:main #作为WSGI服务器对外提供Restful API服务,有三种类型nova-api-ec2/,通过nova.conf中的enable_apis选项值来决定。

 nova-api-ec2 = nova.cmd.api_ec2:main #EC2 API支持

 nova-api-metadata = nova.cmd.api_metadata:main

 nova-api-os-compute = nova.cmd.api_os_compute:main #Openstack API服务

 nova-cells = nova.cmd.cells:main

 nova-cert = nova.cmd.cert:main #管理X509证书

 nova-compute = nova.cmd.compute:main #compute服务,负责虚拟机的生命周期管理

 nova-conductor = nova.cmd.conductor:main #conductor服务,负责与数据库的交互

 nova-console = nova.cmd.console:main 

 nova-consoleauth = nova.cmd.consoleauth:main

 nova-dhcpbridge = nova.cmd.dhcpbridge:main #管理nova-network的DHCP bridge

 nova-idmapshift = nova.cmd.idmapshift:main

 nova-manage = nova.cmd.manage:main

 nova-network = nova.cmd.network:main #已经被Neutron取代,只有在使用Devstack部署的时候才会被使用

 nova-novncproxy = nova.cmd.novncproxy:main #支持用户通过该代理服务以vnc连接到虚拟机实例

 nova-objectstore = nova.cmd.objectstore:main #兼容EC2的存储接口

 nova-rootwrap = oslo_rootwrap.cmd:main #在Openstack运行的过程中,支持以root的身份来运行某些shell指令

 nova-rootwrap-daemon = oslo_rootwrap.cmd:daemon

 nova-scheduler = nova.cmd.scheduler:main #scheduler服务,服务计算节点物理资源的调度

 nova-serialproxy = nova.cmd.serialproxy:main

 nova-spicehtml5proxy = nova.cmd.spicehtml5proxy:main

 nova-xvpvncproxy = nova.cmd.xvpvncproxy:main #允许用户通过代理的方式来访问虚拟机实例的控制台。

nova.api.v21.extensions:其中的每一项都对应了一个 API ,starting nova-api service 时会根据nova.api.v21.extensions命名空间来进行加载。Extensions 是不同版本之间的过渡,以后更趋向以这种方式来实现路由的Setup ,将资源映射到Controller。如果希望搞清楚一个API的实现过程,那么这个命名空间的选项值代码路径将会作为突破口,能更有效的理清API的脉络。 Nova中RPC(远程过程调用)

RPC:同一个项目内的不同服务进程之间的交互方式。

nova-compute/nova-conductor/nova-scheduler 在启动时都会注册一个RPC Server,这几个服务之间会通过消息队列 Queue 和 RPC 来实现互相调用,因为 nova-api 负责传递请求,并没有会调用它的服务,所以无需要启动RPC Server。


nova-compute 主要用于管理虚拟机的生命周期,所以其RPC API实现的方法多是用于对虚拟机的操作。

# 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 Project 中大多数的服务都提供了 API 或 RPC API 的实现文件,这些 API 是服务进程自身为了能被其他的服务进程访问所提供出来的一种接口,当别的服务进程希望影响另一个服务进程时,就可以通过 import 另一个服务进程的 rpcapi 就可以实现了。

EXAMPLE:当nova-conductor通知nova-compute创建虚拟机实例时,过程如下:
1. 在 nova-conductor 的代码中使用了 import nova-compute rpcapi module 或者类实例化传参这两种实现方式来加载 compute rpcapi 对象。这样 nova-conductor 就拥有了通过 RPC 访问 nova-compue 的能力。
2. 在 nova-conductor 的代码实现中调用了 rpcapi 模块的方法,即 nova-conductor发送了一个请求到 Queue,并等待 nova-compute 接受和响应。
3. nova-compute 接收到 nova-conductor 的请求,并作出响应。

这里写图片描述

#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接口,以RPC的方式发出一个请求到Queue再被nova-compute接收

 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)

注意:**nova-compute RPC Server 接收到别的服务的RPC请求之后(调用了ComputeAPI提供的RPC接口),真正完成请求操作的是**nova.compute.manager 模块。


nova.compute.manager 会一直在监听 Queue ,当Queue中存在相关的 RPC 请求时,实际上是由 manager 来实现的。


5189 def live_migration(self, context, dest, instance, block_migration, 1 migration, migrate_data): 2 """Executing live migration. 4 :param context: security context 5 :param dest: destination host 6 :param instance: a nova.objects.instance.Instance object 7 :param block_migration: if true, prepare for block migration 8 :param migration: an nova.objects.Migration object 9 :param migrate_data: implementation specific params 11 """ 13 # NOTE(danms): Remove these guards in v5.0 of the RPC API 14 if migration: 15 migration.status = queued 16 migration.save() 18 def dispatch_live_migration(*args, **kwargs): 19 with self._live_migration_semaphore: 20 self._do_live_migration(*args, **kwargs) 22 # NOTE(danms): We spawn here to return the RPC worker thread back to 23 # the pool. Since what follows could take a really long time, we dont 24 # want to tie up RPC workers. 25 utils.spawn_n(dispatch_live_migration, 26 context, dest, instance, 27 block_migration, migration, 28 migrate_data)
一文就读懂RPC远程调用核心原理 rpc的全称是Remote Procedure Call,即远程过程调用,是分布式系统的常用通信方法。 Remote,简单来说的话就是两个不同的服务之间,两个服务肯定是两个不同的进程。因此,我们就从跨进程进行访问的角度去理解就行了。 Procedure,意思是一串可执行的代码,我们写Java的方法,就是一段课程行的代码。 Call,即调用,调用的就是跨了进程的方法。
RocketMQ源码分析-Rpc通信模块(remoting)二 今天继续RocketMQ-Rpc通信模块(remoting)的源码分析。上一章提到了主要的start()方法执行流程,如果有不清楚的地方可以一起讨论哈,这篇文章会继续解读主要方法,按照惯例先看看NettyRemotingAbstract的类图,看类图知方法。和NettyEventExecutor以及MQ的交互流程。 按照惯例先看看NettyRemotingAbstract的类图,看类图知方法,文中会挑重要方法和主要流程解读。
RocketMQ源码分析-Rpc通信模块(remoting)一 上篇文章分析了Rocketmq的nameServer的源码,在继续分析源码之前,先考虑一个问题,设计一个mq并且是高性能的mq最最核心的问题是什么,我个人认为主要是有俩个方面,1:消息的网络传输,2:消息的读写,这两个决定了mq的高性能。
透视RPC协议:SOFA-BOLT协议源码分析 最近在看Netty相关的资料,刚好SOFA-BOLT是一个比较成熟的Netty自定义协议栈实现,于是决定研读SOFA-BOLT的源码,详细分析其协议的组成,简单分析其客户端和服务端的源码实现。当前阅读的源码是2021-08左右的SOFA-BOLT仓库的master分支源码。
徒手写一个RPC框架 - 远程调用 # 前言 微服务已经是每个互联网开发者必须掌握的一项技术。而RPC框架,是构成微服务最重要的组成部分之一。在五一假期,尝试去看了看dubbo的源代码,这里做一个整理。 广义的来讲一个完整的RPC包含了很多组件,包括服务发现,服务治理,远程调用,调用链分析,网关等等。
组队学架构之高并发架构系列:详解RPC远程调用和消息队列MQ的区别 RPC(Remote Procedure Call)远程过程调用,主要解决远程通信间的问题,不需要了解底层网络的通信机制。 RPC框架 知名度较高的有Thrift(FB的)、dubbo(阿里的)。