preload 为True的情况下,会将辅助线程或者进程开在master里,加重master的负担(master最好只是用来负责监听worker进程)

django应用的gunicorn示例:只在主线程里开启后台线程,worker里不启动后台线程

gunicorn -w 5 --preload -b 127.0.0.1:8088 application_name.wsgi:application

wsgi.py文件:

"""
WSGI config for erebus project. It exposes the WSGI callable as a module-level variable named ``application``. For more information on this file, see
https://docs.djangoproject.com/en/2.1/howto/deployment/wsgi/
""" import os from django.core.wsgi import get_wsgi_application
from erebus.get_wsgi_application import get_wsgi_application
from whitenoise import WhiteNoise
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'erebus.settings') application = get_wsgi_application()
application = WhiteNoise(application, root='./static/')
# application.add_files('/path/to/more/static/files', prefix='more-files/')

重写的get_wsgi_application.py文件:

#!/usr/bin/env python
# -*- coding: utf- -*-
"""
@Author : xxxxx @Date : -- : @Description : 本文件的作用描述 @File : get_wsgi_application.py
""" import django
from django.core.handlers.wsgi import WSGIHandler def get_wsgi_application():
"""
The public interface to Django's WSGI support. Return a WSGI callable. Avoids making django.core.handlers.WSGIHandler a public API, in case the
internal WSGI implementation changes or moves in the future.
"""
django.setup(set_prefix=False)
# 把主进程中的kafka consumer线程放入启动过程中(即放入gunicorn的master进程中),
# 以使用gunicorn的preload参数控制这些线程的启动个数。
from utils.kafka_consumer_daemon import start_kafka_consumer_daemon
start_kafka_consumer_daemon()
return WSGIHandler()

后台线程:

# 使用线程池子
def start_kafka_consumer_daemon():
try:
for _ in range(CONSUMER_THREAD_NUM):
consumer = threading.Thread(target=consume_kafka)
consumer.setDaemon(True)
consumer.start()
except Exception as e:
logger.error(e)
logger.error(traceback.format_exc())

配置参考:https://github.com/benoitc/gunicorn/blob/29f0394cdd381df176a3df3c25bb3fdd2486a173/examples/example_config.py

配置解读:http://docs.gunicorn.org/en/stable/settings.html

Gunicorn+Flask中重复启动后台线程问题

假设程序如下:

1 if __name__ == '__main__':
2 t = Thread(target=test)
3 t.start()
4 app.run(host='0.0.0.0',port=8080,debug=False)

gunicorn在启动过程只会从flask的app文件中取出app使用,并不会执行main函数,如果希望在gunicorn中仍旧能启动后台线程并保证后台线程不因为gunicorn的子进程重复执行,有三种方式。

1.  使用gunicorn的preload参数。在worker进程被复制(派生)之前载入应用的代码。这种方式,线程执行代码需要写在app文件的全局部分,利用预加载只执行一下。

2. 使用flask的app的钩子函数before_first_request。在before_first_request中执行线程。但这种方式必须要有第一个请求才能触发线程启动。

3. 使用文件锁。这种方式与第一种方式相同,需要把线程执行的代码写在app文件的全局部分。在第一个子进程启动时创建文件并加锁,在后续的子进程启动时判断锁的状态,如果有锁则不执行。

以上通过奇怪的操作启动后台线程。但不推荐。可以考虑使用celery或者cron等方式实现需求。

参考:

1、https://www.jianshu.com/p/509985f98416

2、https://www.cnblogs.com/chenxianpao/p/9931483.html

3、

4、

