在NGINX中是否应该禁用proxy_buffering来支持SockJS XHRstream?

我有一个“单页”的Web应用程序,需要客户端和服务器之间的双向通信。

该应用程序最初devise为依赖于WebSocket,但已被修改为使用SockJS,禁用WebSocket支持。

使用SockJS库的客户倾向于使用“XHRstream”作为双向通信的手段。

服务器是一个Java Web应用程序,使用Spring托pipe在Tomcat中的SockJS服务器(来自Spring的WebSocket模块)实现。

NGINX被用作Tomcat的反向代理

NGINX的默认configuration是启用proxy_buffering

NGINX的文档没有充分解释缓冲区的行为:如果数据正在被stream式传输(来自Tomcat)长期存在,在什么情况下缓冲区将被刷新(即当数据实际上被推送到客户端时)是不明显的HTTP连接。

我的观察是,从服务器推送的数据(对客户请求的响应)可能位于NGINX的缓冲区中,直到为该客户端发生下一个服务器生成的SockJS心跳。 这样做的效果是延迟25秒将响应传输到客户端!

我可以通过实验非常可靠地重现此问题 – 行为是确定性的,但是我无法解释configuration的缓冲区大小,正在传输的数据大小和NGINX行为之间的关系。

我的服务器的责任是生成响应客户端的命令调用; 每个响应的大小会有所不同(从几个字节到几十千字节),但是是独立的。

主要目标是减less对客户端命令的响应延迟。

NGINX只看到一个长期的HTTPstream; 将stream的内容划分为单独的命令响应(用于立即发送)将要求NGINX理解SockJS的专有协议,但是它不能。

因此,我认为NGINX的缓冲政策与我的使用情况根本是不相容的,并计划closuresproxy_buffering ; 这是明智的吗?

NGINX的文档build议,如果proxy_buffering被禁用,上游服务器(Tomcat)将被迫保持HTTP响应打开,直到客户端收到所有的数据(这似乎是一个合理的缓冲定义!)。

因此,NGINX的文档build议禁用proxy_buffering ,因为它可能会浪费上游服务器资源。

但是,因为我的客户端使用XHRstream,我的服务器已经有义务为每个活动客户端持有HTTP连接(对吗?)。 因此,禁用proxy_buffering不应对我的Tomcat服务器产生负面影响; 它是否正确?

我想你在这里的推理是正确的。 我有一个应用程序使用相同的设置,sockjs后面的nginx代理。 我们看到很多来自高延迟位置的连接断开。 find这个post后,closuresproxy_buffering我们丢弃的连接问题清理。

根据我所看到的日志,我相信nginx缓冲防止了一些消息在客户端/服务器之间正确发送。