我刚才想到的东西:
假设我正在为我的Django网站编写视图代码,我犯了一个错误并创建了一个无限循环。
每当有人试图访问该视图时,分配给该请求的工作人员(无论是Gevent工作者还是Python线程)都将无限期地保持循环。
如果我理解正确,服务器会在30秒后向客户端发送超时错误。但是Python工作者会发生什么?它会继续无限期地继续工作吗?这听起来很危险!
想象一下,我有一台服务器,我已经分配了10名工人。我让它运行,在某些时候,客户端尝试使用无限循环访问视图。将为其分配一名工作人员,并且在下一次重新启动服危险的是,起初我不会注意到它,因为该网站只会在不知不觉中变慢,有9名工人而不是10名。但是这可能会在很长一段时间内,也许是几个月内一次又一次地发生。该网站会逐渐变慢,直到最终只有一名工人才会变得非常缓慢。
服务器重启可以解决问题,但我不想让我的网站功能依赖于服务器重启。
这是一个真正的问题吗? 有没有办法避免它?
更新:我也非常感谢一种方法来获取陷入无限循环的线程/工作者的堆栈跟踪,所以我可以通过电子邮件发送给我,这样我就会意识到这个问题。 (我不知道怎么做,因为没有异常被提出。)
更新给人们说“避免编写具有无限循环的代码”的效果:如果不明显,我不会花费我的空闲时间故意将无限循环放入我的码。当这些事情发生时,它们就是错误,错误可以被最小化,但永远不会完全避免。我想知道即使我犯了错误,也会有一个安全网通知我,让我解决问题。
答案 0 :(得分:4)
这是一个真正的问题。如果是gevent,由于上下文切换,它甚至可以立即阻止您的网站响应。
一切都取决于您的环境。例如,当通过uwsgi在生产中运行django时,你可以设置harakiri
- 这是以秒为单位的时间,之后如果处理请求的线程没有完成处理响应,它将被终止。强烈建议设置这样的值以处理某些错误请求或错误代码。这种事件在uwsgi日志中报告。我相信在生产中运行Django的其他解决方案也有类似的选择。
否则,由于网络架构,客户端断开连接不会停止无限循环,并且默认情况下根本没有响应 - 只是无限加载。各种超时选项(其中一个harakiri
)可能最终显示连接超时 - 例如,php(据我记得)默认超时为30秒,它将返回504网关超时。套接字断开超时取决于http服务器设置,它不会停止应用程序线程,它只会关闭客户端套接字。
如果不使用gevent(或任何其他绿色线程),无限循环将倾向于占用100%的可用CPU功率(仅限于一个核心),可能会占用越来越多的内存,因此您的网站工作速度会相当慢和/或超时非常快。 Django本身并不知道请求时间,因此 - 如前所述 - 您的生产环境堆栈是防止这种情况发生的方法。如果是uwsgi,http://uwsgi-docs.readthedocs.org/en/latest/Options.html#harakiri-verbose是可行的方法。
Harakiri确实打印了被杀死进程的堆栈跟踪:(https://uwsgi-docs.readthedocs.org/en/latest/Tracebacker.html?highlight=harakiri)直接到uwsgi日志,并且由于报警系统,您可以通过电子邮件(http://uwsgi-docs.readthedocs.org/en/latest/AlarmSubsystem.html)
获得通知答案 1 :(得分:2)
我刚刚在Django的开发服务器上测试了这个。
<强>结果:强>
我想一种避免它的方法,实际上只是避免使用类似的代码,就是使用线程来控制超时并能够停止线程。
可能是这样的:
import threading
from django.http import HttpResponse
class MyThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
def run(self):
print "your possible infinite loop code here"
def possible_loop_view(request):
thread = MyThread()
thread.start()
return HttpResponse("html response")
答案 2 :(得分:0)
是的,您的分析是正确的。工作线程/进程将继续运行。而且,如果循环中没有等待/休眠,它将占用CPU。其他线程/进程将获得非常少的cpu,导致整个站点响应缓慢。
另外,我认为服务器不会明确地向客户端发送任何超时错误。如果设置了TCP超时,则TCP连接将被关闭。
客户端也可能有一些超时设置来获得响应,这可能会出现。
避免使用此类代码是避免此类代码的最佳方法。您还可以在服务器上使用一些监视工具来查找CPU /内存使用情况并通知异常活动,以便您可以采取措施。