背景:最近在做的全域事件项目,快要靠近尾声了,需要用到uwsgi部署至生产环境,由于之前是debug模式,运行项目也是通过命令 python manager.py runserver (manage是通过flask_script创建的脚本管理,用于类似django的数据库初始化、迁移和管理app等操作)。现项目由uwsgi管理,由于uwsgi一些特性造成项目运行中出现的一系列问题,顺便记录下解决方案。

uwsgi.ini

 1 [uwsgi]
2 # 项目文件夹
3 chdir = xxx/xxx/xxx
4 # wsgi文件路经
5 wsgi-file = xxx/xxx/xxx/manage.py
6 # 回调的app对象
7 callback = manager
8 # 虚拟环境路经
9 home = /home/xxx/.virtualenvs/xxx
10 # 主进程
11 master = true
12 # 最大输了的工作进程
13 processes = 2
14 # 项目中使用的IP:端口
15 http = xxx.xxx.xxx.xxx:5000
16 # 退出的时候是否清理环境
17 vacuum = true
18 # uwsgi日志文件路经
19 daemonize = /home/xxx/xxx/xxx/uwsgi.log
20 # 进程pid文件
21 pidfile = /home/xxx/xxx/xxx/uwsgi.pid

一、uwsgi通过callback回调app,manager虽管理app,但并不能提供uwsgi所用到的回调的app,直接如上配置callback=manager,接口请求在uwsgi.log中会看到__callback__错误,因为数据库迁移后manager没什么用,因此将manager换成原app,如下:

manager.py

1 from xxx import create_app
2
3 # 创建flask应用对象
4 app = create_app("product")
5
6
7 if __name__ == '__main__':
8
9 app.run()

uwsgi.ini修改callback

1 # 回调的app对象
2 callback = app

二、flask_apscheduler定时任务不启动

uwsgi启动后在没有请求的时候,部分进程会被挂起,需在uwsgi.ini中增加如下配置:

1 # flask_apscheduler配置
2 enable-threads = true
3 preload = true
4 lazy-apps = true

三、uwsgi启动后,定时任务启动两次,重复启动

原因uwsgi中开启了两个进程,进程独享一份资源,因此两个进程都启动了各自的scheduler,网上找了许久解决方案后,最终确定用文件锁的方式解决

create_app函数中

 1 from xxx.tasks import scheduler
2 import os
3 import atexitcc
4 import fcntl
5
6 def create_app(config_name):
7 app = Flask(__name__, template_folder="static/")
8 。。。
9
10 # 使用app初始化任务
11 # 使用文件锁,解决flask_apscheduler定时任务重复启动问题
12 f = open(os.path.join(BASE_DIR, "xxx/xxx/scheduler.lock"), "wb")
13 try:
14 fcntl.flock(f, fcntl.LOCK_EX | fcntl.LOCK_NB)
15 scheduler.init_app(app)
16 scheduler.start()
17 except:
18 pass
19
20 def unlock():
21 fcntl.flock(f, fcntl.LOCK_UN)
22 f.close()
23
24 # 注册退出事件,如果flask项目退出,则解除scheduler.lock文件锁并关闭文件
25 atexit.register(unlock)

四、uwsgi启动项目后,config中配置的定时任务正常运行且不会重复启动,uwsgi.log中也可以看到scheduler正常启动;但通过api启动,使用scheduler.add_job()方式启动的任务,从uwsgi.log中发现是等待scheduler start状态,由此发现还是创建了两个scheduler对象。看了许久代码后发现了问题

因为项目中需要运行的任务较多,任务函数也都是需要区分开写在不同py文件中的,因此为了方便管理,我在项目中创建了tasks文件夹(python包),在tasks中的__init__.py文件中定义了scheduler对象,tasks中的各任务文件引用此scheduler并使用

tasks.__init__.py

 1 from flask_apscheduler import APScheduler
