Ram*_*hum 7 python django infinite-loop web
我刚才想到的东西:
假设我正在为我的Django网站编写视图代码,我犯了一个错误并创建了一个无限循环.
每当有人试图访问视图时,分配给请求的工作者(无论是Gevent工作者还是Python线程)都将无限期地保持循环.
如果我理解正确,服务器将在30秒后向客户端发送超时错误.但是Python工作者会发生什么?它会继续无限期地继续工作吗?这听起来很危险!
想象一下,我有一台服务器,我已经分配了10名工人.我让它运行,在某些时候,客户端尝试使用无限循环访问视图.将为其分配一名工作人员,并且在下一次服务器重新启动之前,工作人员将被切换.危险的是,起初我不会注意到它,因为该站点只会在不知不觉中变慢,有9名工人而不是10名.但是这可能会在很长一段时间内,也许是几个月内一次又一次地发生.该网站将逐渐变慢,直到最终只有一名工人才会真的很慢.
服务器重启可以解决问题,但我不想让我的网站功能依赖于服务器重启.
这是一个真正的问题吗?有没有办法避免它?
更新:我也非常感谢一种方法来获取线程/工作者的堆栈跟踪,这种线程/工作者陷入无限循环,所以我可以通过电子邮件发送给我,这样我就会意识到这个问题.(我不知道怎么做,因为没有异常被提出.)
更新人们说"避免编写具有无限循环的代码"的效果:如果不明显,我不会花费我的空闲时间故意将无限循环放入我的代码中.当这些事情发生时,它们就是错误,错误可以被最小化但从未完全避免.我想要知道,即使我犯了错误,也会有一个安全网通知我并允许我解决问题.
这是一个真正的问题。在 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 )