【问题标题】:Django - Heroku - Serving dynamic large file timing outDjango - Heroku - 服务动态大文件超时
【发布时间】:2017-11-02 21:25:23
【问题描述】:

我有一个使用 xlsxwriter 创建报告的函数视图,它是使用 StringIO 作为缓冲区动态创建的,最后通过 HttpResponse 发送。
使用本地服务器效果很好。

问题在于,在 Heroku 上,几秒钟后(文档提到 30 秒超时且不可修改),服务器挂起并重新启动 Web 进程,并给出错误作为响应。

最好的方法是什么?

  • 在内存中动态(动态)创建一个 xmlx 文件
  • 将整个文件提供给客户端。
  • 防止服务器因为长时间运行而挂起

这是我正在使用的一段代码:

def reporte_usuarios(request):
    from xlsxwriter.workbook import Workbook
    try:
        import cStringIO as StringIO
    except ImportError:
        import StringIO

    # create a workbook in memory
    output = StringIO.StringIO()

    workbook = Workbook(output)

    bold = workbook.add_format({'bold': True})

    # get the data
    from django.db.models import Count
    usuarios = User.objects.filter(....... # all filter stuff

    for usr in usuarios:
        if usr.activos > 0:

            # create a workbook sheet every User registered
            ws = workbook.add_worksheet(u'%s' % usr.username)

            # some relevant user data
            ws.write(1, 1, u'USUARIO: %s' % usr.username)
            ...

            # get rows for user
            log = LogActivos.objects.filter(usuario=usr).select_related('activo__unidad__id', 'activo__unidad__nombre', 'activo__nombre')

            # write headers
            ws.write(3, 0, u'FECHA', bold)
            ...
            sig_fila = 4  #starting row for data (after headers)
            for l in log:
                # write all data
                ws.write(sig_fila, 0, u'%s' % l.fecha)
                ...
                sig_fila += 1
    # close the workbook
    workbook.close()
    # go to the beginning of the buffer
    output.seek(0)
    # response using the buffer
    response = HttpResponse(output.read(), content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet')
    response['Content-Disposition'] = 'attachment; filename="ACTIVOS_USUARIOS__%s.xlsx"' % datetime.now().strftime("%Y%m%d_%H%M")
    return response

注意:我在 Heroku、django 1.9.13 和 python 2.7.11 上使用 Gunicorn

【问题讨论】:

    标签: python django heroku large-data


    【解决方案1】:

    恕我直言,在这种情况下,您应该采用完全不同的方法。 由于您正在生成一个相当大的文件,因此系统因超时错误而挂起是正常的。

    您可以做的是部署一个后台任务队列,例如 Celery 或 DjangoRQ。这样,您将获得使用用户数据创建此文件的后台任务,然后您可以通过任何方式(例如通知或电子邮件)让您的用户知道它已准备就绪。

    如果您需要有关如何执行此类操作的更多详细信息,请告诉我,我可以提供帮助:)

    【讨论】:

    • 我一直在使用 Celery 和 Redis 在后台进程中工作,它创建文件并将其保存在临时目录中,然后在文件准备好时提供文件并通知用户。但是让它在 Heroku 中运行的部分是痛苦的。你有什么指南可以做到这一点吗?
    • 你有没有卡住的特定部分?只需更准确地了解您需要什么样的信息,我会四处寻找有关类似案例的指南
    • 我现在所有的后台作业都可以很好地使用 redis 和 celery,但是我将我的存档保存在 Amazon S3 中并将 URL 返回给用户以开始下载。这是可行的,但不是我想要的,因为我需要使存档临时或在内存中生成它,并且所有内容都在工作进程或后台进程中。
    • 好吧,解决方法是在短时间内(例如 2 小时)后从 S3 中删除文件。这对你更有效吗?
    • 是的!会很好!但是,我应该需要更多的heroku工人来做到这一点吗?或者创建“计时器删除”的方法是什么?
    猜你喜欢
    • 2015-06-06
    • 2016-02-16
    • 2012-01-20
    • 1970-01-01
    • 2023-03-20
    • 2011-12-12
    • 2021-07-30
    • 2016-04-05
    • 2013-12-08
    相关资源
    最近更新 更多