生命力的好处在于拚搏,因为世界本身就是一个竞技场。
oslo.service为OpenStack各组件提供了一个定义新的长运行服务的框架;包括带有SSL和WSGI,周期性操作,结合systemd等的长运行应用。
oslo.service的实现原理
在oslo.service的实现中,核心是oslo_service.service模块中的Service类和Launcher类。下面分别介绍这两个类:
Service类
Service类的对象描述了一个服务,其定义了一套管理服务生命周期的方法,包括启动服务start()、停止服务stop()、等待服务wait()、重置服务reset()等管理方法。另外,在实例化Service对象时,可以传入一个threads的参数创建一个包含threads个线程的线程组ThreadGroup对象,用来管理服务中的所有线程。
除了Service类外,oslo.service还提供了一个Services类来管理一组服务。其除了定义了run_service()、stop()、wait()、restart()等生命周期管理方法之外,还定义了一个add()方法用于为Services对象添加服务。
Launcher类
Launcher类主要用来启动一个或多个服务并等待其完成。其定义了launcher_service(service, workers)、stop()、wait()、restart()方法管理Launcher对象中所有服务的生命周期;在实例化Launcher对象时,需要传入两个参数conf和restart_method,其中,conf表示加载的服务配置文件,restart_method表示重启服务的方式,在oslo.service中,定义了两种服务重启方式:reload方式表示重启服务时重新加载配置文件,mutate则表示重启服务时改变服务配置文件。
在oslo.service中,Launcher类主要有两个实现方案:ServiceLauncher类和ProcessLauncher类。其中,ServiceLauncher类是在一个一个父进程中启动一个或多个服务,其通过一个单实例的SignalHandler类监听针对服务的信号。而ProcessLauncher类则是在给定数量的worker中运行一个或多个服务,其启动服务时,首先将服务、workers封装为ServiceWrapper对象;然后,调用ProcessLauncher对象的
launch()方法
在其他OpenStack组件的实际使用中,通常都会调用oslo_service.service模块下的launch()方法启动相应的服务。该方法需要传入一下几个参数:
- conf:对应服务的配置参数对象,即oslo.config中的ConfigOpt对象;
- service:一个实例化的Service对象;
- workers:为一个服务启动的worker数,如果workers为空或为1,则使用ServiceLauncher启动服务,如果workers>1,则使用ProcessLauncher类启动服务;
- restart_method:服务重启方式。
launch()方法会根据上述给定的参数创建服务启动方法类,并调用其launcher_service()方法启动服务。
oslo.service的使用方法
本节主要以nova组件的nova-api服务的启动为例,阐述oslo.service的使用方法。通常,启动nova-api服务首先都会调用nova.cmd.api模块下的main()方法。其源码如下:
1 | def main(): |
从nova-api启动程序源码可知,在启动服务时,系统首先调用nova.service的process_launcher()方法创建了一个ProcessLauncher对象launcher;然后根据配置文件配置的enabled_apis创建了WSGIService对象;接着,调用launcher对象的launch_service()方法启动WSGI服务;最后,当所有enabled_apis中配置的api服务都启动后,调用launcher.wait()方法使所有api服务都处于等待状态等待外部请求。
在上述服务启动过程中,调用了nova.service模块中的WSGIService类,该类为nova组件自身封装的一个用于启动WSGI服务的Service子类;除此之外,nova.service模块中还定义了一个继承oslo.service Service类的子类Service。由此可知,在OpenStack各组件使用oslo.service时,还可以根据自身需求,实现自身的Service子类以便更好的使用oslo.service组件来管理自身的服务。
oslo.service组件的其他使用
本文开头介绍了oslo.service除了为OpenStack各组件提供了一个定义新的长运行服务的框架外,还可以实现带有SSL和WSGI,周期性操作,结合systemd等的长运行应用。本节将对这些实现进行简单介绍。
sslutils模块
sslutils模块主要提供一个wrap(conf, sock)方法,根据服务的配置文件,为基于SSL协议的服务添加ssl认证。
periodic_task模块
periodic_task模块主要提供对周期性任务的管理方法。其中,主要包括一个类和一个方法:
- periodic_task(args, *kwargs)方法:为周期性任务提供一个装饰器。如果某周期性方法没有@periodic_task装饰器,则其将默认每隔60s运行一次;而如果其带有@periodic_task(spacing=N [, run_immediately=[True|False]] [, name=[None|”string”])装饰器,表示该方法将每隔Ns运行一次,如果run_immediately不为空,且设置为True,则表示该方法第一次运行将会马上执行,否则第一次运行将在Ns后执行。
- PeriodicTasks类:封装了周期性任务的管理,其提供两个主要方法:add_periodic_task(task),为PeriodicTask对象添加周期性任务task;run_periodic_tasks(context, raise_on_error=False),运行周期性任务。
wsgi模块
wsgi模块主要提供WSGI服务管理的实现框架。其中,主要包含三个重要的类:
- Loader类:主要用于加载WSGI的配置文件(如nova的api-paste.ini文件),主要提供load_app(name)加载WSGI配文件,并返回一个WSGI应用的URLMap对象;
- Router类:主要用于缓存WSGI各REST API请求的路由信息,并在接收到请求时解析url并路由到具体的实现方法进行处理;
- Server类:一个Service子类,主要实现了定义一个WSGI服务和管理该WSGI服务的生命周期。
systemd模块
systemd模块是一个用于通知systemd服务准备就绪的辅助类。使用onready(notify_socket, timeout)方法监听systemd服务准备就绪通知;使用notify()、notify_once()方法通知systemd服务准备就绪。
loopingcall模块
loopingcall模块主要实现了一组管理回路调用的类。实现了动态回路调用、回滚回路调用、异常回路调用以及重试调用等多种回路调用策略。
threadgroup模块
threadgroup模块首先通过Thread类封装了一个线程的生命周期管理;然后通过ThreadGroup类管理一组线程的生命周期。
原文链接:https://blog.csdn.net/Bill_Xiang_/article/details/78492967