zoukankan      html  css  js  c++  java
  • 转载——gunicorn的实践经验

    gunicorn的实践经验

    mania_yan 2020-03-08 21:42:31 783 收藏 3
    分类专栏: python
    版权
    为什么要上gunicorn?
    flask自带的web容器不满足生产环境的要求。生产环境不能直接采用flask自带的web容器。

    gunicorn是目前应用较广的支持WSGI的web容器。

    gunicorn能否替代flask自带的web容器进行开发调试?
    可以,加入- -reload,则代码变更后,gunicorn会自动重启。

    gunicorn的worker选择gevent时的注意事项
    当没有指定worker类型时,默认为同步类型,线程为native类型。

    异步worker gevent有很强的并发性能

    当worker指定为gevent或evenlet类型时,线程变成基于greentlet的task(伪线程),这时,线程数量的参数是无效的。

    采用gevent worker时,默认并发数量是1000,有很强的并发能力。

    gevent的兼容性问题

    但是,使用gevent时,系统会使用monkey patch。系统的部分函数会被修改。

    有些库的使用要选择兼容gevent的类型。

    例如,任务调度的库apscheduler,web socket需要socketio的库等,需要专门选择gevent的函数。

    而有些库则直接无法使用,例如多进程multiprocess。

    例如,在一个api请求中,如果需要使用多核cpu资源,采用multiprocess进行多进程计算。则会出现卡死的问题。gevent中,不能使用multiprocess库

    gunicorn的timeout参数
    gunicorn默认的timeout时间是30秒,这是满足web应用的典型参数。

    但是,我们是深度学习的领域,任务的执行需要的时间很长,所以,timeout参数是一个常用的参数。

    gunicorn的管理进程如果在timeout时间内,没有收到worker进程的消息心跳,则会认为worker进程出现了死亡,从而重启相应的worker进程。

    会导致worker进程正在执行的任务被中断。

    worker进程处于阻塞或高CPU计算时,会出现不能及时发送心跳给管理进程的问题。

    因此,对于深度学习领域,timeout要根据业务场景有余量的进行设置,才能保证时间较久的任务不被管理进程中断。

    gunicorn什么时候使用- -preload参数
    preload

    Load application code before the worker processes are forked

    默认情况下,gunicorn的每个进程,会将代码重新加载一次,以保障进程之间是互相隔离的。这样可以做到更好的兼容性。

    但是,有些情况,需要多个进程共享同一个资源时,或多个进程只能开启1个任务时,则需要使用- -preload

    使用preload后,API函数之外的初始化代码,只会出现在gunicorn的管理进程中,以共享的方式让worker进程访问

    (这个需要大家自己写demo代码好好体验一下,尤其是初始化变量打印进程号,感知一下preload的差异

    可以参考示例:https://testerhome.com/topics/18306)

    思考:gunicorn每个进程在执行log的rotate时的问题。

    gunicorn如何集成进程序,不通过命令行进行启动
    目前算法采用pyinstaller进行打包,只有一个自启动的执行文件,无法采用传统的gunicorn命令行加载内部代码变量的方式启动。

    制作基于gunicorn自启动执行文件,可以参考:http://docs.gunicorn.org/en/latest/custom.html

    gunicorn的日志问题
    我们平时的日志,只记录业务代码的日志。

    第三方库的日志和gunicorn自身的日志没有被正常记录在日志文件中,必须在docker的日志里去查看,这样不方便也容易导致丢失或管理不统一。

    简单示例代码:

    加入gunicorn日志

    去掉默认的,防止内容和gunicorn重复

    logger.removeHandler(default_handler)

    加入gunicorn的handler

    logger.handlers.extend(logging.getLogger('gunicorn.error').handlers)

    详细使用参考gunicorn的日志配置部分

    或者业务代码的log不变,gunicorn通过配置让其日志单独输出一个文件

    web socket的场景
    web socket是一个长连接方案,gunicorn默认的同步方式是不支持长连接的。

    当使用web socket时,建议独立一个程序,使用异步worker。否则,将它集成到主程序中,会强迫主程序的worker从同步改为异步。

    在ops模块中,主程序需要将最新信息推送到web时,可以通过消息队列(ops模块使用的是zeromq)实现进程间的通信,然后通过web socket的独立程序将消息发送到浏览器。

    未来,可以尝试ASGI的框架,ASGI是兼容WSGI,同时支持长连接的web socket和http2的推送机制,进一步简化设计。

    另外,web socket独立一个程序之后,需要关注其监控问题。

    默认的docker启动gunicorn服务,gunicorn服务死亡,docker服务会自动重启。

    但是,web socket采用另一个独立的后台进程服务,它的死亡不会导致docker重启。因此,如果web socket进程意外死亡是不会被自动重启的。需要加入监控软件。

    官方推荐了很多,目前项目已经使用的有supervisor,使用非常简单。

    其他问题
    为什么ocr server中,要加入nginx,有什么作用?

    正常来说,无需nginx,gunicorn可以正常提供服务。

    但是,C++的插件在发送图片给ocr server时,经常会出现witch的错误(目前未知什么原因)。

    加入nginx后,无此问题。

    (官方推荐使用nginx:Although there are many HTTP proxies available, we strongly advise that you use Nginx.)

    原文连接:https://blog.csdn.net/yyw794/article/details/104741340/

  • 相关阅读:
    《需求工程——软件建模与分析》读后感之三
    项目目标文档
    利益相关者描述案例
    《需求工程——软件建模与分析》读后感之二
    《需求工程——软件建模与分析》读后感之一
    专业实训题目需求分析
    《代码之美》读后感
    计算“1”的数量
    团队冲刺第九天
    linux df 命令
  • 原文地址:https://www.cnblogs.com/pythonwl/p/14270517.html
Copyright © 2011-2022 走看看