openstack 源码分析之swift proxy 服务启动 2

来源:互联网 发布:天谕豪男捏脸数据 编辑:程序博客网 时间:2024/06/14 08:52

接上篇 

通过wift-proxy-server 脚本,swift调用swift.common.wsgi中的run_wsgi(conf_file, 'proxy-server', default_port=8080, **options) 启动 wsgi服务

def run_wsgi(conf_path, app_section, *args, **kwargs):    """    Runs the server using the specified number of workers.    :param conf_path: Path to paste.deploy style configuration file/directory    :param app_section: App name from conf file to load config from    """    # Load configuration, Set logger and Load request processor    try:        (conf, logger, log_name) = \            _initrp(conf_path, app_section, *args, **kwargs)    except ConfigFileError, e:        print e        return    # bind to address and port    sock = get_socket(conf, default_port=kwargs.get('default_port', 8080)) #socket 绑定端口和conf中的ip地址得到socket    # remaining tasks should not require elevated privileges    drop_privileges(conf.get('user', 'swift'))    # Ensure the application can be loaded before proceeding.    loadapp(conf_path, global_conf={'log_name': log_name})    # set utils.FALLOCATE_RESERVE if desired    reserve = int(conf.get('fallocate_reserve', 0))    if reserve > 0:        utils.FALLOCATE_RESERVE = reserve    # redirect errors to logger and close stdio    capture_stdio(logger)    worker_count = int(conf.get('workers', '1'))    # Useful for profiling [no forks].    if worker_count == 0:        run_server(conf, logger, sock) #使用得到的socket,logger日志, 和配置运行server        return


下来转入 run_server()函数 真正启动wsgi 服务 使用基于eventlet的并发多线程网络IO库,实现了协程 (博大精深,要慢慢学习)

def run_server(conf, logger, sock):    # 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())    wsgi.HttpProtocol.default_request_version = "HTTP/1.0" #以下都设置此wsgi服务的http协议    # Turn off logging requests by the underlying WSGI software.    wsgi.HttpProtocol.log_request = lambda *a: None    # Redirect logging other messages by the underlying WSGI software.    wsgi.HttpProtocol.log_message = \        lambda s, f, *a: logger.error('ERROR WSGI: ' + f % a)    wsgi.WRITE_TIMEOUT = int(conf.get('client_timeout') or 60)    eventlet.hubs.use_hub(get_hub())    eventlet.patcher.monkey_patch(all=False, socket=True)    eventlet_debug = config_true_value(conf.get('eventlet_debug', 'no'))    eventlet.debug.hub_exceptions(eventlet_debug)    # utils.LogAdapter stashes name in server; fallback on unadapted loggers    if hasattr(logger, 'server'):        log_name = logger.server    else:        log_name = logger.name    app = loadapp(conf['__file__'], global_conf={'log_name': log_name})#loadapp方法加载conf文件中的app的app_factory实例化这些app    max_clients = int(conf.get('max_clients', '1024'))    pool = RestrictedGreenPool(size=max_clients) #RestrictedGreenPool线程池用来实现协程,保证并行    try:        wsgi.server(sock, app, NullLogger(), custom_pool=pool) #使用eventlet库中的wsgi.server实现携程(多线程的并发运行app并管理socket,实现对请求的非阻塞IO)    except socket.error, err:        if err[0] != errno.EINVAL:            raise    pool.waitall()

上述的app就是 配置文件中 wsgi管道中的app 他们都要实现__call__方法保证是callable的,这些wsgi app 响应请求的操作就在__call__方法中实现(以后会说到) 并且服务的启动顺序和响应顺序应该是相反的。