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

简介: 目录目录Nova Project ServicesProject 的程序入口 setuppy Nova中RPC远程过程调用nova-compute RPC API的实现novacomputemanager 模块最后Nova Project Servicesnova-api:捕获novaclient发送过来的HTTP请求,并且将它转换为AMQP消息,通过Queue来与别的services通信。

目录

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 调用过程。

相关文章
|
编解码 JSON 网络协议
Golang 语言使用标准库 net/rpc/jsonrpc 包跨语言远程调用
Golang 语言使用标准库 net/rpc/jsonrpc 包跨语言远程调用
116 0
|
6月前
|
Java 应用服务中间件 API
干翻RPC系列之HesssionRPC:HesssionRPC的开发体验和源码分析
干翻RPC系列之HesssionRPC:HesssionRPC的开发体验和源码分析
|
3月前
|
负载均衡 网络协议 小程序
SpringCloud远程调用为啥要采用HTTP,而不是RPC?
【8月更文挑战第28天】在微服务架构日益盛行的今天,SpringCloud凭借其强大的生态系统和灵活的集成能力,成为了众多企业构建微服务系统的首选框架。在微服务之间的远程调用中,一个常见的问题是选择HTTP还是RPC(远程过程调用)作为通信协议。本文将深入探讨SpringCloud为何更倾向于采用HTTP而非RPC进行远程调用。
347 5
|
1月前
|
负载均衡 Java 开发者
Spring Cloud 远程调用:为何选择 HTTP 而非 RPC?
【10月更文挑战第1天】在微服务架构中,远程服务调用是一个核心环节。面对HTTP和RPC(Remote Procedure Call,远程过程调用)这两种通信协议,Spring Cloud 选择了HTTP作为其主要通信手段。本文将深入探讨Spring Cloud选择HTTP而非RPC的原因,以及这一选择在实际工作中的优势。
90 0
|
3月前
|
存储 API 调度
OpenStack的计算服务(Nova)
【8月更文挑战第23天】
245 9
|
3月前
|
编解码 负载均衡 监控
RPC远程调用
RPC远程调用
|
3月前
|
API 调度 数据库
OpenStack核心组件Nova
【8月更文挑战第4天】
144 9
|
6月前
|
Linux 网络安全 API
云计算|OpenStack|社区版OpenStack安装部署文档(五 --- 计算服务nova安装部署---Rocky版)
云计算|OpenStack|社区版OpenStack安装部署文档(五 --- 计算服务nova安装部署---Rocky版)
367 0
|
6月前
|
网络协议 Java 程序员
SpringCloud 远程调用为啥要采用HTTP,而不是RPC?
关于SpringCloud远程调用采用HTTP而非RPC。
122 0
|
6月前
|
Go
Go语言RPC实战:打造自己的远程调用服务
Go语言RPC实战:打造自己的远程调用服务
151 0
下一篇
无影云桌面