用法

在项目中使用 oslo.service

import oslo_service

迁移到 oslo.service

oslo.service 库不再假定存在全局配置对象。相反,以下函数和类已更改为需要消耗应用程序传入一个 oslo.config 配置对象

在使用 oslo-incubator 中的 service 时

from foo.openstack.common import service

launcher = service.launch(service, workers=2)

在使用 oslo.service 时

from oslo_config import cfg
from oslo_service import service

CONF = cfg.CONF
launcher = service.launch(CONF, service, workers=2)

使用 oslo.service 与 oslo-config-generator

oslo.service 提供了几个入口点来生成配置文件。

注意: 该库不提供 oslo.service 入口点。

$ oslo-config-generator --namespace oslo.service.service \
--namespace oslo.service.periodic_task \
--namespace oslo.service.sslutils

启动和控制服务

oslo_service.service 模块提供了用于启动 OpenStack 服务和控制其生命周期的工具。

服务是任何继承自 oslo_service.service.ServiceBase 类的实例。 ServiceBase 是一个抽象类,定义了每个服务应实现的一个接口。 oslo_service.service.Service 可以作为构建新服务的基类。

启动器

oslo_service.service 模块提供了两个启动器来运行服务

  • oslo_service.service.ServiceLauncher - 用于在父进程中运行一个或多个服务。

  • oslo_service.service.ProcessLauncher - 在给定的工作进程中分叉,然后在其中启动服务。

可以初始化所需的任何启动器,然后使用它来启动服务。

from oslo_config import cfg
from oslo_service import service

CONF = cfg.CONF


service_launcher = service.ServiceLauncher(CONF)
service_launcher.launch_service(service.Service())

process_launcher = service.ProcessLauncher(CONF, wait_interval=1.0)
process_launcher.launch_service(service.Service(), workers=2)

或者,可以简单地调用 oslo_service.service.launch(),它将根据传递给它的工作进程数自动选择合适的启动器(如果 workers=1None,则使用 ServiceLauncher,否则使用 ProcessLauncher)。

from oslo_config import cfg
from oslo_service import service

CONF = cfg.CONF

launcher = service.launch(CONF, service.Service(), workers=3)

注意

强烈建议每个进程使用不超过一个 ServiceLauncherProcessLauncher 类实例。

信号处理

oslo_service.service 为诸如 SIGTERMSIGINTSIGHUP 等信号提供了处理程序。

SIGTERM 用于优雅地终止服务。这允许服务器在拒绝新的传入请求的同时等待所有客户端关闭连接。配置选项 graceful_shutdown_timeout 指定在收到 SIGTERM 信号后服务器应继续运行多少秒,以处理现有连接。将 graceful_shutdown_timeout 设置为零表示服务器将无限期地等待,直到完全服务完所有剩余请求。

要强制立即终止,必须发送 SIGINT 信号。

接收 SIGHUP 的行为取决于服务的配置方式。如果启动器使用 restart_method='reload'(默认值),则服务将重新加载其配置,并且所有线程都将完全重新启动。如果使用 restart_method='mutate',则只会重新加载标记为可变配置选项,并且服务线程不会重新启动。

有关 restart_method 参数的更多详细信息,请参阅 oslo_service.service.Launcher

注意

SIGHUP 不受 Windows 支持。

注意

配置选项 graceful_shutdown_timeout 不受 Windows 支持。

以下是一个具有重置方法的服务的示例,该方法允许通过发送 SIGHUP 重新加载日志记录选项。

from oslo_config import cfg
from oslo_log import log as logging
from oslo_service import service

CONF = cfg.CONF

LOG = logging.getLogger(__name__)

class FooService(service.ServiceBase):

    def start(self):
        pass

    def wait(self):
        pass

    def stop(self):
        pass

    def reset(self):
        logging.setup(cfg.CONF, 'foo')

性能分析

通过 oslo_service.service 启动的进程可以通过 eventlet_backdoor 模块进行性能分析(函数调用跟踪)。必须使用 backdoor_port 选项配置服务,以使其工作进程侦听 TCP 端口。然后,用户可以发送 prof() 命令来捕获工作进程的函数调用跟踪。

  1. 要开始性能分析,请将 prof() 命令发送到进程的侦听端口

  2. 要停止性能分析并将 pstat 调用跟踪捕获到文件,请将 prof() 命令以及文件基本名称作为参数(prof(basename))发送到工作进程的侦听端口。将生成一个统计文件(pstat 格式)到临时目录中,并带有用户提供的基本名称和 .prof 后缀。

例如,要分析 neutron 服务器进程(它通过 backdoor_port 选项配置的侦听端口 8002)

$ echo "prof()" | nc localhost 8002
$ neutron net-create n1; neutron port-create --name p1 n1;
$ neutron port-delete p1; neutron port-delete p1
$ echo "prof('neutron')" | nc localhost 8002

这将在 /tmp/neutron.prof 中生成一个统计文件。可以从跟踪文件中打印统计信息如下

import pstats

stats = pstats.Stats('/tmp/neutron.prof')
stats.print_stats()