1.问题描述
后端服务,从数据库中查询日志,并生成表格文件返回静态文件。当数据量几兆时,返回正常,但是超过几十兆,几百兆,就会超过网关的连接超时时间30秒。
时序图
这里面主要花费时间的地方在:
1后台服务器,将数据格式化,写到本地的文件的过程
2后台服务器将文件发送到网关,网关整体接收完
3网关将文件整体接收完后,转发给nginx
4nginx整体缓存文件后发送给浏览器
5浏览器下载从nginx发送的文件
也就是说,一个大文件,需要下载四次才能真正到达用户本地!可想而知多慢
2.解决思路
1.优化sql查询,优化数据处理
但是明显即使优化sql查询,优化数据处理,也快不了多少。但不是没有优化的可能。
首先,sql查询优化,查询下时候有慢查询,查询语句是否是慢查询,索引是否有效,索引是否在where 和select中。
2.减少文件下载的次数
只下载一次!数据流返回,边查询,边返回,浏览器自己下载。而且这样最不一样的地方是,http请求是立马返回的,所以不存在超时的可能。
可以看到,文件只在浏览器下载一次,后台查询数据,是每次只查询一部分数据,并在格式化后就返回,nginx也是接到一部分数据就立马返回,浏览器接到一部分数据就开始下载,让整个http请求立马结束,这样不会超时,但是文件会一直慢慢下载。
nginx配置:
location log {
proxy_pass http://server:111/log;
proxy_cache off;
proxy_buffering off;
chunked_transfer_encoding on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 300;
}
proxy_cache off;
:这一行禁用了Nginx的代理缓存。这意味着每次请求都会直接发送到后端服务器,而不会在Nginx中缓存结果。proxy_buffering off;
:这一行禁用了Nginx的代理缓冲。这意味着Nginx不会预先读取请求的内容,而是在每个请求/响应循环中仅读取实际需要的数据。chunked_transfer_encoding on;
:这一行允许使用分块传输编码。这是一种允许不一次将所有数据发送给客户端,而是分块发送的技术。这对于大数据传输非常有用。tcp_nopush on;
:这一行禁止Nginx使用TCP推送(push)选项。这通常用于告诉浏览器不要缓存数据。tcp_nodelay on;
:这一行设置TCP的nodelay选项为on,这通常用于控制数据流是否应该立即发送。keepalive_timeout 300;
:这一行设置保持活动连接的超时时间为300秒。这意味着,如果客户端和服务器之间的连接在300秒内没有任何活动,连接将会关闭。
然后,前端也要将数据流接到。后端的返回也需要是数据流的形式返回,每次只返回一部分。因为涉及到前端,nginx反向代理服务器和后端服务器,所以往往需要前端和后端同事一起配合才行。