【问题标题】:Dump Django stack trace on Gunicorn timeout在 Gunicorn 超时时转储 Django 堆栈跟踪
【发布时间】:2013-03-15 21:26:35
【问题描述】:

我正在尝试调试 Django 应用程序的罕见挂起。到目前为止,我未能隔离问题,它在生产中大约每天发生一次,Gunicorn 重新启动该过程并显示一条消息:

[CRITICAL] WORKER TIMEOUT

有没有办法配置 Django 或 Gunicorn 来转储重新启动进程的堆栈跟踪?

【问题讨论】:

    标签: django gunicorn


    【解决方案1】:

    尝试将您的 Gunicorn 日志设置为更详细,也许将其设置为 INFODEBUG,这可能会在日志中提供更多信息。

    您还可以查看 Dog Slow,它会记录慢速请求。 https://pypi.python.org/pypi/dogslow.

    对于一般的日志记录胜利,请尝试使用 Sentry:https://www.getsentry.com/welcome/

    随机问题,当时服务器上运行的任何 crons、备份之类的东西?

    【讨论】:

    • Dog Slow 看起来很棒,我可以将其超时设置为比 Gunicorn 超时稍低,并跟踪锁定进程。谢谢!这在 Heroku 上运行,因此不应该有任何繁重的后台进程。
    • Nick ODell 在下面的回答对我有帮助,但我想知道通过设置 Gunicorn 日志级别是否应该可以通过这个公认的答案来实现。还是解决了 OP 问题的 Dogslow 建议?
    【解决方案2】:

    这将在工作人员被杀死时打印堆栈跟踪。您需要创建一个gunicorn config file,并将以下函数粘贴到其中。

    def worker_abort(worker):
        import traceback, io
        debug_info = io.StringIO()
        debug_info.write("Traceback at time of timeout:\n")
        traceback.print_stack(file=debug_info)
        worker.log.critical(debug_info.getvalue())
    

    (我只在 Python 3 上对此进行了测试。如果您使用 Python 2,则需要将 io 更改为 StringIO。参见 StringIO in Python3

    【讨论】:

      【解决方案3】:

      超时并不意味着请求超时。这意味着对工人进行活性检查。对于同步工作人员,这起到了请求超时的作用,因为工作人员除了处理请求之外不能做任何事情。异步工作人员即使在处理长时间运行的请求时也会心跳,因此除非工作人员阻塞/冻结,否则不会被杀死。

      Gunicorn 有一个名为 worker_abort 的函数(请参阅下面的 gunicorn 文档)。

      def worker_abort(worker):
          worker.log.info("worker received abort signal")
          import threading, sys, traceback
          id2name = dict([(th.ident, th.name) for th in threading.enumerate()])
          code = []
          for threadId, stack in sys._current_frames().items():
              code.append("\n# Thread: %s(%d)" % (id2name.get(threadId,""), threadId))
              stack = traceback.extract_stack(stack)
              for filename, lineno, name, line in stack:
                  code.append('File: "%s", line %d, in %s' % (filename, lineno, name))
                  if line:
                      code.append("  %s" % (line.strip()))
          worker.log.debug("\n".join(code))
      

      当工作人员收到 SIGABRT 信号时调用。此调用通常在超时时发生。可调用对象需要为已初始化的 Worker 接受一个实例变量。

      来源:

      http://docs.gunicorn.org/en/stable/settings.htmlhttps://github.com/benoitc/gunicorn/issues/1493https://github.com/benoitc/gunicorn/blob/master/examples/example_config.py

      【讨论】:

        猜你喜欢
        • 2019-12-01
        • 2013-10-06
        • 2022-01-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-04-29
        相关资源
        最近更新 更多