2 from apscheduler.schedulers.background import BackgroundScheduler
3 from multiprocessing import Queue
4
5 # APScheduler任务对象
6 scheduler = APScheduler(BackgroundScheduler(timezone="Asia/Shanghai"))
7
8 # 任务流
9 event_info_q = Queue()
10
11 # 处理的任务中间件列表
12 middleware_li = []

因此在uwsgi开启多进程情况下,scheduler还是因多进程创建了多次,加上文件锁的原因,仅一个scheduler被启动,于是改动如下:

tasks.__init__.py

1 # APScheduler任务对象
2 scheduler = None
3
4 # 任务流
5 event_info_q = Queue()
6
7 # 处理的任务中间件列表
8 middleware_li = []

create_app函数

 1 from flask_apscheduler import APScheduler
2 from apscheduler.schedulers.background import BaskgroundScheduler
3 from xxx import tasks
4 import os
5 import atexit
6 import fcntl
7
8 def create_app(config_name):
9 app = Flask(__name__, template_folder="static/")
10 。。。
11
12 # 使用app初始化任务
13 # 使用文件锁,解决flask_apscheduler定时任务重复启动问题
14 f = open(os.path.join(BASE_DIR, "xxx/xxx/scheduler.lock"), "wb")
15 try:
16 fcntl.flock(f, fcntl.LOCK_EX | fcntl.LOCK_NB)
17 tasks.scheduler = APScheduler(BaskgroundScheduler(timezone="Asia/Shanghai"))
18 tasks.scheduler.init_app(app)
19 tasks.scheduler.start()
20 except:
21 pass
22
23 def unlock():
24 fcntl.flock(f, fcntl.LOCK_UN)
25 f.close()
26
27 # 注册退出事件,如果flask项目退出,则解除scheduler.lock文件锁并关闭文件
28 atexit.register(unlock)

因为项目启动后首先调用的是create_app,create_app中将tasks.__init__.py中的scheduler重置为了APScheduler对象,并初始化app和启动,因此tasks文件夹内的各任务文件引用scheduler对象不会出现问题。

