我有一个python Django manage命令,应该在收到输入文件时调用,但此命令对于并行调用不安全。因此,仅当没有其他文件正在处理时,才应处理输入文件。
我有一个解决方案是使用锁定文件。基本上,在过程开始时创建一个锁定文件,并在结束时将其删除。
我担心如果进程崩溃,锁定文件将不会被删除,因此在我们手动删除该锁定文件之前,不会处理其他文件。
该解决方案不需要特定于 Django 甚至 python,但是强制只运行此过程的一个实例的最佳实践是什么?
正如 KlausD 在他的评论中提到的,规范(和语言无关(解决方案是使用包含正在运行的进程的 pid 的锁文件,因此负责锁获取的代码可以检查进程是否仍在运行。
如果在项目中使用 redis 的替代解决方案是将锁定存储在 redis 中,其 TTL 比任务的最坏情况运行时稍长。这确保了锁将被释放,并且还允许在需要时在多个服务器之间轻松共享锁。
编辑:
是否有可能进程崩溃并且另一个进程拾取相同的 PID?
是的,当然,在运行一个月或更长时间而不重新启动的服务器上,这甚至很有可能(这是一个轻描淡写的说法(,如果服务器运行大量短期进程,则更是如此。您不仅要检查是否有与此 pid 匹配的正在运行的进程,还要获取进程统计信息以检查进程开始时间、命令行、父进程等,并确定它是同一进程还是新进程的可能性。
请注意,这并不是什么新鲜事 - 大多数过程监控工具都面临相同的问题,因此您可能需要检查它们是如何解决的(gunicorn 可能是一个很好的起点(。