gunicorn结合django启动后台线程的更多相关文章

  1. Gunicorn+Flask中重复启动后台线程问题

    假设程序如下: if __name__ == '__main__': t = Thread(target=test) t.start() app.run(host='0.0.0.0',port=808 ...

  2. Java多线程——<五>后台线程(daemon)

    一.后台线程(守护线程) 学一个东西,最重要的一点就是,为什么要用它? 后台线程区别于普通线程,普通线程又可以称为用户线程,只完成用户自己想要完成的任务,不提供公共服务.而有时,我们希望编写一段程序, ...

  3. 随web应用启动而自启动的后台线程

    当前遇到一个需求: 需要在web应用启动的时候就启动一个线程定时的来做某项工作. 有两种解决方法: 1.增加一个监听器Listener来实现相关功能. 2.增加一个随项目启动的servlet来实现相关 ...

  4. 使用Postgres,Nginx和Gunicorn将Django配置到服务器上

    先决条件 首先你得先在Digital Ocean上有一台自己的服务器,如果还没有,可参考教程如何在Digital Ocean上申请服务器. 为了方便起见,我将本教程分为两部分.第一部分(步骤1 - 6 ...

  5. 使用 Nginx 和 Gunicorn 部署 Django 博客(转)

    原文:http://zmrenwu.com/post/20/  http://www.siar.me/post/9/ 针对很多朋友反映按照教程的做法始终只能看到 Nginx 欢迎页面的问题,Tian ...

  6. Nginx 和 Gunicorn 部署 Django项目

    目录 Nginx 和 Gunicorn 部署 Django项目 配置Nginx 安装配置Gunicorn 通过命令行直接启动 Gunicorn 与 uwsgi 的区别,用哪个好呢 Gunicorn u ...

  7. C#夯实基础之多线程二:主线程、前台线程与后台线程

    我们在<C#夯实基础之多线程一:初识多线程>一文中第二部分中指出,既然windows最终发展出了多线程模型,按理说,我们直接使用一个.NetFramework的线程类就可以直接撸代码了,但 ...

  8. 开源WinForms界面开发框架Management Studio 选项卡文档 插件 Office 2007蓝色风格 后台线程

    Management Studio是我在WinForms小项目开发过程中搭建起来的一个插件式结构的应用程序框架,因为简单灵活又容易扩展,现在将它开源供读者参考. 跑起来的效果图如下所示,具备选项卡式多 ...

  9. HandlerThread 创建一个异步的后台线程

    使用HandlerThread几大优点: 1.制作一个后台异步线程,需要的时候就可以丢一个任务给它,使用比较灵活; 2.Android系统提供的,使用简单方便,内部自己封装了Looper+Handle ...

随机推荐

  1. 【LeetCode】142. Linked List Cycle II

    Difficulty:medium  More:[目录]LeetCode Java实现 Description Given a linked list, return the node where t ...

  2. Java核心编程快速入门

    Java核心编程部分的基础学习内容就不一一介绍了,本文的重点是JAVA中相对复杂的一些概念,主体内容如下图所示. 反射reflect是理解Java语言工作原理的基础,Java编译器首先需要将我们编写的 ...

  3. Eclipse设置之:代码注释/server 控制台输出乱码解决

    1           Eclipse设置 Configure clean up style The location is here: And the configuration should fo ...

  4. 项目冲刺First

    First Sprint 1.各个成员在 Alpha 阶段认领的任务(由于后面小组的讨论,修改本阶段的任务安排,()内为新任务安排) 蔡振翼:管理员界面.书籍管理,图书归还,消息,退出功能(撰写博客) ...

  5. BZOJ 4198: [Noi2015]荷马史诗 哈夫曼树 k叉哈夫曼树

    https://www.lydsy.com/JudgeOnline/problem.php?id=4198 https://blog.csdn.net/chn_jz/article/details/7 ...

  6. MySQL Replication(Master与Slave基本原理及配置)

    MySQL Replication(Master与Slave基本原理及配置) 1.  主从mysql server的工作原理:(如图及其过程分析) 过程:   Mysql的复制(replication ...

  7. hdu 5753 Permutation Bo 水题

    Permutation Bo 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5753 Description There are two sequen ...

  8. oracle 根据约束名查表名

    PK_ID为约束名 select constraint_name,constraint_type,table_name from all_constraints where CONSTRAINT_NA ...

  9. request.getRequestDispatcher("").forward()中文乱码

    即使jsp页面的编码已设为“UTF-8”,有中文的地方还是会出现乱码,但是用response.sendRedirect不会出现此问题. 解决方案一: 不使用PrintWriter out=respon ...

  10. phonegap helloworld 之android

    一 phonegap cordova: http://cordova.apache.org/phonegap: http://phonegap.com PhoneGap 是Cordova的一个开源的发 ...