除了IIS 调用office组件的com_error 里提到的权限问题之外,调用 COM 对象的另一个常见的坑就是多进程问题。
还是用 python 调 word 来转 pdf 为例,下面几行代码就能够实现该功能。
from win32com.client import DispatchEx
import pythoncom
# 完成 docx -> pdf
pythoncom.CoInitialize()
word = DispatchEx("Word.Application")
doc = word.Documents.Open('1.docx')
doc.SaveAs('1.pdf', FileFormat=17)
doc.Close()
word.Quit()
pythoncom.CoUninitialize()
开发环境都没有问题。上线后,时不时就会报出 permission denied
之类的错误。
原因
经过分析,定位故障是由web服务的多进程机制触发的。也就是说,web服务会有多个进程同时服务用户请求。如果两个进程同时操作同一个word文件,上述代码就会报错。这也是微软官方并不推荐使用word COM接口作为服务的主要原因——它并没有做多进程优化管理。
解决方案
可以用消息队列解耦。web服务的多个进程把待处理的任务交给消息队列,然后再启动一个单进程的消费者,来专门处理任务即可。
网友评论