Nginx通过uwsgi发布Django项目导致Apscheduler计划任务不能正常运行

说明

在项目中,需要使用到定时执行函数的操作,通过Apscheduler写了一个定时任务,启动时发现出现以下错误。

Exception in thread Thread-18:
Traceback (most recent call last):
  File "/usr/local/software/Python3.6/lib/python3.6/threading.py", line 916, in _bootstrap_inner
    self.run()
  File "/usr/local/software/Python3.6/lib/python3.6/threading.py", line 1182, in run
    self.function(*self.args, **self.kwargs)
  File "./Timer/Timer.py", line 44, in Interface_Monitor_Timer
    Monitor_Timer_clock1.start()
  File "/usr/local/software/Python3.6/lib/python3.6/threading.py", line 846, in start
    _start_new_thread(self._bootstrap, ())
RuntimeError: can't start new thread

出现以上错误后,项目还能正常运行,不过会消耗大量服务器资源。通过项目长时间的运行,会出现以下错误。

Unhandled exception in thread started by <bound method Thread._bootstrap of <Timer(Thread-780, started 140604168185600)>>
Traceback (most recent call last):
  File "/usr/local/software/Python3.6/lib/python3.6/threading.py", line 916, in _bootstrap_inner
  File "/usr/local/software/Python3.6/lib/python3.6/threading.py", line 1180, in run
  File "/usr/local/software/Python3.6/lib/python3.6/threading.py", line 551, in wait
MemoryError

解决方式

此情况在开发环境中没有遇到(开发环境使用python manager.py runserver 0.0.0.0:80启动项目),而在生产环境中使用python manager.py runserver 0.0.0.0:80启动项目也正常。通过网上查询资料,没有找到解决方法。最后无意间发现是由uwsgi的配置导致的,更改uwsgi.ini文件后,项目正常运行。

之前的配置:

[uwsgi]
env = LC_CTYPE=zh_CN.utf-8
socket = 127.0.0.1:8001
master = false
workers = 1
reload-mercy = 100
vacuum = true
enable-threads = True
max-requests = 1000
limit-as = 512
buffer-size = 30000
daemonize = /var/log/uwsgi.log
pidfile = /tmp/uwsgi.pid

解决问题之后的配置:

[uwsgi]
# 字符编码
env = LC_CTYPE=zh_CN.utf-8
# 项目目录
chdir=/Project/WEB_PRO
# 指定项目的application
module=WEB_PRO.wsgi:application
# 进程个数
workers=5
pidfile=/tmp/uwsgi.pid
# 指定IP端口,以下是通过 uwsgi 访问的端口
http= :8010
# 转发给nginx的端口号
socket = 127.0.0.1:8001
# 指定静态文件
#static-map=/static=/var/web/工程目录/static
# 启动uwsgi的用户名和用户组
uid=root
gid=root
# 启用主进程
master=true
# 自动移除unix Socket和pid文件当服务停止的时候
vacuum=true
# 序列化接受的内容,如果可能的话
thunder-lock=true
# 启用线程
enable-threads=true
# 设置自中断时间
harakiri=30
# 设置缓冲
post-buffering=4096
# 设置日志目录
daemonize=/var/log/uwsgi.log
#目录中一旦有文件被改动就自动重启
touch-reload=/Project/WEB_PRO

借鉴资料

Django APScheduler + uwsgi 定时任务重复运行

django 异步执行定时任务APScheduler

Django Nginx+uwsgi 安装配置

Django中使用django-apscheduler执行定时任务

二〇二〇年四月十五日 10:10:52

THE END