Skip to content

Latest commit

 

History

History
192 lines (135 loc) · 5.89 KB

NeutronAgent之external_process.md

File metadata and controls

192 lines (135 loc) · 5.89 KB

Neutron agent 之 external_process

该模块用于监测子进程的状态

  1. ProcessManager 用于包装那些需要被监测的子进程(并负责启动该子进程)
  2. ProcessMonitor 用于监测那些被包装过的子进程

class MonitoredProcess(object)

@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."""

抽象基类

class ProcessManager(MonitoredProcess)

__init__

    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()))

def get_pid_file_name(self)

获取 pid 文件所在的路径(pid 文件内写有该子进程的 pid 号)

def pid(self)

属性方法,读取 pid

def active(self)

判断该子进程是否存活

def disable(self, sig='9', get_stop_command=None)

通过 cmd = ['kill', '-%s' % (sig), pid] 来该子进程发信号,对子进程进行杀死或重启操作

def reload_cfg(self)

调用 disable 让子进程重新启动,重新加载配置

def enable(self, cmd_callback=None, reload_cfg=False)

通过调用 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()

class ProcessMonitor(object)

def __init__(self, config, resource_type)

    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)

    def _spawn_checking_thread(self):
        self._monitor_processes = True
        eventlet.spawn(self._periodic_checking_thread)

孵化一个绿色线程,并在绿色线程内执行 _periodic_checking_thread 方法

def _periodic_checking_thread(self)

    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 方法

def _check_child_processes(self)

监视 _monitored_processes 里面存储的子进程是否还在运行,若是该子进程死亡,则调用 _execute_action 将其重新执行。

def _execute_action(self, service_id)

check_child_processes_action 用来设定当一个子进程死掉时,用什么方式将其再次启动。改配置在 /etc/neutron/neutron.conf 中:check_child_processes_action = respawn

所以这里调用的是 _respawn_action 来再次启动该子进程

def _respawn_action(self, service_id)

    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 stop(self)

停止检测子进程的状态

def register(self, uuid, service_name, monitored_process)

注册需要监听的子进程

def unregister(self, uuid, service_name)

取消对某一子进程的监测

def _exit_action(self, service_id)

    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)

    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)