我有一个“单页”的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缓冲防止了一些消息在客户端/服务器之间正确发送。