在Django + Gunicorn + Heroku上记录请求超时

时间:2014-05-29 09:00:38

标签: django heroku gunicorn

我们有一个运行Gunicorn的Django应用程序,其同步工作程序部署在Heroku上。我们的请求响应时间显示了几个命令达到30秒(并且死亡),这是默认的Gunicorn超时。

记录这些请求并分析超时的最佳方法是什么? Gunicorn似乎没有提供捕获这些超时的钩子,至少不是那些显而易见的东西。

3 个答案:

答案 0 :(得分:1)

一种相当粗略的方法是使用“看门狗”计时器,在25秒后中断该过程。一旦你知道哪些触发很慢,你就可以优化数据来弄清楚发生了什么。

示例:

import signal

def timeout(_signum, _frame):
    print 'TIMEOUT'

signal.signal(signal.SIGALRM, timeout)
signal.alarm(1)                 # send SIGALRM in 1 second

print 'waiting'
signal.pause()
print 'done'

答案 1 :(得分:0)

另一种方法是触发Thread,它会在经过一定时间后触发主代码。它有几个注意事项 - 请务必阅读ActiveState链接。

以下是来自ActiveState.com

的Aaron Swartz的一个实现
import threading
class TimeoutError(Exception): pass

def timelimit(timeout):
    def internal(function):
        def internal2(*args, **kw):
            class Calculator(threading.Thread):
                def __init__(self):
                    threading.Thread.__init__(self)
                    self.result = None
                    self.error = None

                def run(self):
                    try:
                        self.result = function(*args, **kw)
                    except:
                        self.error = sys.exc_info()[0]

            c = Calculator()
            c.start()
            c.join(timeout)
            if c.isAlive():
                raise TimeoutError
            if c.error:
                raise c.error
            return c.result
        return internal2
    return internal

答案 2 :(得分:0)

https://github.com/benoitc/gunicorn/pull/768/files添加了worker_abort信号,这是我在这种情况下使用的信号。