uwsgi部署flask,flask_apscheduler任务遇到各种问题解决的更多相关文章

  1. 使用Nginx和uwsgi部署Flask项目

    前言   之前用Flask框架开发了一个Python的Web项目,使用Nginx和uWSGI部署起来感觉挺麻烦,过程中还因为对Flask框架的不熟悉,花了好长时间才把应用完全部署起来.下面分享部署成功 ...

  2. CentOS 下用 Nginx 和 uwsgi 部署 flask 项目

    前几天利用flask 写了几个调用salt-api 的接口,需要上线到正式环境,搜了一下 都是 用 nginx + uwsgi 来部署,这里记录下关键的配置项. 1.首先将代码上传到服务器上目录为: ...

  3. Nginx+uWSGI部署flask项目

    uwsgi配置 uwsgi安装 安装uwsgi pip install uwsgi 启动uwsgi uwsgin --ini uwsgi.ini # 后台启动 nohup uwsgi --ini uw ...

  4. nginx+uwsgi部署flask应用后只能在本机访问解决办法,ipv4 和ipv6

    我的系统是centos7 nginx监听8888端口 在window下  :telnet 192.168.81.224 8888  发现连接不上, 端口22能连上 关闭224的防火墙就好了 syste ...

  5. 使用Flask+uwsgi+Nginx部署Flask正式环境

    环境准备 在开始正式讲解之前,我们将首先进行环境准备. Step1:安装Python,pip以及nginx: sudo apt-get update sudo apt-get install pyth ...

  6. 通过Nginx部署flask项目

    用Flask开发之后,很多人,喜欢用nohup python manage.py & 这样的形式,放到后台运行,其实这样只是个发开模式,很简陋,无法支持并发,进程监控等功能.所以采用nginx ...

  7. 将树莓派变成一个web服务器(2):Nginx+Flask+uWSGI部署全过程

    1)安装Flask,uwsgi,nginx sudo apt-get update sudo apt-get install python-flask #Flask sudo apt-get inst ...

  8. 使用Nginx+Uwsgi部署Python Flask项目

    第一次用Flask做Web(也是第一次用Python做Web),在部署的时候遇到了不少问题,现在将过程就下来,供在这方面也有疑惑的人参考.(PS:使用Apache+mod_wsgi部署模式的可以参考另 ...

  9. 如何使用Nginx和uWSGI或Gunicorn在Ubuntu上部署Flask Web应用

    你好!欢迎阅读我的博文,你可以跳转到我的个人博客网站,会有更好的排版效果和功能. 此外,本篇博文为本人Pushy原创,如需转载请注明出处:https://pushy.site/posts/151981 ...

  10. uWSGI+Nginx+Flask在Linux下的部署

    搞了一天多,终于搞通了uWSGI的部署原理,下面总结一下遇到的一些坑,希望给读者能够少走弯路.        简单来说,uWSGI是一个web服务器,Nginx进行反向代理的其实跟这些服务器可以说没有 ...

随机推荐

  1. 注解_概念-注解_JDK内置注解

    注解_概念 注解: 概念:说明程序的.给计算机看的 注释:用文字描述程序的.给程序员看的 定义︰注解(Annotation),也叫元数据.一种代码级别的说明.它是J0K1.5及以后版本引久的一个特性, ...

  2. 使用字节流丢读取中文的问题-Reader类

    使用字节流丢读取中文的问题 当使用字节流读取文本文件时,可能会有一个小问题.就是遇到中文字符时,可能不会显示完整的字符,那是因为一个中文字符可能占用多个字节存储.所以Java提供一些字符流类,以字符为 ...

  3. Collection集合常用功能-Iterator接口介绍

    Collection集合常用功能 Collection是所有单列集合的父接口,因此在Collection中定义了单列集合(List和Set)通用的一些方法,这些方法可用于操作所有的单列集合.方法如下︰ ...

  4. 计算机网络基础09 TCP/IP

    https://www.jianshu.com/p/066d99da7cbd 1 概念 TCP/IP[TCP(传输控制协议)和IP(网际协议)]提供点对点的链接机制,将数据应该如何封装.定址.传输.路 ...

  5. 继承与多态 动手动脑3方法覆盖(override)”的要点

    方法覆盖(override)"的要点 方法覆盖要求子类与父类的方法一模一样,否则就是方法重载(overload)! 在子类中,若要调用父类中被覆盖的方法,可以使用super关键字. 以下子类 ...

  6. C++练习-1 简单输入输出

    首先完整代码如下: #include <iostream> #include <string> using namespace std; int main() { int on ...

  7. 推荐系统[一]:超详细知识介绍,一份完整的入门指南,解答推荐系统相关算法流程、衡量指标和应用,以及如何使用jieba分词库进行相似推荐

    1. 推荐算法的初步理解 如果说互联网的目标就是连接一切,那么推荐系统的作用就是建立更加有效率的连接,推荐系统可以更有效率的连接用户与内容和服务,节约了大量的时间和成本. 1.1 推荐系统主要解决问题 ...

  8. JZOJ 5451.Genocide

    题目 题解 对于 \(m=1\) 这档分 我们可以 \(dp\) 然后斜率优化 具体来说就是 \(f_i = f_j + \frac{(i-j)\times (i-j+1)}{2} + sum[j]- ...

  9. 跳板攻击之:reGeorg 代理转发

    跳板攻击之:reGeorg 代理转发 郑重声明: 本笔记编写目的只用于安全知识提升,并与更多人共享安全知识,切勿使用笔记中的技术进行违法活动,利用笔记中的技术造成的后果与作者本人无关.倡导维护网络安全 ...

  10. 比较多普勒超声与临床缓解标准对RA放射学进展的预测效能

    比较多普勒超声与临床缓解标准对RA放射学进展的预测效能 de Miguel, et al. EULAR 2015. Present ID: FRI0586. 原文 译文 FRI0586 DOPPLER ...