Https流式输出一次输出一大段,一卡一卡的-解决方案
【背景】
最近遇到一个奇怪的现象,前端vue,后端python,服务部署在服务器上面后,本来一切正常,但公司说要使用https访问,想着也没什么问题,切过去发现在没有更改任何代码的情况下,https的这个地址,流式输出时,总是一卡一卡的,一次输出一大段,而http这边的地址,一切正常,输出都是好着的,一个字一个字的崩,起初怀疑是证书的问题,更换证书后依旧卡顿。 经过curl命令排查, https请求时,后端响应明显变慢,但是http正常, 排除代码本身的原因。怀疑到nginx上后,经过一顿搜索,问题解决。
linux系统生成ssl证书后nginx配置可参考博主的另外一篇文章:
linux系统生成ssl证书后nginx配置_linux生成ssl pem-CSDN博客
先上解决办法
server {listen 443 ssl;server_name example.com;ssl_certificate /path/to/cert.pem;ssl_certificate_key /path/to/key.pem;location /agent {proxy_pass http://backend;proxy_buffering off; # 关闭代理缓冲,确保流式传输}
}
核心配置:proxy_buffering off; # 关闭代理缓冲,确保流式传输
配置完后,nginx重新加载一下配置
nginx -s reload
深究原理:
我有个疑问: 相同的nginx配置,为什么 http访问正常, https访问好像被nginx 截流了呢? 为什么 http请求 没有proxy_buffering off; 设置也正常响应呢?
这个问题的核心在于 HTTP 和 HTTPS 在 Nginx 代理中的处理方式不同。以下几点解释了为什么 HTTP 请求可以正常响应,而 HTTPS 请求在没有关闭 proxy_buffering
时表现出卡顿的现象。
这是因为
https
和http
协议在传输数据时使用的是不同的传输方式。http
协议使用的是明文传输,数据是一行一行地传输的,每行数据以回车符和换行符结尾。这种传输方式比较简单,但是不够安全,容易被窃听和篡改。https
协议使用的是加密传输,数据是一大段一大段地传输的,每段数据的长度是不固定的。这种传输方式比较安全,可以保护数据的机密性和完整性,但是相对于http
协议来说,传输效率会稍微低一些。因此,如果你需要传输机密性较高的数据,建议使用https
协议进行传输。如果你需要传输的数据不太机密,可以使用
http
协议进行传输。
1. Nginx 代理行为差异:
- HTTP:在 HTTP 请求中,Nginx 默认会使用缓冲机制,但由于 HTTP 请求本身并不涉及加密和解密,数据的传输和处理通常比较快,即使启用了
proxy_buffering
,只要后端响应速度快,客户端也不会明显感受到延迟。Nginx 能够较快速地将缓冲的数据传递给客户端,因此你感受不到 HTTP 请求的卡顿。 - HTTPS:HTTPS 请求涉及加密、解密过程,Nginx 需要处理 SSL/TLS 协议,导致响应的数据经过更多处理环节。在这种情况下,
proxy_buffering
缓冲机制可能会导致 Nginx 等待完整的响应数据块,再将其推送到客户端,增加了数据传输的延迟感,尤其在流式数据的场景中更明显。
2. 缓冲的作用:
proxy_buffering
的默认行为:Nginx 默认会缓冲来自后端服务器的响应数据,缓冲满了之后再一次性发送到客户端。对于 HTTP 请求,数据包小而且无需解密,Nginx 处理较为快速,通常不会影响用户体验。- HTTPS 的复杂性:在 HTTPS 情况下,由于涉及加密和较大的数据包,Nginx 可能需要更长的时间来处理响应。而当启用缓冲时,Nginx 会先缓冲较大的数据块,再推送到客户端,这使得 HTTPS 的流式响应延迟更为明显。关闭
proxy_buffering
后,Nginx 可以直接将流式数据传递给客户端,无需等待缓冲区填满。
3. 流式传输的需求:
- 流式响应要求数据能够即时从后端传递给前端,而不是经过代理服务器的缓冲。对于流式传输来说,
proxy_buffering
可能会阻碍这种即时时性。HTTP 由于传输开销小,能承受一定的缓冲延迟,而 HTTPS 的加密过程放大了这个问题。
4. 数据包大小和网络开销:
- HTTPS 请求的每个数据包相对更大,因为它包含了加密后的数据。Nginx 可能需要缓冲这些较大的数据包,而一旦 Nginx 使用
proxy_buffering
进行缓冲处理,这种额外的等待时间会被放大。而 HTTP 请求没有这种加密开销,响应更快。
总结:
简单来说,HTTPS 请求的流式响应之所以卡顿,主要是因为:
- 数据包更大:HTTPS 请求的数据包经过加密后确实比 HTTP 大一些,加密增加了开销。
- 缓冲机制的影响:在 HTTPS 请求中,Nginx 的缓冲机制需要更多时间来处理这些加密的数据包,导致延迟。相比之下,HTTP 没有加密开销,即使启用缓冲,数据传输也相对流畅。
因此,同样的请求,HTTPS 因为加密、数据包较大,加上 Nginx 的缓冲,导致流式响应出现卡顿。关闭 proxy_buffering
后,Nginx 不再等待缓冲区填满,而是直接传输数据,HTTPS 响应也就变得流畅了。
性能影响及优化建议
- 性能影响:https的加密和解密过程增加了处理时间,尤其是在流式数据的场景中,Nginx需要等待完整的响应数据块才能推送给客户端,这可能导致延迟感增加。
- 优化建议:可以通过调整Nginx配置来减少缓冲,使用分块传输编码等方式来优化性能。此外,对于大数据处理,可以考虑使用更高效的算法和硬件资源来减轻CPU负担
https://juejin.cn/post/7417521775586770995
https://mp.weixin.qq.com/s?__biz=MzAxMjY5NDU2Ng==&mid=2651867175&idx=1&sn=8fe3429c9943c981480f7e51ed9a4133