AWS Django NGINX超时和错误

egmofgnx  于 5个月前  发布在  Nginx
关注(0)|答案(1)|浏览(66)

我有一个视图,我试图通过表单上传Excel工作表。我上传的Excel不是那么大,但Excel中的数据处理导致Nginx超时问题,导致502 Bad Gateway错误。我在本地测试时没有这个问题,但在AWS EC2上测试时,它会弹出。
我在nginx中增加了超时时间(如建议的here):

proxy_read_timeout 300s;
proxy_connect_timeout 300s;

proxy_buffer_size          128k;
proxy_buffers              4 256k;
proxy_busy_buffers_size    256k;

字符串
这确实改善了一些事情,因为我可以看到更多的结果,但它是不够的。奇怪的是,它再次超时之前,300秒了。顺便说一句,如果它使用所有300秒,它应该完成这个过程。
也有人建议我使用UBC-C使处理独立于上传过程,并在后台运行处理。然而,在尝试中,我不断遇到这个错误:
“对象HttpResponseRedirect不能在'await'表达式中使用”
当我尝试加载页面时,甚至在我尝试上传Excel文件之前,这是我唯一一次有重定向,这意味着重定向到列出上传文档的页面时,会发生此错误。
如果我从上传视图中删除@sync_to_decorator,我会得到这个错误
“未返回HttpResponse对象。它返回了一个未等待的协程。您可能需要在视图中添加"await””
我该如何解决此问题?

@sync_to_async
def process_excel_upload(request, excel_file):
    ** processing of the excel document ***
    return ("complete")

@login_required
@sync_to_async
@user_preapproved(home_url='landing-dashboard', redirect_field_name='', message='You are not authorised to perform this action.')
@user_passes_test(group_check, redirect_field_name=None)
async def ExcelUploadEditView(request):
    user = request.user
    member = ProfileMember.objects.get(user=user)
    if request.method == 'POST':
        form = ExcelUploadForm(request.POST or None, request.FILES or None)
        if form.is_valid():            
            json_payload = {
                "message": "Your file is being processed"
            }
            excel = request.POST.get('excel')
            await asyncio.create_task(process_excel_upload(request,excel))
            form.save()
            return redirect('excel-after',json_payload)
        else:
            print(form.errors)
    else:
        form = ReportUploadForm()
        context = {
            'form_documentupload': form,
            'user': user,
            'member':member,

            }
        return render(request, "excel_upload.html", context)

ubof19bj

ubof19bj1#

这可能对你有用:
[网址:views.py]

import threading
    
    def process_excel_upload(request, excel_file):
        ** processing of the excel document ***
        upload_status = UploadStatus.objects.get(user=request.user)
        upload_status.status = 'complete'
        upload_status.save()
    
    def get_upload_status(request):
        upload_status = UploadStatus.objects.get(user=request.user)
        return JsonResponse({'status': upload_status.status})
    
    @login_required
    @user_preapproved(home_url='landing-dashboard', redirect_field_name='', message='You are not authorised to perform this action.')
    @user_passes_test(group_check, redirect_field_name=None)
    def ExcelUploadEditView(request):
        user = request.user
        member = ProfileMember.objects.get(user=user)
        if request.method == 'POST':
            form = ExcelUploadForm(request.POST or None, request.FILES or None)
            if form.is_valid():            
                json_payload = {
                    "message": "Your file is being processed"
                }
                excel = request.POST.get('excel')
                upload_status = UploadStatus.objects.get(user=request.user)
                upload_status.status = 'processing'
                upload_status.save()
                t = threading.Thread(target=process_excel_upload,args=(request,excel))
                t.setDaemon(True)
                t.start()
                form.save()
                return redirect('excel-after',json_payload)
            else:
                print(form.errors)
        else:
            form = ReportUploadForm()
            context = {
                'form_documentupload': form,
                'user': user,
                'member':member,
                }
            return render(request, "excel_upload.html", context)

字符串
[template.html]

//call this function in the upload response:
    
    function checkUploadStatus() {
        $.ajax({
            url: '/get_upload_status/',  // replace with the URL you set to your get_upload_status view
            success: function(data) {
                if (data.stats === 'complete') {
                    //replace the uploading... message with a completion message
                } else {
                    setTimeout(checkUploadStatus, 3000);
                }
            }
        });
    }


[网址:models.py]

from django.contrib.auth.models import User
    
    class UploadStatus(models.Model):
        user = models.OneToOneField(User, on_delete=models.CASCADE, primary_key=True)
        status = models.CharField(max_length=20, default='pending')


你也可以考虑使用网络套接字,虽然我认为这是一个矫枉过正

相关问题