Nginx反向代理腾讯云COS的一个坑

守給你的承諾、 提交于 2020-03-19 13:14:09

3 月,跳不动了?>>>

有一个朋友开发的手机app,把大量文件都保存在腾讯云COS上,然后通过CDN分发。 最近有一个特殊的需求,希望通过CVM来提供部分COS文件的访问。因为服务器用的是Nginx,所以事情也很简单: 1 到COS的管理页面上查询一下内网访问域名

2 给nginx增加一个标准的upstream配置,上游指向腾讯云COS的内网域名

照理说,配置好域名解析就可以开始工作了。但是一开始工作就出现很奇怪的现象:下载开始很快,随后变得很慢,最终有很大概率失败。

首先排除网络原因的可能性。登录服务器用wget通过访问本机localhost验证:

现象就是前面都下载的飞快,到了最后一部分就突然下载不动了。

打开nginx的error_log,发现了upstream timed out (Connection timed out)错误

再排除COS有问题的可能性:

现在问题就很诡异了:上游没有问题,经过反向代理后文件的前面一大部分也都没有问题,就是最后一小截文件要等待很久很久,并且发生了upstream timed out超时。

通过肥龙找到了熟悉nginx的ares同学协助抓包,才定位到了这个问题:

这里的UA是wget,wget默认使用的是http1.0协议。当前服务器使用的nginx是1.0.15这个比较古老的稳定版,还不支持 proxy_http_version 1.1这样的参数(要到1.1.4版本以后才支持)。所以也是采用http1.0协议代理了请求。

照理说innercos服务接到这样的请求应该按照http1.0的方式返回数据,但是我们看到服务器返回了 HTTP/1.1 200 OK 。也就是说不管客户端支持什么http版本cos服务总是用http1.1协议来工作。

http1.1有一个重要的特性是keep-alive,也就是说http数据传输完毕后TCP连接继续保持一段时间不断开,可以给后续的http请求重用。而http1.0的客户端原则上并不知道http1.1的这套原理。所以对于这个老版本的Nginx来讲,它收到完整的数据以后,看到TCP链接一直没有断开,以为upstream还有话说,就一直挂在那里,等上游继续送数据,直到上游连接超时,才在error_log里面记录一个timed out错误,然后断开下游的连接。

把proxy_buffering 关掉让上下游直接对上话可以绕过这个问题,但是有附带的损失。更好的办法是把nginx升级到1.1.4以上的版本,并且开启proxy_http_version 1.1 。

至此圆满解决。

总结一下,腾讯云COS的后台服务假设客户端都支持http1.1协议,对http1.0协议没有做很好的兼容,而腾讯云CVM提供的带Nginx的系统镜像里面的Nginx版本又有点儿老旧了,proxy还只能工作在http1.0上,导致了这个问题的出现。

相关推荐

【腾讯云的1001种玩法】Nginx + Tomcat 负载均衡配置详解

nginx 基本入门


阅读原文,本文由腾云阁授权发布,经社区允许后方可转载。更多技术文章,请访问腾云阁

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!