内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用
我有一个Django应用程序Web应用程序,我想知道是否有可能让nginx传播abort / close到uwsgi / Django。
基本上我知道nginx知道过早的中止/关闭,因为它默认为uwsgi_ignore_client_abort
“关闭”,并且当发送响应之前请求被中止/关闭时,nginx 499错误会在你的nginx日志中出现。一旦uwsgi完成处理请求,它会在返回响应给nginx时抛出一个“IO Error”。
转到uwsgi_ignore_client_abort
“on”只会让nginx不知道中止/关闭,并移除uwsgi“IO Errors”,因为uwsgi仍然可以写回到nginx。
我的用例是我有一个应用程序,用户可以非常快速地浏览一些ajax结果,所以如果通过快速页面中止他们跳过的页面的挂起的ajax请求,这可以使客户端保持清洁和高效。但是这对服务器端(uwsgi / Django)没有任何作用,因为即使没有任何东西会等待响应,他们仍然需要处理每一个请求。
现在显然可能会有某些页面,我不希望请求因任何原因过早中止。但是我使用celery来处理可能属于该类别的长时间运行的请求。
这可能吗?uwsgi's
hariakari设置让我觉得它在某种程度上......只是无法弄清楚如何去做。
现在显然可能会有某些页面,我不希望请求因任何原因过早中止。
这正是采取这种或那种方式背后的问题。
如前所述,问题出在uWSGI上,而不是在NGINX上。然而,你不能让uWSGI自动决定你的意图,没有你自己向uWSGI透露这样的意图。
你将如何在你的代码中揭示你的意图?一大堆编程语言并不真正支持多线程和/或异步编程模型,这使得取消操作变得完全不重要。
因此,这里没有神奇的解决方案。 即使像Golang这样的并发友好的编程语言也存在一些问题WithCancel
context
- 你可能不得不在每一个可能阻塞的函数调用中传递它,使得代码非常难看。
是否已经在Django中传递上述上下文?如果不是,那么解决方案很难但非常简单 - 只要您明确放弃请求,就可以检查客户端是否仍然连接uwsgi.is_connected(uwsgi.connection_fd())
:
我的用例是我有一个应用程序,用户可以非常快速地浏览一些ajax结果,所以如果通过快速页面中止他们跳过的页面的挂起的ajax请求,这可以使客户端保持清洁和高效。
通过在客户端中止AJAX请求XMLHttpRequest.abort()
。如果请求在abort()
被调用时尚未发出,则该请求不会熄灭。但是,如果请求已发送,服务器将不知道该请求已被中止。连接不会关闭,不会有任何消息发送到服务器,什么都不是。如果希望服务器知道不再需要某个请求,则基本上需要提供一种识别请求的方法,以便在发出初始请求时获得该请求的标识符。然后,通过另一个AJAX请求,您以告诉服务器应该取消先前的请求。
请注意,uwsgi_ignore_client_abort
这是处理TCP级别的连接关闭的事情。这与放弃AJAX请求完全不同。在JavaScript中通常不会采取任何行动,这将导致关闭TCP连接。浏览器优化连接的创建和销毁以适应其需求。刚才,我这样做了:
lsof
检查过程是否有连接example.com
。没有。(lsof
是允许列出打开文件的* nix工具,网络连接是* nix中的“文件”)。lsof
显示了连接和打开它的过程。lsof
,看看我之前确定的连接是否仍然打开。即使没有真正需要保持连接打开,我在关闭页面后仍保持打开状态约一分钟。而且没有太多的uswgi设置的摆弄,这将使它意识到通过执行中止 XMLHttpRequest.abort()
你提供的用例场景是用户通过某些结果进行快速分页的场景。我可以看到在问题中给出的描述有两种可能性: