将HTTP中止/关闭从Nginx传播到uwsgi/Django [英] Propagate http abort/close from nginx to uwsgi / Django

查看:166
本文介绍了将HTTP中止/关闭从Nginx传播到uwsgi/Django的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Django应用程序Web应用程序,我想知道是否有可能让Nginx将中止/关闭传播到uwsgi/Django.

I have a Django application web application, and I was wondering if it was possible to have nginx propagate the abort/close to uwsgi/Django.

基本上,我知道nginx知道过早中止/关闭,因为它默认将uwsgi_ignore_client_abort设置为"off",并且在发送响应之前中止/关闭请求时,nginx日志中会出现nginx 499错误.一旦uwsgi完成了对请求的处理,它将把响应返回给nginx时抛出"IO错误".

Basically I know that nginx is aware of the premature abort/close because it defaults to uwsgi_ignore_client_abort to "off", and you get nginx 499 errors in your nginx logs when requests are aborted/closed before the response is sent. Once uwsgi finishes processing the request it throws an "IO Error" when it goes to return the response to nginx.

uwsgi_ignore_client_abort设置为"on"只会使nginx不知道中止/关闭操作,并删除uwsgi的"IO错误",因为uwsgi仍然可以写回nginx.

Turning uwsgi_ignore_client_abort to "on" just makes nginx unaware of the abort/close, and removes the uwsgi "IO Errors" because uwsgi can still write back to nginx.

我的用例是,我有一个应用程序,人们可以快速浏览某些Ajax结果,因此,如果快速浏览页面可以中止他们跳过的页面的未决ajax请求,则可以使客户端保持干净高效.但这对服务器端(uwsgi/Django)无效,因为即使没有任何内容等待响应,它们仍然必须处理每个单个请求.

My use case is that I have an application where people page through some ajax results very quickly, and so if the quickly page through I abort the pending ajax request for the page that they skipped, this keeps the client clean and efficient. But this does nothing for the server side (uwsgi/Django) because they still have to process every single request even if nothing will be waiting for the response.

现在显然可能有某些页面,我不希望出于任何原因而中止请求.但是我将芹菜用于可能属于该类别的长时间运行的请求.

Now obviously there may be certain pages, where I don't want the request to be prematurely aborted for any reason. But I use celery for long running requests that may fall into that category.

那么这可能吗? uwsgi's hariakari的设置使我认为它处于某种程度..只是不知道如何去做.

So is this possible? uwsgi's hariakari setting makes me think that it is at some level.... just can't figure out how to do it.

推荐答案

我的用例是,我有一个应用程序,人们可以快速浏览某些Ajax结果,因此,如果快速浏览页面可以中止他们跳过的页面的未决Ajax请求,则可以使客户端保持整洁高效.

My use case is that I have an application where people page through some ajax results very quickly, and so if the quickly page through I abort the pending ajax request for the page that they skipped, this keeps the client clean and efficient.

通过 XMLHttpRequest.abort() .如果在调用abort()时尚未发出请求,则该请求不会发出.但是,如果请求已发送,服务器将不知道请求已中止.连接不会关闭,不会有任何消息发送到服务器,什么也不会.如果您希望服务器知道不再需要某个请求,则基本上需要提出一种识别请求的方法,以便在发出初始请求时获得该请求的标识符.然后,通过另一个AJAX请求,您可以 告诉服务器应取消先前的请求. (如果您像这样搜索有关abort() 的问题,并搜索服务器"您会发现解释相同.)

Aborting an AJAX request on the client side is done through XMLHttpRequest.abort(). If the request has not yet been sent out when abort() is called, then the request won't go out. But if the request has been sent, the server won't know that the request has been aborted. The connection won't be closed, there won't be any message sent to the server, nothing. If you want the server to know that a request is no longer needed, you basically need to come up with a way to identify requests so that when you make the initial request you get an identifier for it. Then, through another AJAX request you could tell the server that an earlier request should be cancelled. (If you search questions about abort() like this one and search for "server" you'll find explanations saying the same.)

请注意,uwsgi_ignore_client_abort是在TCP级别处理连接关闭 的内容.这与中止AJAX请求不同.通常,您无法在JavaScript中执行需要关闭TCP连接的操作.浏览器可以优化连接的创建和销毁以适应其需求.刚才,我这样做了:

Note that uwsgi_ignore_client_abort is something that deals with connection closures at the TCP level. That's a different thing from aborting an AJAX request. There is generally no action you can take in JavaScript that will entail closing a TCP connection. The browser optimizes the creation and destruction of connections to suit its needs. Just now, I did this:

  1. 我使用了lsof来检查是否有任何进程与example.com有连接.没有. (lsof是一个* nix实用程序,它允许列出打开的文件.网络连接是* nix中的文件".)

  1. I used lsof to check whether any process had a connection to example.com. There were none. (lsof is a *nix utility that allows listing open files. Network connections are "files" in *nix.)

我在Chrome中打开了example.com的页面. lsof显示了连接及其打开过程.

I opened a page to example.com in Chrome. lsof showed the connection and the process that opened it.

然后我关闭了页面.

我用lsof进行了轮询,以查看之前确定的连接是否仍处于打开状态. 即使没有真正需要保持连接打开的状态,它在关闭页面后仍保持打开状态约一分钟.

I polled with lsof to see if the connection I identified earlier was still opened. It stayed open for about one minute after I closed the page even though there was no real need to keep the connection open.

并且没有对uswgi设置的摆弄,这会使它知道通过XMLHttpRequest.abort()

And there's no amount of fiddling with uswgi settings that will make it be aware of aborts performed through XMLHttpRequest.abort()

您提供的用例场景是用户快速浏览某些结果的场景.对于问题中给出的描述,我可以看到两种可能性:

The use-case scenario you gave was one where users were paging fast through some results. I can see two possibilities for the description given in the question:

  1. 用户在刷新之前等待刷新.例如,爱丽丝正在浏览按用户"Zeno"字母顺序排序的用户名列表,每次显示新页面时,她都会看到该名称不存在并且向下翻页.在这种情况下,没有什么可中止的,因为用户的操作取决于已被 first 处理的请求. (用户必须先查看新页面,然后才能做出决定.)

  1. The user waits for a refresh before paging further. For instance, Alice is looking through an list of user names sorted alphabetically for user "Zeno" and each time a new page is shown, she sees the name is not there and pages down. In this case, there's nothing to abort because the user's action is dependent on the request having been handled first. (The user has to see the new page before making a decision.)

用户无需等待刷新就可以向下翻页.爱丽丝再次寻找"Zeno",但她认为它会出现在最后一页上,因此,单击,单击,然后单击.在这种情况下,您可以删除对服务器的请求.然后按下下一页按钮,增加应向用户显示但不正确发送请求的页面数离开.相反,您要在用户停止单击按钮之后等待一小段延迟,然后再发送带有 final 页码的请求,因此您只发出一个请求,而不是一打. 此处是针对DataTables搜索执行的反跳操作的示例.

The user just pages down without waiting for a refresh. Alice again is looking for "Zeno" but she figures it's going to be on the last page so click, click, click she goes. In this case, you can debounce the requests made to the server. Then the next page button is pressed, increment the number of the page that should be shown to the user but don't send the request right away. Instead, you wait for a small delay after the user ceases clicking the button to then send the request with final page number and so you make one request instead of a dozen. Here is an example of a debounce performed for a DataTables search.

这篇关于将HTTP中止/关闭从Nginx传播到uwsgi/Django的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