• OpenStack_Swift源代码分析——ObjectReplicator源代码分析(1)


    1、ObjectorReplicator的启动

    首先执行启动脚本

    swift-init object-replicator start
    此执行脚本的执行过程和ring执行脚本执行过程差点儿相同。找到swift 源代码bin下的swift-object-replicator其代码例如以下所看到的

    if __name__ == '__main__':
        parser = OptionParser("%prog CONFIG [options]")
        parser.add_option('-d', '--devices',
                          help='Replicate only given devices. '
                               'Comma-separated list')
        parser.add_option('-p', '--partitions',
                          help='Replicate only given partitions. '
                               'Comma-separated list')
        conf_file, options = parse_options(parser=parser, once=True)
        run_daemon(ObjectReplicator, conf_file, **options)
    最后一行:
     run_daemon(ObjectReplicator, conf_file, **options)
    也就是要运行run_daemon()函数。为其传入的是ObjectReplicator和配置文件參数已经选项參数,以下继续看run_daemon方法。他是swift/daemon.py下Daemon类中的方法。看详细代码实现:

    def run_daemon(klass, conf_file, section_name='', once=False, **kwargs):
        """
        Loads settings from conf, then instantiates daemon "klass" and runs the
        daemon with the specified once kwarg.  The section_name will be derived
        from the daemon "klass" if not provided (e.g. ObjectReplicator =>
        object-replicator).
    
        :param klass: Class to instantiate, subclass of common.daemon.Daemon
        :param conf_file: Path to configuration file
        :param section_name: Section name from conf file to load config from
        :param once: Passed to daemon run method
        """
        # very often the config section_name is based on the class name
        # the None singleton will be passed through to readconf as is
        if section_name is '':
            #得到section_name = ojbect-replicator  sub()为正則表達式
            section_name = sub(r'([a-z])([A-Z])', r'1-2',
                               klass.__name__).lower()
    
        conf = utils.readconf(conf_file, section_name,
                              log_name=kwargs.get('log_name'))
    
        # once on command line (i.e. daemonize=false) will over-ride config
        once = once or not utils.config_true_value(conf.get('daemonize', 'true'))
    
        # pre-configure logger
        if 'logger' in kwargs:
            logger = kwargs.pop('logger')
        else:
            logger = utils.get_logger(conf, conf.get('log_name', section_name),
                                      log_to_console=kwargs.pop('verbose', False),
                                      log_route=section_name)
    
        # disable fallocate if desired
        if utils.config_true_value(conf.get('disable_fallocate', 'no')):
            utils.disable_fallocate()
        # set utils.FALLOCATE_RESERVE if desired
        reserve = int(conf.get('fallocate_reserve', 0))
        if reserve > 0:
            utils.FALLOCATE_RESERVE = reserve
    
        # By default, disable eventlet printing stacktraces
        eventlet_debug = utils.config_true_value(conf.get('eventlet_debug', 'no'))
        eventlet.debug.hub_exceptions(eventlet_debug)
    
        # Ensure TZ environment variable exists to avoid stat('/etc/localtime') on
        # some platforms. This locks in reported times to the timezone in which
        # the server first starts running in locations that periodically change
        # timezones.
        os.environ['TZ'] = time.strftime("%z", time.gmtime())
    
        try:
            #開始执行
            klass(conf).run(once=once, **kwargs)
        except KeyboardInterrupt:
            logger.info('User quit')
        logger.info('Exited')
    
    因ObjectReplicator继承了Daemon类,代码片段

     klass(conf).run(once=once, **kwargs)
    ObjectReplicator运行run方法,主要此时传入的once为False一般once在測试时能够设为True。

    继续看run方法,在Objector中没有实现run方法,其继承了父类的方法,

        def run(self, once=False, **kwargs):
            """Run the daemon"""
            utils.validate_configuration()
            utils.drop_privileges(self.conf.get('user', 'swift'))
            utils.capture_stdio(self.logger, **kwargs)
    
            def kill_children(*args):
                #SIGTERM = 15  SIG_IGN = 1L
                signal.signal(signal.SIGTERM, signal.SIG_IGN)
                os.killpg(0, signal.SIGTERM)
                sys.exit()
    
            signal.signal(signal.SIGTERM, kill_children)
            if once:
                self.run_once(**kwargs)
            else:
                self.run_forever(**kwargs)

    因once为False所以执行的是run_forever方法。从方法名字面上就能够看出这是一个永久执行的程序。也就是会成为守护进程。


      def run_forever(self, *args, **kwargs):
            self.logger.info(_("Starting object replicator in daemon mode."))
            # Run the replicator continually
            while True:
                start = time.time()
                self.logger.info(_("Starting object replication pass."))
                # Run the replicator
                #运行replicator 程序
                self.replicate()
                total = (time.time() - start) / 60
                self.logger.info(
                    _("Object replication complete. (%.02f minutes)"), total)
                dump_recon_cache({'object_replication_time': total,
                                  'object_replication_last': time.time()},
                                 self.rcache, self.logger)
                self.logger.debug(_('Replication sleeping for %s seconds.'),
                                  self.run_pause)
                #sleep 一段时间时间自己在部署时自己设定,也能够默觉得30秒
                sleep(self.run_pause)

    在run_forever方法中会运行replicate()方法。下一节介绍replicate方法的详细实现

  • 相关阅读:
    JVM底层原理 内存模型+GC垃圾回收
    新Socket与网络小结
    Redis五大数据结构及基本指令用法
    MySql高级汇总-事务,索引,SQL调优,分库分表,读写分离
    笔试错题整理
    设计模式(思路)
    网络编程
    linux
    基础算法--KMP匹配字符串
    基础算法--整数二分
  • 原文地址:https://www.cnblogs.com/jzssuanfa/p/7044499.html
Copyright © 2020-2023  润新知