该模块用于监测子进程的状态
ProcessManager
用于包装那些需要被监测的子进程(并负责启动该子进程)ProcessMonitor
用于监测那些被包装过的子进程
@six.add_metaclass(abc.ABCMeta)
class MonitoredProcess(object):
@abc.abstractproperty
def active(self):
"""Boolean representing the running state of the process."""
@abc.abstractmethod
def enable(self):
"""Enable the service, or respawn the process."""
抽象基类
def __init__(self, conf, uuid, namespace=None, service=None,
pids_path=None, default_cmd_callback=None,
cmd_addl_env=None, pid_file=None, run_as_root=False,
custom_reload_callback=None):
self.conf = conf
self.uuid = uuid
self.namespace = namespace
self.default_cmd_callback = default_cmd_callback
self.cmd_addl_env = cmd_addl_env
self.pids_path = pids_path or self.conf.external_pids
self.pid_file = pid_file
self.run_as_root = run_as_root
self.custom_reload_callback = custom_reload_callback
if service:
self.service_pid_fname = 'pid.' + service
self.service = service
else:
self.service_pid_fname = 'pid'
self.service = 'default-service'
common_utils.ensure_dir(os.path.dirname(self.get_pid_file_name()))
获取 pid 文件所在的路径(pid 文件内写有该子进程的 pid 号)
属性方法,读取 pid
判断该子进程是否存活
通过 cmd = ['kill', '-%s' % (sig), pid]
来该子进程发信号,对子进程进行杀死或重启操作
调用 disable 让子进程重新启动,重新加载配置
通过调用 ip_lib.IPWrapper
来启动该子进程
def enable(self, cmd_callback=None, reload_cfg=False):
if not self.active:
if not cmd_callback:
cmd_callback = self.default_cmd_callback
cmd = cmd_callback(self.get_pid_file_name())
ip_wrapper = ip_lib.IPWrapper(namespace=self.namespace)
ip_wrapper.netns.execute(cmd, addl_env=self.cmd_addl_env,
run_as_root=self.run_as_root)
elif reload_cfg:
self.reload_cfg()
def __init__(self, config, resource_type):
"""Handle multiple process managers and watch over all of them.
:param config: oslo config object with the agent configuration.
:type config: oslo_config.ConfigOpts
:param resource_type: can be dhcp, router, load_balancer, etc.
:type resource_type: str
"""
self._config = config
self._resource_type = resource_type
self._monitored_processes = {}
if self._config.AGENT.check_child_processes_interval:
self._spawn_checking_thread()
check_child_processes_interval
为检查子进程的间隔时间,在 /etc/neutron/neutron.conf 中设置:check_child_processes_interval = 60
def _spawn_checking_thread(self):
self._monitor_processes = True
eventlet.spawn(self._periodic_checking_thread)
孵化一个绿色线程,并在绿色线程内执行 _periodic_checking_thread
方法
def _periodic_checking_thread(self):
while self._monitor_processes:
eventlet.sleep(self._config.AGENT.check_child_processes_interval)
eventlet.spawn(self._check_child_processes)
每次睡眠间隔时间之后,都会启动一个绿色线程去执行 _check_child_processes
方法
监视 _monitored_processes
里面存储的子进程是否还在运行,若是该子进程死亡,则调用 _execute_action
将其重新执行。
check_child_processes_action
用来设定当一个子进程死掉时,用什么方式将其再次启动。改配置在 /etc/neutron/neutron.conf 中:check_child_processes_action = respawn
。
所以这里调用的是 _respawn_action
来再次启动该子进程
def _respawn_action(self, service_id):
LOG.warning(_LW("Respawning %(service)s for uuid %(uuid)s"),
{'service': service_id.service,
'uuid': service_id.uuid})
self._monitored_processes[service_id].enable()
停止检测子进程的状态
注册需要监听的子进程
取消对某一子进程的监测
def _exit_action(self, service_id):
LOG.error(_LE("Exiting agent as programmed in check_child_processes_"
"actions"))
self._exit_handler(service_id.uuid, service_id.service)
def _exit_handler(self, uuid, service):
"""This is an exit handler for the ProcessMonitor.
It will be called if the administrator configured the exit action in
check_child_processes_actions, and one of our external processes die
unexpectedly.
"""
LOG.error(_LE("Exiting agent because of a malfunction with the "
"%(service)s process identified by uuid %(uuid)s"),
{'service': service, 'uuid': uuid})
raise SystemExit(1)