Python 如何防止gunicorn eventlet workers在调度程序长时间运行的任务中超时退出?
我有一个小烧瓶应用程序,运行在一个用于磁盘分析的服务器上。它显示s.m.a.r.t。磁盘参数,我正在尝试向其添加磁盘格式化功能。不管它是什么类型的操作(安全的erace或只是“碎片”),但它需要相当长的时间。 起初,我尝试使用以下命令同步工人:Python 如何防止gunicorn eventlet workers在调度程序长时间运行的任务中超时退出?,python,flask,gunicorn,apscheduler,Python,Flask,Gunicorn,Apscheduler,我有一个小烧瓶应用程序,运行在一个用于磁盘分析的服务器上。它显示s.m.a.r.t。磁盘参数,我正在尝试向其添加磁盘格式化功能。不管它是什么类型的操作(安全的erace或只是“碎片”),但它需要相当长的时间。 起初,我尝试使用以下命令同步工人: ./venv/bin/gunicorn -b :5000 --access-logfile - --error-logfile - --log-file - -p myapp.pid -w 5 run:app 使用计划程序任务创建部件: if disk
./venv/bin/gunicorn -b :5000 --access-logfile - --error-logfile - --log-file - -p myapp.pid -w 5 run:app
使用计划程序任务创建部件:
if disk_type == 'NVMe':
scheduler.add_job(id=f'{serial}_formatting',
func=format_nvme,
args=[name, serial])
elif disk_type == 'HDD':
scheduler.add_job(id=f'{serial}_formatting',
func=format_hdd,
args=[name, serial])
...
和格式化功能:
def format_hdd(name, serial):
from run import app
with app.app_context():
print(f'[{datetime.now()}] initiated ssd formatting. name={name}, serial={serial}')
record_in_db = Disk.query.filter(Disk.serial == serial).first()
record_in_db.formatting_status = 1
db.session.commit()
info, error = Popen(f'wipefs -a {name}', shell=True, stdout=PIPE,
stderr=PIPE).communicate()
process = Popen(f'shred -v {name}', shell=True, stdout=PIPE, stderr=PIPE,
encoding='utf-8', errors='replace', bufsize=1)
while True:
realtime_output = process.stdout.readline()
if realtime_output == '' and process.poll() is not None:
break
if realtime_output:
record_in_db.formatting_last_msg = realtime_output
db.session.commit()
正如您所看到的,我希望存储流程消息,以便能够看到格式化的进度,这是一个重要的部分
run.py是:
from flaskapp import create_app
app = create_app()
from flaskapp import routes
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0', use_reloader=True)
在create_app()中,它只是初始化scheduler/db,如下所示:
if not scheduler.running:
scheduler.init_app(app)
scheduler.start()
...
return app
在大多数情况下,使用上面的gunicorn命令启动flaskapp会导致一个或几个工人超时退出,因为有时控制台在执行时没有任何命令输出:
[11209] [CRITICAL] WORKER TIMEOUT (pid:11214)
简单的决定-更大的超时,但格式化确实是很长的操作。。。给了我一个使用eventlet workers的想法,但没有帮助,我仍然会犯错误:
[2020-03-23 14:13:33 +0800] [29136] [CRITICAL] WORKER TIMEOUT (pid:29142)
Exception in worker
Traceback (most recent call last):
File "/usr/lib/python3.7/concurrent/futures/thread.py", line 78, in _worker
work_item = work_queue.get(block=True)
File "/home/user/flaskapp/venv/lib/python3.7/site-packages/gunicorn/workers/base.py", line 201, in handle_abort
sys.exit(1)
SystemExit: 1
我如何修复它并始终能够看到,该操作已结束?(所有这些命令都以任何方式结束了,但我只是不知道什么时候结束,因为工人们去世了)
或者可能有更合适的方法来实现此功能