在Python中,如何仅在程序退出关键部分后处理SIGTERM?
一个名为“eventcollector”的Python 2.7程序持续运行,并轮询Web服务中的事件。然后,它将每个事件作为JSON对象附加到文件-/var/log/eventsexample.JSON的末尾。代理跟踪该文件并将事件发送到处理事件的基于云的软件“anycloud” 我需要使eventcollector成为行为良好的UNIX守护程序,然后使该守护程序成为systemd中的服务。我将为此目的创建的systemd.service单元将让systemd知道,当停止此服务时,它必须在发送SIGTERM后等待15秒,然后再发送SIGKILL。这将使eventcollector有时间保存状态并关闭它正在写入的文件(它自己的日志文件和事件文件)。A将被配置为我现在必须使这个程序更有弹性。程序必须能够保存其状态,以便在终止和重新启动时,程序知道其停止的位置 Eventcollector对任何云都没有可见性。它只能看到源服务中的事件。如果Eventcollector因重新启动而死亡,它必须可靠地知道查询源服务事件的新开始时间。因此,在退出和保存状态之前完成将事件写入文件的关键业务是至关重要的 我的问题是关于如何处理SIGTERM,以便程序有时间完成它正在做的事情,然后保存它的状态 然而,我担心的是,除非我在每次写入文件的消息之后都写入状态(这将消耗比看起来必要的更多的资源),否则如果不及时保存状态,我无法确保我的程序不会终止。这将产生重复消息的影响,重复消息是不可接受的 如果我必须承受性能损失,我会的,但我更希望有一种方法能够优雅地处理SIGTERM,以便程序能够巧妙地执行以下操作,例如(简化伪代码摘录):在Python中,如何仅在程序退出关键部分后处理SIGTERM?,python,linux,multithreading,python-2.7,signals,Python,Linux,Multithreading,Python 2.7,Signals,一个名为“eventcollector”的Python 2.7程序持续运行,并轮询Web服务中的事件。然后,它将每个事件作为JSON对象附加到文件-/var/log/eventsexample.JSON的末尾。代理跟踪该文件并将事件发送到处理事件的基于云的软件“anycloud” 我需要使eventcollector成为行为良好的UNIX守护程序,然后使该守护程序成为systemd中的服务。我将为此目的创建的systemd.service单元将让systemd知道,当停止此服务时,它必须在发送S
为true时:
response=使用返回方法查询Web服务
100本字典(事件)的列表
对于响应中的i.data:
event=json.dumps(i)
outputfile.write(i)#<在第二个事件期间接收SIGTERM,但不
退出,直到for循环完成。(怎么做?)
信号处理器:
用当前状态pickle对象。
其思想是,即使在编写第二个事件时收到了SIGTERM,程序也会等到编写了第100个事件后,才决定是否安全地处理SIGTERM
我在报纸上读到:
无法暂时“阻止”来自关键部分的信号(因为并非所有Unix版本都支持这种方式)
我的一个想法似乎太复杂了,我觉得一定有更简单的方法。这个想法是:
我正在考虑使用我理解为Ben Finney对他所写的PEP[PEP 3143](>)的参考实现。根据他所写的内容,以及我从使用UNIX和UNIXlike操作系统的经验中所看到的,我理解什么是“良好行为”在守护进程方面,我没有达成一致意见。我之所以提到这一点,是因为我同意PEP 3143,并希望实现这一点,但它没有回答我当前的问题,即如何像我希望的那样处理信号。您的守护进程使用的是python 2.7
python在进行系统调用时使用起来并不方便,这对信号量的使用不利 我不确定在python中使用
全局变量的副作用和注意事项
文件锁
脆弱,文件系统IO对信号处理程序不好
所以我没有一个完美的答案,只有想法
这是我在C中实现一个小守护进程时的想法
主线程设置一个同步点,对于一个C程序,/dev/shm、信号量、全局变量、文件锁是我考虑过的事情,最后我选择了/dev/shm
设置信号处理程序,在接收到SIGTERM时,通过更改/dev/shm中存储的值来提升同步标志
在每个工作线程中,在作业的一部分之后检查/dev/shm以获取同步标志,如果该标志被触发,则退出自身
在主线程中,设置一个捕获线程,尝试捕获其他所有工作线程,如果成功捕获,则继续退出守护进程本身
我不相信我问了一个很好的问题。我认为我已经足够具体了,但我不确定我是否足够详细。我想在根据我的方法编写代码之前,了解如何最好地处理信号……与您最初的问题无关:如何处理kille后的恢复d by SIGKILL?如果重复消息不可接受,SIGKILL会比SIGTERM造成更多问题,而通过解决SIGKILL,你就解决了SIGTERM,一箭双雕。@bigdataoldriver,同意。既然我不能控制SIGKILL,我也可能会受到性能的影响。否则,这取决于服务的安装方式。我仍然会保留问题,因为我认为知道是否有比我的想法更好的方法处理它是有价值的
while true:
response = query the webservice using method returning
a list of 100 dictionaries (events)
for i in response.data:
event = json.dumps(i)
outputfile.write(i) #< Receive SIGTERM during 2nd event, but do not
exit until the for loop is done. (how?)
signal handler:
pickle an object with the current state.