zoukankan      html  css  js  c++  java
  • gunicorn启动flask项目的坑

    问题描述:项目用的是flask框架,在项目上线的时候,服务器上是使用gunicorn来启动项目的。但是上线之后,发现服务成功启动了,也有正确的返回值,但是没有生成日志,而用python来启动服务的时候,是会生成日志的。

    下面是要上线的服务的入口文件server.py的主要代码块:

    from xxx import app   # app = Flask(__name__)
    
    if __name__ == '__main__':
        log_init('xx', 'xxx')
        app.run(host='0.0.0.0', port=8000, threaded=True)
    

    log_init是一个工具方法,用来初始化日志。

    gunicorn启动服务的时候是用下面的命令启动的:

    ~/anaconda/envs/my_py3/bin/gunicorn -w 5 -b 0.0.0.0:8000 --threads 6 server:app
    

    问题的原因:Python只有在这个脚本是Python解释器的入口文件的时候,才会把它的__name__的值置为'__main__',但是用gunicorn启动的时候,这个脚本是被用import导入了,所以对于Python解释器来说,这个脚本根本就不是入口文件,所有__name__的值不等于'__main__',所有也就不会执行if __name__ == '__main__'里面的代码块。而用Python启动的时候,这个文件就是Python解释器的入口文件。

    那么问题来了,为什么这两行代码没有执行,服务还是可以起来呢,因为对gunicorn来说,它只要知道app是哪个就可以了,不需要知道其它,而上面的那条用gunicorn启动服务的命令中,已经指定了ip和端口号,所以服务可以成功启动起来。而且如果把代码放到外面,写成下面的这种形式也是会报错的:

    from xxx import app   # app = Flask(__name__)
    
    log_init('xx', 'xxx')
    app.run(host='0.0.0.0', port=8000, threaded=True)
    

    这里报错是因为gunicorn的那条命令已经启动了一个app了,然后app.run(host='0.0.0.0', port=8000, threaded=True)这行代码又要启动一个app,端口被占用了。

    所以最好写成下面这种方式,这样的话就可以兼容gunicorn和python启动两种方式。

    from xxx import app   # app = Flask(__name__)
    
    log_init('xx', 'xxx')
    if __name__ == '__main__':
        app.run(host='0.0.0.0', port=8000, threaded=True)

     
  • 相关阅读:
    iOS 苹果开发证书失效的解决方案(Failed to locate or generate matching signing assets)
    iOS NSArray数组过滤
    App Store2016年最新审核规则
    iOS 根据字符串数目,自定义Label等控件的高度
    iOS 证书Bug The identity used to sign the executable is no longer valid 解决方案
    Entity FrameWork 增删查改的本质
    EF容器---代理类对象
    Entity FrameWork 延迟加载本质(二)
    Entity FrameWork 延迟加载的本质(一)
    Entity FrameWork 增删查改
  • 原文地址:https://www.cnblogs.com/ExMan/p/10775686.html
Copyright © 2011-2022 走看看