Flask同步服务下多用户调用unoconv转换文档进程崩溃问题
问题根因
- 你对Flask运行模式的理解存在偏差:Flask 1.0及以上版本默认开启多线程支持,哪怕是单worker进程也会并行处理多个请求,并不会严格等待上一个请求处理完成再处理下一个,所以会出现多个用户的转换请求同时执行的情况。
- unoconv本身存在单实例限制:unoconv依赖LibreOffice的soffice后台进程完成转换,默认所有unoconv调用会复用同一个soffice实例,多请求同时调用会引发实例冲突。再加你代码中每次转换完成后都会全局杀死所有soffice.exe进程,会直接中断其他正在运行的转换任务,最终抛出你遇到的运行时异常。
解决方案
- 小流量场景可强制Flask单线程运行:开发环境启动时添加参数
threaded=False,示例:app.run(threaded=False);生产环境部署时将worker数、线程数都设置为1,让所有请求排队处理。该方案改动最小,但会降低接口并发能力,高流量下容易出现请求超时。 - 改造unoconv调用逻辑,避免实例共享:每个unoconv调用时指定独立的监听端口和用户配置目录,让每个任务启动独立的soffice实例,不会互相干扰,参考调用命令:
"C:\Program Files\LibreOffice\program\python.exe" "C:\Program Files\LibreOffice\program\unoconv" -f pdf -p <随机端口号> --user-profile=file:///C:/临时目录/lo_%随机标识%/ <待转换文件路径>
- 修复现有代码的不合理逻辑:删除全局kill所有soffice.exe的代码,改为仅清理当前转换任务对应的进程,或者给unoconv添加
--timeout参数让进程自动退出,避免误杀其他任务。另外你现有代码中print('error kill process'缺少右括号,属于语法bug,需要补充完整。 - 高并发场景引入异步任务队列:使用Celery、RQ等任务队列将转换任务异步化,设置队列的消费进程为单线程,所有转换任务排队执行,既不会出现并发冲突,也不会阻塞Flask的正常请求响应。
内容的提问来源于stack exchange,提问作者DRaDoN
相关产品推荐
相关产品推荐

