相比之下,流允许我们提供定制的客户端和服务器之间的协议,但代价的绕过许多浏览器提供的服务:最初的HTTP握手可以执行一些协商参数的连接,但是一旦建立了会话,所有进一步的客户端和服务器之间的数据流是不透明到浏览器。因此,交付自定义协议的灵活性也有其缺点,应用程序可能必须实现自己的逻辑来填补缺失的空白:缓存、状态管理、消息元数据的交付,等等!
初始的HTTP升级握手允许服务器利用现有的HTTP 机制来验证用户。如果验证失败,服务器可以拒绝升级。
利用浏览器和中间缓存
使用常规HTTP具有显著的优势。问您自己一个简单的问题:客户机会从缓存接收到的数据中获益吗?或者,如果中介可以缓存资产,它是否可以优化资产的交付?
例如,支持二进制传输,这允许应用程序流任意的图像格式而没有开销——好漂亮!然而,图像是在自定义协议中交付的这一事实意味着它不会被浏览器缓存或任何中介(例如CDN)缓存。因此,您可能需要向客户机进行不必要的传输,并向源服务器传输更多的流量。同样的逻辑也适用于所有其他数据格式:视频、文本等等。
因此,确保你为工作选择了合适的交通工具!解决这些问题的一个简单而有效的策略是使用会话来传递非缓存数据,比如实时更新和应用“控制”消息,这可以触发XHR请求来通过HTTP协议获取其他资产。
部署基础设施
HTTP为短时间和突发传输进行了优化。因此,许多服务器、代理和其他中介经常被配置为主动超时空闲HTTP连接,当然,这正是我们不希望看到的长时间会话。为了解决这个问题,有三方面需要考虑:
我们无法控制客户端网络的策略。事实上,一些网络可能会完全阻止流量,这就是为什么您可能需要一个备用策略。类似地,我们无法控制外部网络上的代理。然而,这正是TLS可以帮助的地方!通过在安全的端到端连接上使用隧道,通信可以绕过所有的中间代理。
使用TLS并不会阻止中间层对空闲TCP连接计时。然而,在实践中,它极大地提高了协商会话的成功率,并且通常还有助于扩展连接超时间隔。
最后,还有我们自己部署和管理的基础设施,这通常也需要关注和调优。尽管责怪客户端或外部网络很容易,但问题往往是在家里。服务路径中的每个负载均衡器、路由器、代理和web服务器都必须进行调优,以允许长时间连接。
例如,Nginx 1.3.13+可以代理流量,但默认为60秒超时!为了增加限制,我们必须明确地定义较长的超时:
location /websocket {
proxy_pass http://backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_read_timeout 3600;
proxy_send_timeout 3600;
}
设置读取间隔60分钟的超时时间在写之间设置60分钟的超时时间
类似地,在一个或多个Nginx服务器前安装一个负载均衡器也很常见,比如。毫不奇怪,我们在这里也需要应用类似的显式配置。,因为:
defaults http
timeout connect 30s
timeout client 30s
timeout server 30s
timeout tunnel 1h
前面示例的问题是额外的“隧道”超时。在中,连接、客户端和服务器的超时只适用于初始的HTTP升级握手,但是一旦升级完成,超时由隧道值控制。
Nginx和只是在我们的数据中心运行的数百个不同的服务器、代理和负载平衡器中的两个。我们不能列举这些页面中所有的配置可能性。前面的示例只是说明了大多数基础设施需要自定义配置来处理长期存在的会话。因此,在实现应用程序保持生命值之前,首先要仔细检查基础设施。
长期会话和空闲会话占用所有中间服务器上的内存和套接字资源。因此,短超时通常被认为是安全、资源和操作方面的预防措施。部署、SSE和HTTP/2(它们都依赖于长寿命会话)带来了各自的新操作挑战。
性能检查表
部署高性能服务需要在客户端和服务器端进行仔细的调优和考虑。列入议程的标准的简短清单:
最后,但绝对不是最不重要的,优化移动!在手机上,实时推送可能是一个代价高昂的性能反模式,因为电池寿命总是非常宝贵。这并不是说不应该在移动设备上使用。相反,它可以是一种高效的交通工具,但一定要考虑到它的要求:
(此处已添加圈子卡片,请到今日头条客户端查看)
评论(0)