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

目录

  • 目录
  • Nova Project Services
  • Project 的程序入口 setuppy
  • Nova中RPC远程过程调用
    • nova-compute RPC API的实现
  • novacomputemanager 模块
  • 最后

Nova Project 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-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 模块

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

# nova/nova/compute/manager.py

5189     def live_migration(self, context, dest, instance, block_migration,
   1                        migration, migrate_data):
   2         """Executing live migration.
   3
   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
  10
  11         """
  12
  13         # NOTE(danms): Remove these guards in v5.0 of the RPC API
  14         if migration:
  15             migration.status = 'queued'
  16             migration.save()
  17
  18         def dispatch_live_migration(*args, **kwargs):
  19             with self._live_migration_semaphore:
  20                 self._do_live_migration(*args, **kwargs)
  21
  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 don't
  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)

最后

说到底,从 ComputeAPI 到 ComputeManager 的过程即是 RPC 调用过程。

时间: 2024-09-14 09:48:10

Openstack Nova 源码分析 — RPC 远程调用过程的相关文章

Openstack Nova 源码分析 — 使用 VCDriver 创建 VMware Instance

目录 目录 前言 流程图 nova-compute vCenter 前言 在上一篇Openstack Nova 源码分析 - Create instances (nova-conductor阶段)中,记录了 nova-api 接收到创建虚拟机的请求后,在 nova-conductor 中的执行流程.最终 nova-comductor 通过调用 nova-compute 的 RPC 接口函数 compute_rpcapi.build_and_run_instance() 将创建虚拟机的请求,通过

Openstack Nova 源码分析 — Create instances (nova-conductor阶段)

目录 目录 前言 Instance Flavor Instance Status Virt Driver Resource Tracker nova-conductor Create Instancenova-conductor阶段 前言 Nova 控制着一个个虚拟机的状态变迁和生命周期,这种对虚拟机生命周期的管理是由 nova-compute service 来完成的. 在了解 Nova 创建虚拟机的流程之前,需要先补充一些 Openstack 基本概念. Instance Instance

Mybatis源码分析之存储过程调用和运行流程_java

这一篇我们学习一下Mybatis调用存储过程的使用和运行流程.首先我们先创建一个简单的存储过程 DELIMITER $ CREATE PROCEDURE mybatis.ges_user_count(IN age INT, OUT user_count INT) BEGIN SELECT COUNT(*) FROM users WHERE users.age=age INTO user_count; END $ 这个存储过程的含义其实比较简单的,就是输入age,然后执行select count(

Openstack nova-scheduler 源码分析 — Filters/Weighting

目录 目录 前言 调度器 FilterScheduler调度器的工作流程 Filters 过滤器 Filters 类型 Weighting 权重 源码实现 关键文件及其意义 阶段一nova-scheduler 接收 build_instances RPC 远程调用 阶段二从 schedulerrpcapiSchedulerAPI 到 schedulermanagerSchedulerManager 阶段三从 schedulermanagerSchedulerManager 到调度器 Filter

Spark 源码分析 -- task实际执行过程

Spark源码分析 – SparkContext 中的例子, 只分析到sc.runJob 那么最终是怎么执行的? 通过DAGScheduler切分成Stage, 封装成taskset, 提交给TaskScheduler, 然后等待调度, 最终到Executor上执行 val sc = new SparkContext(--) val textFile = sc.textFile("README.md") textFile.filter(line => line.contains(

HBase源码分析:HTable put过程

HBase版本:0.94.15-cdh4.7.0 在 HBase中,大部分的操作都是在RegionServer完成的,Client端想要插入.删除.查询数据都需要先找到相应的 RegionServer.什么叫相应的RegionServer?就是管理你要操作的那个Region的RegionServer.Client本身并 不知道哪个RegionServer管理哪个Region,那么它是如何找到相应的RegionServer的?本文就是在研究源码的基础上了解这个过程. 首先来看看写过程的序列图: 客

openstack nova 源码解析 — Nova API 执行过程从(novaclient到Action)

目录 目录 Nova API Nova API 的执行过程 novaclient 将 Commands 转换为标准的HTTP请求 PasteDeploy 将 HTTP 请求路由到具体的 WSGI Application Routes 将 HTTP 请求路由到具体的操作函数并执行 Nova API Nova API 是访问.使用 Nova 各组件服务的唯一途径,作为 novaclient 和 Nova services 之间的中间层.Nova API 需要保证高度的稳定性,所以这些 API 的名称

spark源码分析之Checkpoint的过程

概述 checkpoint 的机制保证了需要访问重复数据的应用 Spark 的DAG执行行图可能很庞大,task 中计算链可能会很长,这时如果 task 中途运行出错,那么 task 的整个需要重算非常耗时,因此,有必要将计算代价较大的 RDD checkpoint 一下,当下游 RDD 计算出错时,可以直接从 checkpoint 过的 RDD 那里读取数据继续算. 我们先来看一个例子,checkpoint的使用 import org.apache.spark.SparkContext imp

Android源码分析-Alarm机制与Binder的交互

转载请注明出处:http://blog.csdn.net/singwhatiwanna/article/details/18448997 前言 本次给大家分析的是Android中Alarm的机制以及它和Binder的交互,所用源码为最新的Android4.4.因为Alarm的功能都是通过Binder来完成的,所以,介绍Alarm之前必须要先介绍下它是如何调用Binder来完成定时功能的.由于内容较多,本文会比较长,在文章结构安排上是这样的:首先简单介绍如何使用Alarm并给出其工作原理,接着分析