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

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

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

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

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

那有可能吗? uwsgi's hariakari设置使我认为它处于某种水平..只是不知道如何去做。

最佳答案



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

注意uwsgi_ignore_client_abort是在TCP级别处理连接关闭的东西。这与中止AJAX请求不同。通常,您无法在JavaScript中采取任何措施来关闭TCP连接。浏览器可以优化连接的创建和销毁以适应其需求。刚才,我这样做:

  • 我使用lsof来检查是否有任何进程与example.com有连接。没有。 (lsof是一个* nix实用程序,允许列出打开的文件。网络连接是* nix中的"file"。)
  • 我在Chrome中打开了example.com的页面。 lsof显示了连接及其打开过程。
  • 然后关闭页面。
  • 我以lsof进行了轮询,以查看我之前确定的连接是否仍处于打开状态。 即使没有真正需要保持连接打开的状态,它在关闭页面后仍保持打开状态约一分钟。

  • 而且我们对uswgi设置没有任何摆弄,这会使它知道通过XMLHttpRequest.abort() 执行的中止操作

    您提供的用例场景是用户快速浏览某些结果的场景。对于问题中给出的描述,我可以看到两种可能性:
  • 用户等待刷新,然后再分页。例如,爱丽丝(Alice)正在浏览按用户“Zeno”字母顺序排列的用户名列表,每次显示新页面时,她都会看到该名称不存在并且向下翻页。在这种情况下,没有什么可中止的,因为用户的操作取决于首先处理的请求。 (用户必须在做出决定之前先查看新页面。)
  • 用户无需等待刷新就可以向下翻页。爱丽丝再次寻找“Zeno”,但她认为它会出现在最后一页上,因此,单击,单击,然后单击。在这种情况下,您可以取消对服务器发出的请求。 然后按下下一页按钮,增加应显示给用户但不立即发送请求的页面数。而是,在用户停止单击按钮之后再等待一小段延迟,然后再发送带有最终页码的请求,因此您发出一个请求而不是一打。 Here是对DataTables搜索执行的反跳示例。
  • 关于django - 将HTTP中止/关闭从Nginx传播到uwsgi/Django,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39780755/

    10-11 10:57