Stack Overflow的第一篇文章,而不是(还)有Python / Django的经验,所以要善良:)
我正在开发一个Django Web应用程序,该应用程序在部署到Azure Web服务容器时表现出一些奇怪的行为。该应用程序包含一个页面,您可以从该页面上载包含要输入到支持应用程序的数据库中的记录的CSV文件。
处理文件提交的视图调用一个函数,该函数又启动后台工作线程(threading.Thread对象)来处理CSV文件并向调用视图返回一个简单的True / False状态以指示文件是否存在被接受了,线程是否成功启动。
您上传CSV文件的同一个应用程序页面也有一个带有计时器的JQuery机制,每2秒检索一次线程状态。这是通过一个简单的AJAX查询完成的,该查询由Django视图处理,该视图以JSON格式返回文本状态。状态包含在Python字典中,该字典包含键值对,其中键是后台线程名称,值是状态作为文本字符串。状态由工作线程更新,只需由AJAX处理程序读取并返回。
后台线程做了一些事情:
将正在运行的日志写入本地文件系统,该系统包含每个处理的CSV记录一个条目以及遇到的任何其他错误(例外等)。
将Azure存储帐户中的图像文件复制到本地应用程序存储,每个CSV记录一个
对支持应用程序的Azure SQL数据库进行多次访问。这些访问是通过应用程序中实现的Django模型和表单进行的。这些类用于获取各种实体的主键,并最终为每个CSV记录创建一个新对象,然后使用通常的Django form.save()调用将其保存到数据库中。
问题:
后台工作线程任意退出或被杀死,绝对没有任何错误迹象表明它停止。我已经添加了大量的日志记录(到上面提到的相同日志文件中),以显示几乎逐行详细信息的执行路径。每次提交CSV文件(每次使用相同的文件)时,日志都会停在不同的位置。它似乎与已处理的记录数或线程运行的时间无关。我已经看到线程可以存活大约30秒到超过5分钟,但总是比完全处理CSV文件所需的~2小时还要短。
上面描述的AJAX机制每2秒检索一次的线程状态是看到字典在大约一半时间内保持状态为空(?? !!)通常,当没有后台线程时,字典将为空当线程存在时,每个线程将有1个条目。甚至在线程莫名其妙地终止之前,主应用程序似乎间歇地看到字典(其中应该只有一个全局实例)为空,然后包含数据(然后为空,然后.....)
< / LI>可能与#2直接相关,主要应用程序实际上似乎完全是“失去视力”#34;后台线程。我有一个简单的视图附加到URL ... / threads,它返回所有活动线程的简单文本列表,由threading.enumerate()函数返回。反复点击该URL将显示存在的后台线程,然后不存在然后再次出现。当后台线程出现在列表中时,它的进程ID是不变的,但令我惊讶的是,列表中也显示的主线程进程ID不是常量。主线程似乎每隔几秒钟就会改变ID(或重新产生的东西)。我不知道这是否只是Django做其事情的一部分,但看起来很奇怪。
请注意,在Visual Studio中本地运行,使用内置的Django服务器并连接到本地SQL Server实例,我绝对不会看到这些问题。它们仅在Azure容器中运行时出现。
不幸的是我无法发布任何代码,因为此应用程序附带了一些知识产权问题,但我可以尝试回答任何人可能遇到的任何问题。
技术细节:
Python V2.7
Django V1.8.5
Azure App Service,标准:4大(不共享)
使用Visual Studio Enterprise 2015开发
非常感谢对此问题的任何见解。
更新: 通过一些额外的阅读和Microsoft Azure支持的一些调查,我们已经确定观察到的长时间运行后台线程的行为几乎肯定是由于底层IIS Web服务器如何处理线程和线程池。简短的故事是,我想我正在做一些与我正在使用的网络托管容器不相称的东西。我已经切换了齿轮并将我的后台处理任务划分为一个独立的实体,该实体将作为Azure Web作业运行。感谢所有回复。