如何限制网络请求期间的数据库查询时间?
我们有一个在 postgresql 9.0 上运行的非常典型的 django 应用程序。我们最近发现一些数据库查询由于管理界面中的搜索效率低下而运行了超过 4 小时。虽然我们计划修复这些查询,但作为一种保护措施,我们希望人为地将数据库查询时间限制为 15 秒——但仅限于 Web 请求的上下文中;批处理作业和 celery 任务不应受此约束的限制。
我们怎样才能做到这一点?或者这是一个糟糕的主意?
We've got a pretty typical django app running on postgresql 9.0. We've recently discovered some db queries that have run for over 4 hours, due to inefficient searches in the admin interface. While we plan to fix these queries, as a safeguard we'd like to artificially constrain database query time to 15 seconds--but only in the context of a web request; batch jobs and celery tasks should not be bounded by this constraint.
How can we do that? Or is it a terrible idea?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
执行此操作的最佳方法是设置仅用于运行 Web 请求的角色/用户,然后在该角色上设置 statements_timeout。
所有其他角色将使用statement_timeout 的全局设置(在库存安装中禁用)。
The best way to do this would be to set up a role/user that is only used to run the web requests, then set the statement_timeout on that role.
All other roles will use the global setting of statement_timeout (which is disabled in a stock install).
您需要手动处理这个问题。即检查 15 秒规则并终止违反该规则的查询。
查询 pg_stat_activity 并找到违规者并调用 pg_terminate_backend(procpid) 来杀死违规者。
循环中是这样的:
You will need to handle this manually. That is checking for the 15 second rule and killing the queries that violate it.
Query pg_stat_activity and find the violators and issue calls to pg_terminate_backend(procpid) to kill the offenders.
Something like this in a loop:
就计时而言,您可以通过一个类传递所有查询,该类在实例化时会生成两个线程:一个用于查询,另一个用于计时器。如果计时器达到 15 秒,则终止带有查询的线程。
至于确定查询是否是从 Web 请求实例化的,我对 Django 的了解还不够,无法帮助您。简单地说,在处理数据库调用的类中,构造函数的可选参数可以是类似于
context
的内容,如果发生以下情况,则可以是http
Web 请求和""
用于其他任何内容。As far as the timing goes, you could pass all of your queries through a class which, on instantiation, spawns two threads: one for the query, and one for a timer. If the timer reaches 15 seconds, then kill the thread with the query.
As far as figuring out if the query is instantiated from a web request, I don't know enough about Django to be able to help you. Simplistically, I would say, in your class that handles your database calls, an optional parameter to the constructor could be something like
context
, which could behttp
in the event of a web request and""
for anything else.